Skip to content

Commit f4b5933

Browse files
committed
tests: fix CheckErrors::NoSuchContract error in tests
1 parent 6199c72 commit f4b5933

File tree

2 files changed

+110
-12
lines changed

2 files changed

+110
-12
lines changed

clarity/src/vm/contexts.rs

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ use super::analysis::{self, ContractAnalysis};
3131
#[cfg(feature = "clarity-wasm")]
3232
use super::clarity_wasm::call_function;
3333
use super::EvalHook;
34+
use crate::vm::analysis::AnalysisDatabase;
3435
use crate::vm::ast::{ASTRules, ContractAST};
3536
use crate::vm::callables::{DefinedFunction, FunctionIdentifier};
3637
use crate::vm::contracts::Contract;
3738
use crate::vm::costs::cost_functions::ClarityCostFunction;
3839
use crate::vm::costs::{runtime_cost, CostErrors, CostTracker, ExecutionCost, LimitedCostTracker};
40+
use crate::vm::database::MemoryBackingStore;
3941
use crate::vm::database::{
4042
ClarityDatabase, DataMapMetadata, DataVariableMetadata, FungibleTokenMetadata,
4143
NonFungibleTokenMetadata,
@@ -658,13 +660,51 @@ impl<'a> OwnedEnvironment<'a> {
658660
contract_content: &str,
659661
sponsor: Option<PrincipalData>,
660662
ast_rules: ASTRules,
663+
) -> Result<((), AssetMap, Vec<StacksTransactionEvent>)> {
664+
let mut store = MemoryBackingStore::new();
665+
self.initialize_contract_with_db(
666+
contract_identifier,
667+
contract_content,
668+
sponsor,
669+
ast_rules,
670+
&mut store.as_analysis_db(),
671+
)
672+
}
673+
674+
/// Initializes a Clarity smart contract with a custom analysis database within a transaction context.
675+
///
676+
/// This function creates a complete transaction environment to initialize a Clarity smart contract
677+
/// using a provided memory-backed database for analysis data. It executes the contract initialization
678+
/// within a proper execution context.
679+
///
680+
/// # Arguments
681+
///
682+
/// * `contract_identifier` - Unique identifier for the contract (principal + contract name)
683+
/// * `contract_content` - The raw Clarity source code as a string
684+
/// * `sponsor` - Optional sponsor principal for transaction fees (if `None`, sender pays)
685+
/// * `ast_rules` - Parsing rules to apply during AST construction (e.g., `ASTRules::PrecheckSize`)
686+
/// * `analysis_db` - Mutable reference to a database for analysis data
687+
///
688+
#[cfg(any(test, feature = "testing"))]
689+
pub fn initialize_contract_with_db(
690+
&mut self,
691+
contract_identifier: QualifiedContractIdentifier,
692+
contract_content: &str,
693+
sponsor: Option<PrincipalData>,
694+
ast_rules: ASTRules,
695+
analysis_db: &mut AnalysisDatabase,
661696
) -> Result<((), AssetMap, Vec<StacksTransactionEvent>)> {
662697
self.execute_in_env(
663698
contract_identifier.issuer.clone().into(),
664699
sponsor,
665700
None,
666701
|exec_env| {
667-
exec_env.initialize_contract(contract_identifier, contract_content, ast_rules)
702+
exec_env.initialize_contract_with_db(
703+
contract_identifier,
704+
contract_content,
705+
ast_rules,
706+
analysis_db,
707+
)
668708
},
669709
)
670710
}
@@ -1341,8 +1381,46 @@ impl<'a, 'b> Environment<'a, 'b> {
13411381
contract_content: &str,
13421382
ast_rules: ASTRules,
13431383
) -> Result<()> {
1344-
use super::database::MemoryBackingStore;
1384+
let mut store = MemoryBackingStore::new();
1385+
let mut analysis_db = store.as_analysis_db();
1386+
analysis_db.begin();
1387+
1388+
self.initialize_contract_with_db(
1389+
contract_identifier,
1390+
contract_content,
1391+
ast_rules,
1392+
&mut analysis_db,
1393+
)
1394+
}
13451395

1396+
/// Initializes a Clarity smart contract with a custom analysis database.
1397+
///
1398+
/// This function should only be used for testing.
1399+
///
1400+
/// This function parses and analyzes a Clarity smart contract using
1401+
/// a provided database for analysis data. It's primarily used for testing
1402+
/// scenarios where you need control over the backing storage.
1403+
///
1404+
/// # Arguments
1405+
///
1406+
/// * `contract_identifier` - Unique identifier for the contract (principal + name)
1407+
/// * `contract_content` - The raw Clarity source code as a string
1408+
/// * `ast_rules` - Parsing rules to apply during AST construction
1409+
/// * `analysis_db` - Mutable reference to a database for analysis data
1410+
///
1411+
/// # Returns
1412+
///
1413+
/// * `Ok(())` - Contract successfully initialized
1414+
/// * `Err(Error)` - Initialization failed due to parsing or analysis
1415+
///
1416+
#[cfg(feature = "rusqlite")]
1417+
pub fn initialize_contract_with_db(
1418+
&mut self,
1419+
contract_identifier: QualifiedContractIdentifier,
1420+
contract_content: &str,
1421+
ast_rules: ASTRules,
1422+
analysis_db: &mut AnalysisDatabase,
1423+
) -> Result<()> {
13461424
let clarity_version = self.contract_context.clarity_version;
13471425

13481426
let mut contract_ast = ast::build_ast_with_rules(
@@ -1354,12 +1432,11 @@ impl<'a, 'b> Environment<'a, 'b> {
13541432
ast_rules,
13551433
)?;
13561434

1357-
let mut store = MemoryBackingStore::new();
13581435
let contract_analysis = analysis::run_analysis(
13591436
&contract_identifier,
13601437
&contract_ast.expressions,
1361-
&mut store.as_analysis_db(),
1362-
false,
1438+
analysis_db,
1439+
true,
13631440
LimitedCostTracker::Free,
13641441
self.global_context.epoch_id,
13651442
clarity_version,

clarity/src/vm/tests/assets.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
use stacks_common::types::StacksEpochId;
1818

19+
use crate::vm::analysis::analysis_db;
1920
use crate::vm::ast::ASTRules;
2021
use crate::vm::contexts::{AssetMap, AssetMapEntry, OwnedEnvironment};
22+
use crate::vm::database::MemoryBackingStore;
2123
use crate::vm::errors::{CheckErrors, Error, RuntimeErrorType};
2224
use crate::vm::events::StacksTransactionEvent;
2325
use crate::vm::representations::SymbolicExpression;
@@ -176,20 +178,26 @@ fn test_native_stx_ops(epoch: StacksEpochId, mut env_factory: TopLevelMemoryEnvi
176178
let second_contract_id =
177179
QualifiedContractIdentifier::new(p1_std_principal_data, "second".into());
178180

181+
let mut store = MemoryBackingStore::new();
182+
let mut analysis_db = store.as_analysis_db();
183+
analysis_db.begin();
184+
179185
owned_env
180-
.initialize_contract(
186+
.initialize_contract_with_db(
181187
token_contract_id.clone(),
182188
contract,
183189
None,
184190
ASTRules::PrecheckSize,
191+
&mut analysis_db,
185192
)
186193
.unwrap();
187194
owned_env
188-
.initialize_contract(
195+
.initialize_contract_with_db(
189196
second_contract_id.clone(),
190197
contract_second,
191198
None,
192199
ASTRules::PrecheckSize,
200+
&mut analysis_db,
193201
)
194202
.unwrap();
195203

@@ -941,28 +949,35 @@ fn test_overlapping_nfts(
941949
let names_2_contract_id =
942950
QualifiedContractIdentifier::new(p1_std_principal_data, "names-2".into());
943951

952+
let mut store = MemoryBackingStore::new();
953+
let mut analysis_db = store.as_analysis_db();
954+
analysis_db.begin();
955+
944956
owned_env
945-
.initialize_contract(
957+
.initialize_contract_with_db(
946958
tokens_contract_id,
947959
tokens_contract,
948960
None,
949961
ASTRules::PrecheckSize,
962+
&mut analysis_db,
950963
)
951964
.unwrap();
952965
owned_env
953-
.initialize_contract(
966+
.initialize_contract_with_db(
954967
names_contract_id,
955968
names_contract,
956969
None,
957970
ASTRules::PrecheckSize,
971+
&mut analysis_db,
958972
)
959973
.unwrap();
960974
owned_env
961-
.initialize_contract(
975+
.initialize_contract_with_db(
962976
names_2_contract_id,
963977
names_contract,
964978
None,
965979
ASTRules::PrecheckSize,
980+
&mut analysis_db,
966981
)
967982
.unwrap();
968983
}
@@ -1015,22 +1030,28 @@ fn test_simple_naming_system(
10151030
let name_hash_expensive_1 = execute("(hash160 2)");
10161031
let name_hash_cheap_0 = execute("(hash160 100001)");
10171032

1033+
let mut store = MemoryBackingStore::new();
1034+
let mut analysis_db = store.as_analysis_db();
1035+
analysis_db.begin();
1036+
10181037
owned_env
1019-
.initialize_contract(
1038+
.initialize_contract_with_db(
10201039
tokens_contract_id,
10211040
tokens_contract,
10221041
None,
10231042
ASTRules::PrecheckSize,
1043+
&mut analysis_db,
10241044
)
10251045
.unwrap();
10261046

10271047
let names_contract_id = QualifiedContractIdentifier::new(p1_std_principal_data, "names".into());
10281048
owned_env
1029-
.initialize_contract(
1049+
.initialize_contract_with_db(
10301050
names_contract_id.clone(),
10311051
names_contract,
10321052
None,
10331053
ASTRules::PrecheckSize,
1054+
&mut analysis_db,
10341055
)
10351056
.unwrap();
10361057

0 commit comments

Comments
 (0)