Skip to content

Commit dcf76d1

Browse files
committed
tests: fix CheckErrors::NoSuchContract error in tests
1 parent 6aaba9d commit dcf76d1

File tree

2 files changed

+115
-13
lines changed

2 files changed

+115
-13
lines changed

clarity/src/vm/contexts.rs

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ 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};
3940
use crate::vm::database::{
4041
ClarityDatabase, DataMapMetadata, DataVariableMetadata, FungibleTokenMetadata,
41-
NonFungibleTokenMetadata,
42+
MemoryBackingStore, NonFungibleTokenMetadata,
4243
};
4344
use crate::vm::errors::{
4445
CheckErrors, InterpreterError, InterpreterResult as Result, RuntimeErrorType,
@@ -658,13 +659,56 @@ impl<'a> OwnedEnvironment<'a> {
658659
contract_content: &str,
659660
sponsor: Option<PrincipalData>,
660661
ast_rules: ASTRules,
662+
) -> Result<((), AssetMap, Vec<StacksTransactionEvent>)> {
663+
let mut store = MemoryBackingStore::new();
664+
let mut analysis_db = store.as_analysis_db();
665+
analysis_db.begin();
666+
667+
self.initialize_contract_with_db(
668+
contract_identifier,
669+
contract_content,
670+
sponsor,
671+
ast_rules,
672+
&mut analysis_db,
673+
)
674+
}
675+
676+
/// Initializes a Clarity smart contract with a custom analysis database within a transaction context.
677+
///
678+
/// This function should only be used for testing.
679+
///
680+
/// This function creates a complete transaction environment to initialize a Clarity smart contract
681+
/// using a provided memory-backed database for analysis data. It executes the contract initialization
682+
/// within a proper execution context.
683+
///
684+
/// # Arguments
685+
///
686+
/// * `contract_identifier` - Unique identifier for the contract (principal + contract name)
687+
/// * `contract_content` - The raw Clarity source code as a string
688+
/// * `sponsor` - Optional sponsor principal for transaction fees (if `None`, sender pays)
689+
/// * `ast_rules` - Parsing rules to apply during AST construction (e.g., `ASTRules::PrecheckSize`)
690+
/// * `analysis_db` - Mutable reference to a database for analysis data
691+
///
692+
#[cfg(any(test, feature = "testing"))]
693+
pub fn initialize_contract_with_db(
694+
&mut self,
695+
contract_identifier: QualifiedContractIdentifier,
696+
contract_content: &str,
697+
sponsor: Option<PrincipalData>,
698+
ast_rules: ASTRules,
699+
analysis_db: &mut AnalysisDatabase,
661700
) -> Result<((), AssetMap, Vec<StacksTransactionEvent>)> {
662701
self.execute_in_env(
663702
contract_identifier.issuer.clone().into(),
664703
sponsor,
665704
None,
666705
|exec_env| {
667-
exec_env.initialize_contract(contract_identifier, contract_content, ast_rules)
706+
exec_env.initialize_contract_with_db(
707+
contract_identifier,
708+
contract_content,
709+
ast_rules,
710+
analysis_db,
711+
)
668712
},
669713
)
670714
}
@@ -1341,8 +1385,46 @@ impl<'a, 'b> Environment<'a, 'b> {
13411385
contract_content: &str,
13421386
ast_rules: ASTRules,
13431387
) -> Result<()> {
1344-
use super::database::MemoryBackingStore;
1388+
let mut store = MemoryBackingStore::new();
1389+
let mut analysis_db = store.as_analysis_db();
1390+
analysis_db.begin();
1391+
1392+
self.initialize_contract_with_db(
1393+
contract_identifier,
1394+
contract_content,
1395+
ast_rules,
1396+
&mut analysis_db,
1397+
)
1398+
}
13451399

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

13481430
let mut contract_ast = ast::build_ast_with_rules(
@@ -1354,12 +1436,11 @@ impl<'a, 'b> Environment<'a, 'b> {
13541436
ast_rules,
13551437
)?;
13561438

1357-
let mut store = MemoryBackingStore::new();
13581439
let contract_analysis = analysis::run_analysis(
13591440
&contract_identifier,
13601441
&contract_ast.expressions,
1361-
&mut store.as_analysis_db(),
1362-
false,
1442+
analysis_db,
1443+
true,
13631444
LimitedCostTracker::Free,
13641445
self.global_context.epoch_id,
13651446
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

@@ -944,28 +952,35 @@ fn test_overlapping_nfts(
944952
let names_2_contract_id =
945953
QualifiedContractIdentifier::new(p1_std_principal_data, "names-2".into());
946954

955+
let mut store = MemoryBackingStore::new();
956+
let mut analysis_db = store.as_analysis_db();
957+
analysis_db.begin();
958+
947959
owned_env
948-
.initialize_contract(
960+
.initialize_contract_with_db(
949961
tokens_contract_id,
950962
tokens_contract,
951963
None,
952964
ASTRules::PrecheckSize,
965+
&mut analysis_db,
953966
)
954967
.unwrap();
955968
owned_env
956-
.initialize_contract(
969+
.initialize_contract_with_db(
957970
names_contract_id,
958971
names_contract,
959972
None,
960973
ASTRules::PrecheckSize,
974+
&mut analysis_db,
961975
)
962976
.unwrap();
963977
owned_env
964-
.initialize_contract(
978+
.initialize_contract_with_db(
965979
names_2_contract_id,
966980
names_contract,
967981
None,
968982
ASTRules::PrecheckSize,
983+
&mut analysis_db,
969984
)
970985
.unwrap();
971986
}
@@ -1018,22 +1033,28 @@ fn test_simple_naming_system(
10181033
let name_hash_expensive_1 = execute("(hash160 2)");
10191034
let name_hash_cheap_0 = execute("(hash160 100001)");
10201035

1036+
let mut store = MemoryBackingStore::new();
1037+
let mut analysis_db = store.as_analysis_db();
1038+
analysis_db.begin();
1039+
10211040
owned_env
1022-
.initialize_contract(
1041+
.initialize_contract_with_db(
10231042
tokens_contract_id,
10241043
tokens_contract,
10251044
None,
10261045
ASTRules::PrecheckSize,
1046+
&mut analysis_db,
10271047
)
10281048
.unwrap();
10291049

10301050
let names_contract_id = QualifiedContractIdentifier::new(p1_std_principal_data, "names".into());
10311051
owned_env
1032-
.initialize_contract(
1052+
.initialize_contract_with_db(
10331053
names_contract_id.clone(),
10341054
names_contract,
10351055
None,
10361056
ASTRules::PrecheckSize,
1057+
&mut analysis_db,
10371058
)
10381059
.unwrap();
10391060

0 commit comments

Comments
 (0)