From 96d68e4405eebb3478eea6bc87c8b0e1c5689681 Mon Sep 17 00:00:00 2001 From: bestmike007 Date: Fri, 19 Apr 2024 16:07:18 +0000 Subject: [PATCH] chore: properly handle context rollback for eval readonly --- clarity/src/vm/contexts.rs | 6 +++++- clarity/src/vm/tests/contracts.rs | 35 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/clarity/src/vm/contexts.rs b/clarity/src/vm/contexts.rs index 305c12198..15ead867a 100644 --- a/clarity/src/vm/contexts.rs +++ b/clarity/src/vm/contexts.rs @@ -973,7 +973,11 @@ impl<'a, 'b, 'hooks> Environment<'a, 'b, 'hooks> { let contract = self .global_context .database - .get_contract(contract_identifier)?; + .get_contract(contract_identifier) + .or_else(|e| { + self.global_context.roll_back()?; + Err(e) + })?; let result = { let mut nested_env = Environment::new( diff --git a/clarity/src/vm/tests/contracts.rs b/clarity/src/vm/tests/contracts.rs index 817a74917..ca3bd3c10 100644 --- a/clarity/src/vm/tests/contracts.rs +++ b/clarity/src/vm/tests/contracts.rs @@ -1147,3 +1147,38 @@ fn test_cc_trait_stack_depth( RuntimeErrorType::MaxStackDepthReached.into() ); } + +#[apply(test_epochs)] +fn test_eval_with_non_existing_contract( + epoch: StacksEpochId, + mut env_factory: MemoryEnvironmentGenerator, +) { + let mut owned_env = env_factory.get_env(epoch); + + let mut placeholder_context = ContractContext::new( + QualifiedContractIdentifier::transient(), + ClarityVersion::Clarity2, + ); + + let mut env = owned_env.get_exec_environment( + Some(get_principal().expect_principal().unwrap()), + None, + &mut placeholder_context, + ); + + let result = env.eval_read_only( + &QualifiedContractIdentifier::local("absent").unwrap(), + "(ok 0)", + ); + assert_eq!( + result.as_ref().unwrap_err(), + &Error::Unchecked(CheckErrors::NoSuchContract( + QualifiedContractIdentifier::local("absent") + .unwrap() + .to_string() + )) + ); + drop(env); + owned_env.commit().unwrap(); + assert!(owned_env.destruct().is_some()); +}