Skip to content

Commit 06a8b7b

Browse files
committed
Merge remote-tracking branch 'origin/next' into feat/to-from-buff
2 parents d6a6180 + f38a266 commit 06a8b7b

File tree

42 files changed

+1770
-1157
lines changed

Some content is hidden

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

42 files changed

+1770
-1157
lines changed

CHANGELOG.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,23 @@ This release will contain consensus-breaking changes.
1515

1616
## [2.05.0.2.0]
1717

18+
### IMPORTANT! READ THIS FIRST
19+
20+
Please read the following **WARNINGs** in their entirety before upgrading.
21+
1822
WARNING: Please be aware that using this node on chainstate prior to this release will cause
19-
the node to spend up to 30 minutes migrating the data to a new schema.
23+
the node to spend **up to 30 minutes** migrating the data to a new schema.
24+
Depending on the storage medium, this may take even longer.
25+
26+
WARNING: This migration process cannot be interrupted. If it is, the chainstate
27+
will be **irrecovarably corrupted and require a sync from genesis.**
28+
29+
WARNING: You will need **at least 2x the disk space** for the migration to work.
30+
This is because a copy of the chainstate will be made in the same directory in
31+
order to apply the new schema.
32+
33+
It is highly recommended that you **back up your chainstate** before running
34+
this version of the software on it.
2035

2136
### Changed
2237
- The MARF implementation will now defer calculating the root hash of a new trie
@@ -30,9 +45,7 @@ the node to spend up to 30 minutes migrating the data to a new schema.
3045
- The MARF implementation may now cache trie nodes in RAM if directed to do so
3146
by an environment variable (#3042).
3247
- Sortition processing performance has been improved by about an order of
33-
magnitude, by avoiding a slew of expensive database reads (#3045). WARNING:
34-
applying this change to an existing chainstate directory will take a few
35-
minutes when the node starts up.
48+
magnitude, by avoiding a slew of expensive database reads (#3045).
3649
- Updated chains coordinator so that before a Stacks block or a burn block is processed,
3750
an event is sent through the event dispatcher. This fixes #3015.
3851
- Expose a node's public key and public key hash160 (i.e. what appears in

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,10 @@ impl<'a> ArithmeticOnlyChecker<'a> {
188188
| AsContract | ElementAt | IndexOf | Map | Filter | Fold | Slice => {
189189
return Err(Error::FunctionNotPermitted(function));
190190
}
191-
BuffToIntLe | BuffToUIntLe | BuffToIntBe | BuffToUIntBe | IsStandard => {
191+
BuffToIntLe | BuffToUIntLe | BuffToIntBe | BuffToUIntBe => {
192+
return Err(Error::FunctionNotPermitted(function));
193+
}
194+
IsStandard | PrincipalDestruct | PrincipalConstruct => {
192195
return Err(Error::FunctionNotPermitted(function));
193196
}
194197
IntToAscii | IntToUtf8 | StringToInt | StringToUInt => {

clarity/src/vm/analysis/errors.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub enum CheckErrors {
150150

151151
// argument counts
152152
RequiresAtLeastArguments(usize, usize),
153+
RequiresAtMostArguments(usize, usize),
153154
IncorrectArgumentCount(usize, usize),
154155
IfArmsMustMatch(TypeSignature, TypeSignature),
155156
MatchArmsMustMatch(TypeSignature, TypeSignature),
@@ -287,6 +288,14 @@ pub fn check_arguments_at_least<T>(expected: usize, args: &[T]) -> Result<(), Ch
287288
}
288289
}
289290

291+
pub fn check_arguments_at_most<T>(expected: usize, args: &[T]) -> Result<(), CheckErrors> {
292+
if args.len() > expected {
293+
Err(CheckErrors::RequiresAtMostArguments(expected, args.len()))
294+
} else {
295+
Ok(())
296+
}
297+
}
298+
290299
fn formatted_expected_types(expected_types: &Vec<TypeSignature>) -> String {
291300
let mut expected_types_joined = format!("'{}'", expected_types[0]);
292301

@@ -383,7 +392,8 @@ impl DiagnosableError for CheckErrors {
383392
CheckErrors::MaxContextDepthReached => format!("reached depth limit"),
384393
CheckErrors::UndefinedVariable(var_name) => format!("use of unresolved variable '{}'", var_name),
385394
CheckErrors::UndefinedFunction(var_name) => format!("use of unresolved function '{}'", var_name),
386-
CheckErrors::RequiresAtLeastArguments(expected, found) => format!("expecting >= {} argument, got {}", expected, found),
395+
CheckErrors::RequiresAtLeastArguments(expected, found) => format!("expecting >= {} arguments, got {}", expected, found),
396+
CheckErrors::RequiresAtMostArguments(expected, found) => format!("expecting < {} arguments, got {}", expected, found),
387397
CheckErrors::IncorrectArgumentCount(expected_count, found_count) => format!("expecting {} arguments, got {}", expected_count, found_count),
388398
CheckErrors::IfArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'if' must match (got '{}' and '{}')", type_1, type_2),
389399
CheckErrors::MatchArmsMustMatch(type_1, type_2) => format!("expression types returned by the arms of 'match' must match (got '{}' and '{}')", type_1, type_2),

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,11 @@ impl<'a, 'b> ReadOnlyChecker<'a, 'b> {
282282
| UnwrapErrRet | IsOkay | IsNone | Asserts | Unwrap | UnwrapErr | Match | IsErr
283283
| IsSome | TryRet | ToUInt | ToInt | BuffToIntLe | BuffToUIntLe | BuffToIntBe
284284
| BuffToUIntBe | IntToAscii | IntToUtf8 | StringToInt | StringToUInt | IsStandard
285-
| Append | Concat | AsMaxLen | ContractOf | PrincipalOf | ListCons | GetBlockInfo
286-
| GetBurnBlockInfo | TupleGet | TupleMerge | Len | Print | AsContract | Begin
287-
| FetchVar | GetStxBalance | StxGetAccount | GetTokenBalance | GetAssetOwner
288-
| GetTokenSupply | ElementAt | IndexOf | Slice | ToConsensusBuff => {
285+
| ToConsensusBuff | PrincipalDestruct | PrincipalConstruct | Append | Concat
286+
| AsMaxLen | ContractOf | PrincipalOf | ListCons | GetBlockInfo | GetBurnBlockInfo
287+
| TupleGet | TupleMerge | Len | Print | AsContract | Begin | FetchVar
288+
| GetStxBalance | StxGetAccount | GetTokenBalance | GetAssetOwner | GetTokenSupply
289+
| ElementAt | IndexOf | Slice => {
289290
// Check all arguments.
290291
self.check_each_expression_is_read_only(args)
291292
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ use self::contexts::{ContractContext, TypeMap, TypingContext};
4848
pub use self::natives::{SimpleNativeFunction, TypedNativeFunction};
4949

5050
pub use super::errors::{
51-
check_argument_count, check_arguments_at_least, CheckError, CheckErrors, CheckResult,
51+
check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError,
52+
CheckErrors, CheckResult,
5253
};
5354
use crate::vm::contexts::Environment;
5455
use crate::vm::costs::cost_functions::ClarityCostFunction;

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

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
use super::{
18-
check_argument_count, check_arguments_at_least, no_type, TypeChecker, TypeResult, TypingContext,
18+
check_argument_count, check_arguments_at_least, check_arguments_at_most, no_type, TypeChecker,
19+
TypeResult, TypingContext,
1920
};
2021
use std::convert::TryFrom;
2122

@@ -28,7 +29,7 @@ use crate::vm::types::TypeSignature::SequenceType;
2829
use crate::vm::types::{
2930
BlockInfoProperty, BufferLength, BurnBlockInfoProperty, FixedFunction, FunctionArg,
3031
FunctionSignature, FunctionType, PrincipalData, TupleTypeSignature, TypeSignature, Value,
31-
BUFF_20, BUFF_32, BUFF_33, BUFF_64, BUFF_65, MAX_VALUE_SIZE,
32+
BUFF_1, BUFF_20, BUFF_32, BUFF_33, BUFF_64, BUFF_65, MAX_VALUE_SIZE,
3233
};
3334
use crate::vm::{ClarityName, SymbolicExpression, SymbolicExpressionType};
3435

@@ -481,6 +482,44 @@ fn check_principal_of(
481482
Ok(TypeSignature::new_response(TypeSignature::PrincipalType, TypeSignature::UIntType).unwrap())
482483
}
483484

485+
/// Forms:
486+
/// (define-public (principal-construct (buff 1) (buff 20))
487+
/// (response principal { error_code: uint, principal: (option principal) }))
488+
///
489+
/// (define-public (principal-construct (buff 1) (buff 20) (string-ascii CONTRACT_MAX_NAME_LENGTH))
490+
/// (response principal { error_code: uint, principal: (option principal) }))
491+
fn check_principal_construct(
492+
checker: &mut TypeChecker,
493+
args: &[SymbolicExpression],
494+
context: &TypingContext,
495+
) -> TypeResult {
496+
check_arguments_at_least(2, args)?;
497+
check_arguments_at_most(3, args)?;
498+
checker.type_check_expects(&args[0], context, &BUFF_1)?;
499+
checker.type_check_expects(&args[1], context, &BUFF_20)?;
500+
if args.len() > 2 {
501+
checker.type_check_expects(
502+
&args[2],
503+
context,
504+
&TypeSignature::contract_name_string_ascii_type(),
505+
)?;
506+
}
507+
Ok(TypeSignature::new_response(
508+
TypeSignature::PrincipalType,
509+
TupleTypeSignature::try_from(vec![
510+
("error_code".into(), TypeSignature::UIntType),
511+
(
512+
"principal".into(),
513+
TypeSignature::new_option(TypeSignature::PrincipalType).expect("FATAL: failed to create (optional principal) type signature"),
514+
),
515+
])
516+
.expect("FAIL: PrincipalConstruct failed to initialize type signature")
517+
.into()
518+
)
519+
.expect("FATAL: failed to create `(response principal { error_code: uint, principal: (optional principal) })` type signature")
520+
)
521+
}
522+
484523
fn check_secp256k1_recover(
485524
checker: &mut TypeChecker,
486525
args: &[SymbolicExpression],
@@ -716,6 +755,37 @@ impl TypedNativeFunction {
716755
)],
717756
returns: TypeSignature::UIntType,
718757
}))),
758+
PrincipalConstruct => Special(SpecialNativeFunction(&check_principal_construct)),
759+
PrincipalDestruct => Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction {
760+
args: vec![FunctionArg::new(
761+
TypeSignature::PrincipalType,
762+
ClarityName::try_from("principal".to_owned())
763+
.expect("FAIL: ClarityName failed to accept default arg name"),
764+
)],
765+
returns: {
766+
/// The return type of `principal-destruct` is a Response, in which the success
767+
/// and error types are the same.
768+
fn parse_principal_basic_type() -> TypeSignature {
769+
TupleTypeSignature::try_from(vec![
770+
("version".into(), BUFF_1.clone()),
771+
("hash-bytes".into(), BUFF_20.clone()),
772+
(
773+
"name".into(),
774+
TypeSignature::new_option(
775+
TypeSignature::contract_name_string_ascii_type(),
776+
)
777+
.unwrap(),
778+
),
779+
])
780+
.expect("FAIL: PrincipalDestruct failed to initialize type signature")
781+
.into()
782+
}
783+
TypeSignature::ResponseType(Box::new((
784+
parse_principal_basic_type(),
785+
parse_principal_basic_type(),
786+
)))
787+
},
788+
}))),
719789
StxGetAccount => Simple(SimpleNativeFunction(FunctionType::Fixed(FixedFunction {
720790
args: vec![FunctionArg::new(
721791
TypeSignature::PrincipalType,

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

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::vm::execute_v2;
3131
use crate::vm::representations::SymbolicExpression;
3232
use crate::vm::types::{
3333
BufferLength, FixedFunction, FunctionType, PrincipalData, QualifiedContractIdentifier,
34-
TypeSignature, Value, BUFF_32, BUFF_64,
34+
TypeSignature, Value, BUFF_1, BUFF_20, BUFF_21, BUFF_32, BUFF_64,
3535
};
3636

3737
use crate::vm::database::MemoryBackingStore;
@@ -47,6 +47,8 @@ use std::convert::TryInto;
4747
use super::CheckResult;
4848
use crate::vm::ClarityVersion;
4949

50+
use crate::vm::analysis::type_checker::SequenceSubtype;
51+
5052
mod assets;
5153
pub mod contracts;
5254

@@ -2819,3 +2821,124 @@ fn test_comparison_types() {
28192821
assert_eq!(expected, &type_check_helper(&bad_test).unwrap_err().err);
28202822
}
28212823
}
2824+
2825+
#[test]
2826+
fn test_principal_destruct() {
2827+
let good = [
2828+
// Standard good examples.
2829+
r#"(principal-destruct 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6)"#,
2830+
r#"(principal-destruct 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6.foo)"#,
2831+
];
2832+
let expected = [
2833+
"(response (tuple (hash-bytes (buff 20)) (name (optional (string-ascii 40))) (version (buff 1))) (tuple (hash-bytes (buff 20)) (name (optional (string-ascii 40))) (version (buff 1))))",
2834+
"(response (tuple (hash-bytes (buff 20)) (name (optional (string-ascii 40))) (version (buff 1))) (tuple (hash-bytes (buff 20)) (name (optional (string-ascii 40))) (version (buff 1))))"
2835+
];
2836+
2837+
let bad = [
2838+
// Too many arguments.
2839+
r#"(principal-destruct 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6)"#,
2840+
// Too few arguments.
2841+
r#"(principal-destruct)"#,
2842+
// Wrong type of arguments.
2843+
r#"(principal-destruct 0x22)"#,
2844+
];
2845+
let bad_expected = [
2846+
CheckErrors::IncorrectArgumentCount(1, 2),
2847+
CheckErrors::IncorrectArgumentCount(1, 0),
2848+
CheckErrors::TypeError(TypeSignature::PrincipalType, BUFF_1.clone()),
2849+
];
2850+
2851+
for (good_test, expected) in good.iter().zip(expected.iter()) {
2852+
assert_eq!(
2853+
expected,
2854+
&format!("{}", type_check_helper(&good_test).unwrap())
2855+
);
2856+
}
2857+
2858+
for (bad_test, expected) in bad.iter().zip(bad_expected.iter()) {
2859+
assert_eq!(expected, &type_check_helper(&bad_test).unwrap_err().err);
2860+
}
2861+
}
2862+
2863+
#[test]
2864+
fn test_principal_construct() {
2865+
// This is the type we expect on success.
2866+
let expected_type =
2867+
"(response principal (tuple (error_code uint) (principal (optional principal))))";
2868+
let good_pairs = [
2869+
// Standard good example of a standard principal
2870+
(
2871+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320)"#,
2872+
expected_type,
2873+
),
2874+
// Standard good example of a contract principal.
2875+
(
2876+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foo")"#,
2877+
expected_type,
2878+
),
2879+
// Note: This following buffer is too short. It type-checks but triggers a runtime error.
2880+
(r#"(principal-construct 0x22 0x00)"#, expected_type),
2881+
// Note: This following name is too short. It type-checks but triggers a runtime error.
2882+
(
2883+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "")"#,
2884+
expected_type,
2885+
),
2886+
];
2887+
2888+
for (good_test, expected) in good_pairs.iter() {
2889+
assert_eq!(
2890+
expected,
2891+
&format!("{}", type_check_helper(&good_test).unwrap())
2892+
);
2893+
}
2894+
2895+
let bad_pairs = [
2896+
// Too few arguments, just has the `(buff 1)`.
2897+
(
2898+
r#"(principal-construct 0x22)"#,
2899+
CheckErrors::RequiresAtLeastArguments(2, 1),
2900+
),
2901+
// Too few arguments, just hs the `(buff 20)`.
2902+
(
2903+
r#"(principal-construct 0xfa6bf38ed557fe417333710d6033e9419391a320)"#,
2904+
CheckErrors::RequiresAtLeastArguments(2, 1),
2905+
),
2906+
// The first buffer is too long, should be `(buff 1)`.
2907+
(
2908+
r#"(principal-construct 0xfa6bf38ed557fe417333710d6033e9419391a320 0xfa6bf38ed557fe417333710d6033e9419391a320)"#,
2909+
CheckErrors::TypeError(BUFF_1.clone(), BUFF_20.clone()),
2910+
),
2911+
// The second buffer is too long, should be `(buff 20)`.
2912+
(
2913+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a32009)"#,
2914+
CheckErrors::TypeError(BUFF_20.clone(), BUFF_21.clone()),
2915+
),
2916+
// `int` argument instead of `(buff 1)` for version.
2917+
(
2918+
r#"(principal-construct 22 0xfa6bf38ed557fe417333710d6033e9419391a320)"#,
2919+
CheckErrors::TypeError(BUFF_1.clone(), IntType),
2920+
),
2921+
// `name` argument is too long
2922+
(
2923+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foooooooooooooooooooooooooooooooooooooooo")"#,
2924+
CheckErrors::TypeError(
2925+
TypeSignature::contract_name_string_ascii_type(),
2926+
TypeSignature::bound_string_ascii_type(41),
2927+
),
2928+
),
2929+
// bad argument type for `name`
2930+
(
2931+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 u123)"#,
2932+
CheckErrors::TypeError(TypeSignature::contract_name_string_ascii_type(), UIntType),
2933+
),
2934+
// too many arguments
2935+
(
2936+
r#"(principal-construct 0x22 0xfa6bf38ed557fe417333710d6033e9419391a320 "foo" "bar")"#,
2937+
CheckErrors::RequiresAtMostArguments(3, 4),
2938+
),
2939+
];
2940+
2941+
for (bad_test, expected) in bad_pairs.iter() {
2942+
assert_eq!(expected, &type_check_helper(&bad_test).unwrap_err().err);
2943+
}
2944+
}

0 commit comments

Comments
 (0)