diff --git a/clarity/src/vm/callables.rs b/clarity/src/vm/callables.rs index e4608de67..fe8cf085d 100644 --- a/clarity/src/vm/callables.rs +++ b/clarity/src/vm/callables.rs @@ -82,10 +82,11 @@ pub enum NativeHandle { SingleArg(&'static dyn Fn(Value) -> Result), DoubleArg(&'static dyn Fn(Value, Value) -> Result), MoreArg(&'static dyn Fn(Vec) -> Result), + MoreArgEnv(&'static dyn Fn(Vec, &mut Environment) -> Result), } impl NativeHandle { - pub fn apply(&self, mut args: Vec) -> Result { + pub fn apply(&self, mut args: Vec, env: &mut Environment) -> Result { match self { Self::SingleArg(function) => { check_argument_count(1, &args)?; @@ -98,6 +99,7 @@ impl NativeHandle { function(first, second) } Self::MoreArg(function) => function(args), + Self::MoreArgEnv(function) => function(args, env), } } } @@ -178,7 +180,7 @@ impl DefinedFunction { if *env.contract_context.get_clarity_version() < ClarityVersion::Clarity2 { match (type_sig, value) { ( - TypeSignature::CallableType(CallableSubtype::Trait(trait_identifier)), + TypeSignature::TraitReferenceType(trait_identifier), Value::Principal(PrincipalData::Contract(callee_contract_id)), ) => { // Argument is a trait reference, probably leading to a dynamic contract call diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 178d57a34..f2ebfb617 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -543,14 +543,14 @@ impl EventBatch { impl<'a, 'hooks> OwnedEnvironment<'a, 'hooks> { #[cfg(any(test, feature = "testing"))] - pub fn new(database: ClarityDatabase<'a>) -> OwnedEnvironment<'a, '_> { + pub fn new(database: ClarityDatabase<'a>, epoch: StacksEpochId) -> OwnedEnvironment<'a, '_> { OwnedEnvironment { context: GlobalContext::new( false, CHAIN_ID_TESTNET, database, LimitedCostTracker::new_free(), - StacksEpochId::Epoch2_05, + epoch, ), call_stack: CallStack::new(), } diff --git a/clarity/src/vm/docs/mod.rs b/clarity/src/vm/docs/mod.rs index 5a763edd7..ef4d059ea 100644 --- a/clarity/src/vm/docs/mod.rs +++ b/clarity/src/vm/docs/mod.rs @@ -3035,7 +3035,7 @@ mod test { let conn = store.as_docs_clarity_db(); let docs_test_id = QualifiedContractIdentifier::local("docs-test").unwrap(); let docs_principal_id = PrincipalData::Contract(docs_test_id); - let mut env = OwnedEnvironment::new(conn); + let mut env = OwnedEnvironment::new(conn, StacksEpochId::latest()); let balance = STXBalance::initial(1000); env.execute_in_env::<_, _, ()>( QualifiedContractIdentifier::local("tokens").unwrap().into(), diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index cd242159a..120aa2e4f 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -278,7 +278,7 @@ pub fn lookup_reserved_functions(name: &str, version: &ClarityVersion) -> Option ), Equals => NativeFunction205( "native_eq", - NativeHandle::MoreArg(&native_eq), + NativeHandle::MoreArgEnv(&native_eq), ClarityCostFunction::Eq, &cost_input_sized_vararg, ), @@ -566,7 +566,7 @@ pub fn lookup_reserved_functions(name: &str, version: &ClarityVersion) -> Option } } -fn native_eq(args: Vec) -> Result { +fn native_eq(args: Vec, env: &mut Environment) -> Result { // TODO: this currently uses the derived equality checks of Value, // however, that's probably not how we want to implement equality // checks on the ::ListTypes diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 01b0a706c..235851750 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -289,7 +289,7 @@ pub fn apply( CallableType::NativeFunction(_, function, cost_function) => { runtime_cost(*cost_function, env, evaluated_args.len()) .map_err(Error::from) - .and_then(|_| function.apply(evaluated_args)) + .and_then(|_| function.apply(evaluated_args, env)) } CallableType::NativeFunction205(_, function, cost_function, cost_input_handle) => { let cost_input = if env.epoch() >= &StacksEpochId::Epoch2_05 { @@ -299,7 +299,7 @@ pub fn apply( }; runtime_cost(*cost_function, env, cost_input) .map_err(Error::from) - .and_then(|_| function.apply(evaluated_args)) + .and_then(|_| function.apply(evaluated_args, env)) } CallableType::UserFunction(function) => function.apply(&evaluated_args, env), _ => panic!("Should be unreachable."), diff --git a/clarity/src/vm/tests/assets.rs b/clarity/src/vm/tests/assets.rs index 12447437d..ec13d20a3 100644 --- a/clarity/src/vm/tests/assets.rs +++ b/clarity/src/vm/tests/assets.rs @@ -29,6 +29,7 @@ use crate::vm::types::{ }; use crate::vm::version::ClarityVersion; use crate::vm::ContractContext; +use stacks_common::types::StacksEpochId; use stacks_common::util::hash::hex_bytes; const FIRST_CLASS_TOKENS: &str = "(define-fungible-token stackaroos) @@ -1382,6 +1383,6 @@ fn test_all() { test_native_stx_ops, ]; for test in to_test.iter() { - with_memory_environment(test, true); + with_memory_environment(test, StacksEpochId::latest(), true); } } diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index 5f9b51ab6..fd64f4530 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -21,6 +21,7 @@ use crate::types::chainstate::StacksBlockId; use rstest::rstest; #[cfg(any(test, feature = "testing"))] use rstest_reuse::{self, *}; +use stacks_common::types::StacksEpochId; use crate::vm::ast; use crate::vm::ast::errors::ParseErrors; @@ -140,7 +141,7 @@ fn test_get_block_info_eval() { for i in 0..contracts.len() { let mut marf = MemoryBackingStore::new(); - let mut owned_env = OwnedEnvironment::new(marf.as_clarity_db()); + let mut owned_env = OwnedEnvironment::new(marf.as_clarity_db(), StacksEpochId::latest()); let contract_identifier = QualifiedContractIdentifier::local("test-contract").unwrap(); owned_env .initialize_contract( @@ -1016,7 +1017,7 @@ fn test_at_unknown_block() { } } - with_memory_environment(test, true); + with_memory_environment(test, StacksEpochId::latest(), true); } #[test] @@ -1036,7 +1037,7 @@ fn test_as_max_len() { .unwrap(); } - with_memory_environment(test, true); + with_memory_environment(test, StacksEpochId::latest(), true); } #[test] @@ -1115,6 +1116,7 @@ fn test_cc_stack_depth() { RuntimeErrorType::MaxStackDepthReached.into() ); }, + StacksEpochId::latest(), false, ); } @@ -1157,6 +1159,7 @@ fn test_cc_trait_stack_depth() { RuntimeErrorType::MaxStackDepthReached.into() ); }, + StacksEpochId::latest(), false, ); } @@ -1174,6 +1177,6 @@ fn test_all() { ]; for test in to_test.iter() { eprintln!(".."); - with_memory_environment(test, false); + with_memory_environment(test, StacksEpochId::latest(), false); } } diff --git a/clarity/src/vm/tests/mod.rs b/clarity/src/vm/tests/mod.rs index e90561638..d8367c2c2 100644 --- a/clarity/src/vm/tests/mod.rs +++ b/clarity/src/vm/tests/mod.rs @@ -55,13 +55,13 @@ mod sequences; mod simple_apply_eval; mod traits; -pub fn with_memory_environment(f: F, top_level: bool) +pub fn with_memory_environment(f: F, epoch: StacksEpochId, top_level: bool) where F: FnOnce(&mut OwnedEnvironment) -> (), { let mut marf_kv = MemoryBackingStore::new(); - let mut owned_env = OwnedEnvironment::new(marf_kv.as_clarity_db()); + let mut owned_env = OwnedEnvironment::new(marf_kv.as_clarity_db(), epoch); // start an initial transaction. if !top_level { owned_env.begin(); diff --git a/clarity/src/vm/tests/simple_apply_eval.rs b/clarity/src/vm/tests/simple_apply_eval.rs index 714ff374f..0d82439ab 100644 --- a/clarity/src/vm/tests/simple_apply_eval.rs +++ b/clarity/src/vm/tests/simple_apply_eval.rs @@ -102,7 +102,7 @@ fn test_simple_let(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId if let Ok(parsed_program) = parse(&contract_id, &program, version, epoch) { let context = LocalContext::new(); let mut marf = MemoryBackingStore::new(); - let mut env = OwnedEnvironment::new(marf.as_clarity_db()); + let mut env = OwnedEnvironment::new(marf.as_clarity_db(), StacksEpochId::latest()); assert_eq!( Ok(Value::Int(7)), diff --git a/clarity/src/vm/tests/traits.rs b/clarity/src/vm/tests/traits.rs index 7d3764ac2..226ec63fc 100644 --- a/clarity/src/vm/tests/traits.rs +++ b/clarity/src/vm/tests/traits.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use stacks_common::types::StacksEpochId; + use crate::vm::analysis::errors::CheckError; use crate::vm::ast::ASTRules; use crate::vm::contexts::{Environment, GlobalContext, OwnedEnvironment}; @@ -66,7 +68,7 @@ fn test_all() { test_let3_trait, ]; for test in to_test.iter() { - with_memory_environment(test, false); + with_memory_environment(test, StacksEpochId::latest(), false); } }