Skip to content

Commit f7c6f64

Browse files
committed
Merge branch 'develop' into fix/block_replay_unsuccessful
2 parents 1a6a755 + a7d73af commit f7c6f64

File tree

98 files changed

+12143
-3933
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+12143
-3933
lines changed

.github/actions/dockerfiles/Dockerfile.alpine-binary

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ RUN case "${TAG}" in \
3131
;; \
3232
*) \
3333
echo "/bin/stacks-node mainnet" > /tmp/command.sh && \
34-
rm /bin/blockstack-cli /bin/clarity-cli /bin/stacks-events /bin/stacks-inspect \
34+
rm /bin/stacks-cli /bin/clarity-cli /bin/stacks-inspect \
3535
;; \
3636
esac && \
3737
chmod +x /tmp/command.sh

.github/actions/dockerfiles/Dockerfile.debian-binary

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ RUN case "${TAG}" in \
3131
;; \
3232
*) \
3333
echo "/bin/stacks-node mainnet" > /tmp/command.sh && \
34-
rm /bin/blockstack-cli /bin/clarity-cli /bin/stacks-events /bin/stacks-inspect \
34+
rm /bin/stacks-cli /bin/clarity-cli /bin/stacks-inspect \
3535
;; \
3636
esac && \
3737
chmod +x /tmp/command.sh

.github/workflows/github-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
inputs.node_tag != '' ||
6363
inputs.signer_tag != ''
6464
name: Build Binaries
65-
runs-on: ubuntu-latest
65+
runs-on: ubuntu-latest-m
6666
needs:
6767
- andon-cord
6868
permissions:

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
77

88
## Unreleased
99

10+
### Changed
11+
12+
- Renamed Clarity 4's new `block-time` to `stacks-block-time`
13+
14+
## [3.2.0.0.2]
15+
1016
### Added
1117

1218
- Renamed `clarity-serialization` to `clarity-types`.
@@ -20,7 +26,16 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
2026
- `current-contract`
2127
- `block-time`
2228
- `to-ascii?`
29+
- `restrict-assets?`
30+
- `as-contract?`
31+
- Special allowance expressions:
32+
- `with-stx`
33+
- `with-ft`
34+
- `with-nft`
35+
- `with-stacking`
36+
- `with-all-assets-unsafe`
2337
- Added `contract_cost_limit_percentage` to the miner config file — sets the percentage of a block’s execution cost at which, if a large non-boot contract call would cause a BlockTooBigError, the miner will stop adding further non-boot contract calls and only include STX transfers and boot contract calls for the remainder of the block.
38+
- Fixed a bug caused by a miner winning a sortition with a block commit that pointed to a previous tip, which would cause the miner to try and reorg itself. [#6481](https://github.com/stacks-network/stacks-core/issues/6481)
2439

2540
### Changed
2641

clarity-types/src/errors/analysis.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,16 @@ pub enum CheckErrors {
307307

308308
// time checker errors
309309
ExecutionTimeExpired,
310+
311+
// contract post-conditions
312+
ExpectedListOfAllowances(String, i32),
313+
AllowanceExprNotAllowed,
314+
ExpectedAllowanceExpr(String),
315+
WithAllAllowanceNotAllowed,
316+
WithAllAllowanceNotAlone,
317+
WithNftExpectedListOfIdentifiers,
318+
MaxIdentifierLengthExceeded(u32, u32),
319+
TooManyAllowances(usize, usize),
310320
}
311321

312322
#[derive(Debug, PartialEq)]
@@ -605,6 +615,14 @@ impl DiagnosableError for CheckErrors {
605615
CheckErrors::CostComputationFailed(s) => format!("contract cost computation failed: {s}"),
606616
CheckErrors::CouldNotDetermineSerializationType => "could not determine the input type for the serialization function".into(),
607617
CheckErrors::ExecutionTimeExpired => "execution time expired".into(),
618+
CheckErrors::ExpectedListOfAllowances(fn_name, arg_num) => format!("{fn_name} expects a list of asset allowances as argument {arg_num}"),
619+
CheckErrors::AllowanceExprNotAllowed => "allowance expressions are only allowed in the context of a `restrict-assets?` or `as-contract?`".into(),
620+
CheckErrors::ExpectedAllowanceExpr(got_name) => format!("expected an allowance expression, got: {got_name}"),
621+
CheckErrors::WithAllAllowanceNotAllowed => "with-all-assets-unsafe is not allowed here, only in the allowance list for `as-contract?`".into(),
622+
CheckErrors::WithAllAllowanceNotAlone => "with-all-assets-unsafe must not be used along with other allowances".into(),
623+
CheckErrors::WithNftExpectedListOfIdentifiers => "with-nft allowance must include a list of asset identifiers".into(),
624+
CheckErrors::MaxIdentifierLengthExceeded(max_len, len) => format!("with-nft allowance identifiers list must not exceed {max_len} elements, got {len}"),
625+
CheckErrors::TooManyAllowances(max_allowed, found) => format!("too many allowances specified, the maximum is {max_allowed}, found {found}"),
608626
}
609627
}
610628

clarity-types/src/types/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,16 @@ impl Value {
12351235
Err(InterpreterError::Expect("Expected response".into()).into())
12361236
}
12371237
}
1238+
1239+
pub fn expect_string_ascii(self) -> Result<String> {
1240+
if let Value::Sequence(SequenceData::String(CharType::ASCII(ASCIIData { data }))) = self {
1241+
Ok(String::from_utf8(data)
1242+
.map_err(|_| InterpreterError::Expect("Non UTF-8 data in string".into()))?)
1243+
} else {
1244+
error!("Value '{self:?}' is not an ASCII string");
1245+
Err(InterpreterError::Expect("Expected ASCII string".into()).into())
1246+
}
1247+
}
12381248
}
12391249

12401250
impl BuffData {

clarity-types/src/types/signatures.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,8 @@ impl TypeSignature {
855855
pub const STRING_ASCII_MAX: TypeSignature = Self::type_ascii_const(MAX_VALUE_SIZE);
856856
/// String ASCII type with length 40.
857857
pub const STRING_ASCII_40: TypeSignature = Self::type_ascii_const(40);
858+
/// String ASCII type with length 128.
859+
pub const STRING_ASCII_128: TypeSignature = Self::type_ascii_const(128);
858860

859861
/// String UTF8 type with minimum length (`1`).
860862
pub const STRING_UTF8_MIN: TypeSignature = Self::type_string_utf8(1);
@@ -908,7 +910,7 @@ impl TypeSignature {
908910

909911
/// Creates a string ASCII type with the specified length.
910912
/// It may panic if the provided length is invalid.
911-
#[cfg(test)]
913+
#[cfg(any(test, feature = "testing"))]
912914
pub const fn new_ascii_type_checked(len: u32) -> Self {
913915
Self::type_ascii_const(len)
914916
}

clarity/src/vm/analysis/arithmetic_checker/mod.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl ArithmeticOnlyChecker<'_> {
143143
match native_var {
144144
ContractCaller | TxSender | TotalLiquidMicroSTX | BlockHeight | BurnBlockHeight
145145
| Regtest | TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight
146-
| BlockTime | CurrentContract => Err(Error::VariableForbidden(native_var)),
146+
| StacksBlockTime | CurrentContract => Err(Error::VariableForbidden(native_var)),
147147
NativeNone | NativeTrue | NativeFalse => Ok(()),
148148
}
149149
} else {
@@ -173,9 +173,31 @@ impl ArithmeticOnlyChecker<'_> {
173173
| ContractCall | StxTransfer | StxTransferMemo | StxBurn | AtBlock | GetStxBalance
174174
| GetTokenSupply | BurnToken | FromConsensusBuff | ToConsensusBuff | BurnAsset
175175
| StxGetAccount => Err(Error::FunctionNotPermitted(function)),
176-
Append | Concat | AsMaxLen | ContractOf | PrincipalOf | ListCons | Print
177-
| AsContract | ElementAt | ElementAtAlias | IndexOf | IndexOfAlias | Map | Filter
178-
| Fold | Slice | ReplaceAt | ContractHash => Err(Error::FunctionNotPermitted(function)),
176+
Append
177+
| Concat
178+
| AsMaxLen
179+
| ContractOf
180+
| PrincipalOf
181+
| ListCons
182+
| Print
183+
| AsContract
184+
| ElementAt
185+
| ElementAtAlias
186+
| IndexOf
187+
| IndexOfAlias
188+
| Map
189+
| Filter
190+
| Fold
191+
| Slice
192+
| ReplaceAt
193+
| ContractHash
194+
| RestrictAssets
195+
| AsContractSafe
196+
| AllowanceWithStx
197+
| AllowanceWithFt
198+
| AllowanceWithNft
199+
| AllowanceWithStacking
200+
| AllowanceAll => Err(Error::FunctionNotPermitted(function)),
179201
BuffToIntLe | BuffToUIntLe | BuffToIntBe | BuffToUIntBe => {
180202
Err(Error::FunctionNotPermitted(function))
181203
}

clarity/src/vm/analysis/read_only_checker/mod.rs

Lines changed: 134 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -282,20 +282,101 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
282282
use crate::vm::functions::NativeFunctions::*;
283283

284284
match function {
285-
Add | Subtract | Divide | Multiply | CmpGeq | CmpLeq | CmpLess | CmpGreater
286-
| Modulo | Power | Sqrti | Log2 | BitwiseXor | And | Or | Not | Hash160 | Sha256
287-
| Keccak256 | Equals | If | Sha512 | Sha512Trunc256 | Secp256k1Recover
288-
| Secp256k1Verify | ConsSome | ConsOkay | ConsError | DefaultTo | UnwrapRet
289-
| UnwrapErrRet | IsOkay | IsNone | Asserts | Unwrap | UnwrapErr | Match | IsErr
290-
| IsSome | TryRet | ToUInt | ToInt | BuffToIntLe | BuffToUIntLe | BuffToIntBe
291-
| BuffToUIntBe | IntToAscii | IntToUtf8 | StringToInt | StringToUInt | IsStandard
292-
| ToConsensusBuff | PrincipalDestruct | PrincipalConstruct | Append | Concat
293-
| AsMaxLen | ContractOf | PrincipalOf | ListCons | GetBlockInfo | GetBurnBlockInfo
294-
| GetStacksBlockInfo | GetTenureInfo | TupleGet | TupleMerge | Len | Print
295-
| AsContract | Begin | FetchVar | GetStxBalance | StxGetAccount | GetTokenBalance
296-
| GetAssetOwner | GetTokenSupply | ElementAt | IndexOf | Slice | ReplaceAt
297-
| BitwiseAnd | BitwiseOr | BitwiseNot | BitwiseLShift | BitwiseRShift | BitwiseXor2
298-
| ElementAtAlias | IndexOfAlias | ContractHash | ToAscii => {
285+
Add
286+
| Subtract
287+
| Divide
288+
| Multiply
289+
| CmpGeq
290+
| CmpLeq
291+
| CmpLess
292+
| CmpGreater
293+
| Modulo
294+
| Power
295+
| Sqrti
296+
| Log2
297+
| BitwiseXor
298+
| And
299+
| Or
300+
| Not
301+
| Hash160
302+
| Sha256
303+
| Keccak256
304+
| Equals
305+
| If
306+
| Sha512
307+
| Sha512Trunc256
308+
| Secp256k1Recover
309+
| Secp256k1Verify
310+
| ConsSome
311+
| ConsOkay
312+
| ConsError
313+
| DefaultTo
314+
| UnwrapRet
315+
| UnwrapErrRet
316+
| IsOkay
317+
| IsNone
318+
| Asserts
319+
| Unwrap
320+
| UnwrapErr
321+
| Match
322+
| IsErr
323+
| IsSome
324+
| TryRet
325+
| ToUInt
326+
| ToInt
327+
| BuffToIntLe
328+
| BuffToUIntLe
329+
| BuffToIntBe
330+
| BuffToUIntBe
331+
| IntToAscii
332+
| IntToUtf8
333+
| StringToInt
334+
| StringToUInt
335+
| IsStandard
336+
| ToConsensusBuff
337+
| PrincipalDestruct
338+
| PrincipalConstruct
339+
| Append
340+
| Concat
341+
| AsMaxLen
342+
| ContractOf
343+
| PrincipalOf
344+
| ListCons
345+
| GetBlockInfo
346+
| GetBurnBlockInfo
347+
| GetStacksBlockInfo
348+
| GetTenureInfo
349+
| TupleGet
350+
| TupleMerge
351+
| Len
352+
| Print
353+
| AsContract
354+
| Begin
355+
| FetchVar
356+
| GetStxBalance
357+
| StxGetAccount
358+
| GetTokenBalance
359+
| GetAssetOwner
360+
| GetTokenSupply
361+
| ElementAt
362+
| IndexOf
363+
| Slice
364+
| ReplaceAt
365+
| BitwiseAnd
366+
| BitwiseOr
367+
| BitwiseNot
368+
| BitwiseLShift
369+
| BitwiseRShift
370+
| BitwiseXor2
371+
| ElementAtAlias
372+
| IndexOfAlias
373+
| ContractHash
374+
| ToAscii
375+
| AllowanceWithStx
376+
| AllowanceWithFt
377+
| AllowanceWithNft
378+
| AllowanceWithStacking
379+
| AllowanceAll => {
299380
// Check all arguments.
300381
self.check_each_expression_is_read_only(args)
301382
}
@@ -427,6 +508,45 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
427508
self.check_each_expression_is_read_only(&args[2..])
428509
.map(|args_read_only| args_read_only && is_function_read_only)
429510
}
511+
RestrictAssets => {
512+
check_arguments_at_least(3, args)?;
513+
514+
// Check the asset owner argument.
515+
let asset_owner_read_only = self.check_read_only(&args[0])?;
516+
517+
// Check the allowances argument.
518+
let allowances =
519+
args[1]
520+
.match_list()
521+
.ok_or(CheckErrors::ExpectedListOfAllowances(
522+
"restrict-assets?".into(),
523+
2,
524+
))?;
525+
let allowances_read_only = self.check_each_expression_is_read_only(allowances)?;
526+
527+
// Check the body expressions.
528+
let body_read_only = self.check_each_expression_is_read_only(&args[2..])?;
529+
530+
Ok(asset_owner_read_only && allowances_read_only && body_read_only)
531+
}
532+
AsContractSafe => {
533+
check_arguments_at_least(2, args)?;
534+
535+
// Check the allowances argument.
536+
let allowances =
537+
args[0]
538+
.match_list()
539+
.ok_or(CheckErrors::ExpectedListOfAllowances(
540+
"as-contract?".into(),
541+
1,
542+
))?;
543+
let allowances_read_only = self.check_each_expression_is_read_only(allowances)?;
544+
545+
// Check the body expressions.
546+
let body_read_only = self.check_each_expression_is_read_only(&args[1..])?;
547+
548+
Ok(allowances_read_only && body_read_only)
549+
}
430550
}
431551
}
432552

clarity/src/vm/analysis/type_checker/v2_05/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,9 @@ fn type_reserved_variable(variable_name: &str) -> Result<Option<TypeSignature>,
330330
NativeFalse => TypeSignature::BoolType,
331331
TotalLiquidMicroSTX => TypeSignature::UIntType,
332332
Regtest => TypeSignature::BoolType,
333-
TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight | BlockTime | CurrentContract => {
333+
TxSponsor | Mainnet | ChainId | StacksBlockHeight | TenureHeight | StacksBlockTime | CurrentContract => {
334334
return Err(CheckErrors::Expects(
335-
"tx-sponsor, mainnet, chain-id, stacks-block-height, tenure-height, block-time, and current-contract should not reach here in 2.05".into(),
335+
"tx-sponsor, mainnet, chain-id, stacks-block-height, tenure-height, stacks-block-time, and current-contract should not reach here in 2.05".into(),
336336
)
337337
.into())
338338
}

0 commit comments

Comments
 (0)