diff --git a/Cargo.lock b/Cargo.lock index 500e15aaf3..ac5209810f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3369,6 +3369,7 @@ dependencies = [ "mutants", "nix", "percent-encoding", + "pinny", "pox-locking 2.4.0", "prometheus", "proptest", diff --git a/clarity/src/vm/version.rs b/clarity/src/vm/version.rs index 41226cfad9..445a957d2d 100644 --- a/clarity/src/vm/version.rs +++ b/clarity/src/vm/version.rs @@ -29,6 +29,13 @@ impl ClarityVersion { ClarityVersion::Clarity4 } + pub const ALL: &'static [ClarityVersion] = &[ + ClarityVersion::Clarity1, + ClarityVersion::Clarity2, + ClarityVersion::Clarity3, + ClarityVersion::Clarity4, + ]; + pub fn default_for_epoch(epoch_id: StacksEpochId) -> ClarityVersion { match epoch_id { StacksEpochId::Epoch10 => { diff --git a/stacks-common/src/types/mod.rs b/stacks-common/src/types/mod.rs index ffe1477d51..19db0e515c 100644 --- a/stacks-common/src/types/mod.rs +++ b/stacks-common/src/types/mod.rs @@ -447,6 +447,13 @@ impl StacksEpochId { StacksEpochId::Epoch32 } + pub const ALL_GTE_30: &'static [StacksEpochId] = &[ + StacksEpochId::Epoch30, + StacksEpochId::Epoch31, + StacksEpochId::Epoch32, + StacksEpochId::Epoch33, + ]; + /// In this epoch, how should the mempool perform garbage collection? pub fn mempool_garbage_behavior(&self) -> MempoolCollectionBehavior { match self { diff --git a/stackslib/Cargo.toml b/stackslib/Cargo.toml index 6d2f85dfd0..1d088cda33 100644 --- a/stackslib/Cargo.toml +++ b/stackslib/Cargo.toml @@ -80,6 +80,7 @@ chrono = "0.4.19" tempfile = "3.3" proptest = { version = "1.6.0", default-features = false, features = ["std"] } insta = { version = "1.37.0", features = ["ron"] } +pinny = { git = "https://github.com/BitcoinL2-Labs/pinny-rs.git", rev = "54ba9d533a7b84525a5e65a3eae1a3ae76b9ea49" } #v0.0.2 [features] default = [] @@ -95,3 +96,6 @@ sha2 = { version = "0.10", features = ["asm"] } [target.'cfg(any(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")), any(target_os="windows")))'.dependencies] sha2 = { version = "0.10" } + +[package.metadata.pinny] +allowed = ["consensus"] diff --git a/stackslib/src/chainstate/tests/consensus.rs b/stackslib/src/chainstate/tests/consensus.rs index 2526ceaf1a..abb4e275e0 100644 --- a/stackslib/src/chainstate/tests/consensus.rs +++ b/stackslib/src/chainstate/tests/consensus.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . use std::cell::LazyCell; -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use clarity::boot_util::boot_code_addr; use clarity::codec::StacksMessageCodec; @@ -30,37 +30,38 @@ use clarity::util::secp256k1::MessageSignature; use clarity::vm::ast::stack_depth_checker::AST_CALL_STACK_DEPTH_BUFFER; use clarity::vm::costs::ExecutionCost; use clarity::vm::types::PrincipalData; -use clarity::vm::{Value as ClarityValue, MAX_CALL_STACK_DEPTH}; -use serde::{Deserialize, Serialize}; +use clarity::vm::{ClarityVersion, Value as ClarityValue, MAX_CALL_STACK_DEPTH}; +use pinny::tag; +use serde::{Deserialize, Serialize, Serializer}; use stacks_common::bitvec::BitVec; use crate::burnchains::PoxConstants; use crate::chainstate::burn::db::sortdb::SortitionDB; use crate::chainstate::nakamoto::{NakamotoBlock, NakamotoBlockHeader, NakamotoChainState}; use crate::chainstate::stacks::db::{ClarityTx, StacksChainState, StacksEpochReceipt}; +use crate::chainstate::stacks::events::TransactionOrigin; use crate::chainstate::stacks::tests::TestStacksNode; use crate::chainstate::stacks::{ - Error as ChainstateError, StacksTransaction, TenureChangeCause, MINER_BLOCK_CONSENSUS_HASH, + Error as ChainstateError, StacksTransaction, TenureChangeCause, TransactionContractCall, + TransactionPayload, TransactionSmartContract, MINER_BLOCK_CONSENSUS_HASH, MINER_BLOCK_HEADER_HASH, }; use crate::chainstate::tests::TestChainstate; use crate::core::test_util::{ - make_contract_call, make_contract_publish, make_stacks_transfer_tx, to_addr, + make_contract_call, make_contract_publish_versioned, make_stacks_transfer_tx, to_addr, }; use crate::core::{EpochList, BLOCK_LIMIT_MAINNET_21}; use crate::net::tests::NakamotoBootPlan; +/// The epochs to test for consensus are the current and upcoming epochs. +/// This constant must be changed when new epochs are introduced. +/// Note that contract deploys MUST be done in each epoch >= 2.0. +const EPOCHS_TO_TEST: &[StacksEpochId] = &[StacksEpochId::Epoch32, StacksEpochId::Epoch33]; + pub const SK_1: &str = "a1289f6438855da7decf9b61b852c882c398cff1446b2a0f823538aa2ebef92e01"; pub const SK_2: &str = "4ce9a8f7539ea93753a36405b16e8b57e15a552430410709c2b6d65dca5c02e201"; pub const SK_3: &str = "cb95ddd0fe18ec57f4f3533b95ae564b3f1ae063dbf75b46334bd86245aef78501"; -const EPOCHS_TO_TEST: [StacksEpochId; 4] = [ - StacksEpochId::Epoch30, - StacksEpochId::Epoch31, - StacksEpochId::Epoch32, - StacksEpochId::Epoch33, -]; - /// The private key for the faucet account. pub const FAUCET_PRIV_KEY: LazyCell = LazyCell::new(|| { StacksPrivateKey::from_hex("510f96a8efd0b11e211733c1ac5e3fa6f3d3fcdd62869e376c47decb3e14fea101") @@ -70,6 +71,456 @@ pub const FAUCET_PRIV_KEY: LazyCell = LazyCell::new(|| { const FOO_CONTRACT: &str = "(define-public (foo) (ok 1)) (define-public (bar (x uint)) (ok x))"; +/// Returns the list of Clarity versions that can be used to deploy contracts in the given epoch. +const fn clarity_versions_for_epoch(epoch: StacksEpochId) -> &'static [ClarityVersion] { + match epoch { + StacksEpochId::Epoch10 => &[], + StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => &[ClarityVersion::Clarity1], + StacksEpochId::Epoch21 + | StacksEpochId::Epoch22 + | StacksEpochId::Epoch23 + | StacksEpochId::Epoch24 + | StacksEpochId::Epoch25 => &[ClarityVersion::Clarity1, ClarityVersion::Clarity2], + StacksEpochId::Epoch30 | StacksEpochId::Epoch31 | StacksEpochId::Epoch32 => &[ + ClarityVersion::Clarity1, + ClarityVersion::Clarity2, + ClarityVersion::Clarity3, + ], + StacksEpochId::Epoch33 => &[ + ClarityVersion::Clarity1, + ClarityVersion::Clarity2, + ClarityVersion::Clarity3, + ClarityVersion::Clarity4, + ], + } +} + +/// Helper for [`contract_consensus_test!`] to run a contract function across multiple epochs. +/// +/// This function orchestrates deploying a contract and calling a function across different +/// Stacks epochs and Clarity versions. It is designed for consensus-critical testing. +/// +/// It first deploys the contract in `deploy_epochs` for each applicable Clarity version, +/// then calls the function in `call_epochs` on all previously deployed contracts. The +/// entire operation is run as a single `ConsensusTest`. +/// +/// # Arguments +/// +/// * `contract_name` - Base name for the contract. +/// * `contract_code` - The Clarity source code. +/// * `function_name` - The public function to call. +/// * `function_args` - Arguments for the function call. +/// * `deploy_epochs` - Epochs for contract deployment. +/// * `call_epochs` - Epochs for function execution. +/// * `deploy_success` - Whether deployments blocks are expected to succeed. +/// * `call_success` - Whether function call blocks are expected to succeed. +/// +/// # Returns +/// +/// A `Vec` with the outcome of each transaction block for snapshot testing. +/// +/// # Panics +/// +/// * If `deploy_epochs` is empty. +/// * If any `call_epoch` is earlier than the minimum `deploy_epoch`. +fn run_contract_consensus_test( + contract_name: &str, + contract_code: &str, + function_name: &str, + function_args: &[ClarityValue], + deploy_epochs: &[StacksEpochId], + call_epochs: &[StacksEpochId], + deploy_success: bool, + call_success: bool, +) -> Vec { + assert!( + !deploy_epochs.is_empty(), + "At least one deploy epoch is required" + ); + let min_deploy_epoch = deploy_epochs.iter().min().unwrap(); + assert!( + call_epochs.iter().all(|e| e >= min_deploy_epoch), + "All call epochs must be >= the minimum deploy epoch" + ); + + let all_epochs: BTreeSet = + deploy_epochs.iter().chain(call_epochs).cloned().collect(); + + let mut contract_names = vec![]; + let sender = &FAUCET_PRIV_KEY; + let contract_addr = to_addr(sender); + let mut tx_factory = TestTxFactory::new(CHAIN_ID_TESTNET); + + // Create epoch blocks by pairing each epoch with its corresponding transactions + let epoch_blocks = all_epochs + .into_iter() + .map(|epoch| { + let mut blocks = vec![]; + if deploy_epochs.contains(&epoch) { + let clarity_versions = clarity_versions_for_epoch(epoch); + let epoch_name = format!("Epoch{}", epoch.to_string().replace(".", "_")); + let mut contract_upload_txs: Vec = clarity_versions + .iter() + .map(|version| { + let name = format!( + "{contract_name}-{epoch_name}-{}", + version.to_string().replace(" ", "") + ); + contract_names.push(name.clone()); + TestBlock { + transactions: vec![tx_factory.contract_deploy( + sender, + &name, + contract_code, + Some(*version), + deploy_success, // increase nonce on deploys expected to succeed + )], + } + }) + .collect(); + blocks.append(&mut contract_upload_txs); + } + if call_epochs.contains(&epoch) { + let mut contract_call_txs: Vec = contract_names + .iter() + .map(|contract_name| TestBlock { + transactions: vec![tx_factory.contract_call( + sender, + &contract_addr, + contract_name, + function_name, + function_args, + call_success, // increase nonce on calls expected to succeed + )], + }) + .collect(); + blocks.append(&mut contract_call_txs); + } + (epoch, blocks) + }) + .collect(); + + let test_vector = ConsensusTestVector { + initial_balances: vec![], + epoch_blocks, + }; + + ConsensusTest::new(function_name!(), test_vector).run() +} + +/// Generates a consensus test for a contract function call across multiple epochs. +/// +/// This macro automates deploying a contract and executing a function across different +/// Stacks epochs and Clarity versions. +/// +/// # Behavior +/// +/// - Deployment: Deploys `contract_code` in each epoch from `deploy_epochs` +/// for every applicable [`ClarityVersion`]. +/// - Execution: Calls `function_name` in each epoch from `call_epochs` on all +/// contracts deployed up to that point. +/// - Structure: Each transaction (deploy or call) is placed in a separate block. +/// +/// # Arguments +/// +/// * `$name`: The test function's name. +/// * `contract_name`, `contract_code`: The contract's name and source. +/// * `function_name`, `function_args`: The function to call and its arguments. +/// * `call_success`: Expected function call success flag. +/// * `deploy_success`: (optional): Expected deployment success flag. Defaults to `true`. +/// * `deploy_epochs` (optional): Epochs to deploy the contract in. Defaults to all epochs >= 3.0. +/// * `call_epochs` (optional): Epochs to call the function in. Defaults to [`EPOCHS_TO_TEST`]. +/// +/// # Example +/// +/// ```rust,ignore +/// contract_call_consensus_test!( +/// my_test, +/// contract_name: "my-contract", +/// contract_code: "(define-public (get-message) (ok \"hello\"))", +/// function_name: "get-message", +/// function_args: &[], +/// ); +/// ``` +macro_rules! contract_call_consensus_test { + ( + $name:ident, + contract_name: $contract_name:expr, + contract_code: $contract_code:expr, + function_name: $function_name:expr, + function_args: $function_args:expr, + call_success: $call_success:expr, + $(deploy_success: $deploy_success:expr,)? + $(deploy_epochs: $deploy_epochs:expr,)? + $(call_epochs: $call_epochs:expr,)? + ) => { + #[tag(consensus)] + #[test] + fn $name() { + let contract_name = $contract_name; + + // Handle deploy_epochs parameter (default to all epochs >= 3.0 if not provided) + let deploy_epochs = StacksEpochId::ALL_GTE_30; + $(let deploy_epochs = $deploy_epochs;)? + + // Handle call_epochs parameter (default to EPOCHS_TO_TEST if not provided) + let call_epochs = EPOCHS_TO_TEST; + $(let call_epochs = $call_epochs;)? + + // Handle deploy_success parameter (default to true if not provided) + let deploy_success = true; + $(let deploy_success = $deploy_success;)? + + let result = run_contract_consensus_test( + contract_name, + $contract_code, + $function_name, + $function_args, + deploy_epochs, + call_epochs, + deploy_success, + $call_success, + ); + + insta::assert_ron_snapshot!(result); + } + }; +} + +/// Generates a consensus test for contract deployment across multiple epochs. +/// +/// This macro automates deploying a contract in different Stacks epochs and +/// Clarity versions, validating deployment success and comparing results. +/// +/// # Arguments +/// +/// * `$name`: The test function's name. +/// * `contract_name`: The contract's name. +/// * `contract_code`: The contract's source code. +/// * `deploy_success`: Expected deployment success flag. +/// * `deploy_epochs` (optional): Epochs to deploy in. Defaults to [`EPOCHS_TO_TEST`]. +/// +/// # Example +/// +/// ```rust,ignore +/// contract_deploy_consensus_test!( +/// deploy_test, +/// contract_name: "my-contract", +/// contract_code: "(define-public (init) (ok true))", +/// deploy_success: true, +/// ); +/// ``` +macro_rules! contract_deploy_consensus_test { + // Handle the case where deploy_epochs is not provided + ( + $name:ident, + contract_name: $contract_name:expr, + contract_code: $contract_code:expr, + deploy_success: $deploy_success:expr, + ) => { + contract_deploy_consensus_test!( + $name, + contract_name: $contract_name, + contract_code: $contract_code, + deploy_success: $deploy_success, + deploy_epochs: EPOCHS_TO_TEST, + ); + }; + ( + $name:ident, + contract_name: $contract_name:expr, + contract_code: $contract_code:expr, + deploy_success: $deploy_success:expr, + deploy_epochs: $deploy_epochs:expr, + ) => { + contract_call_consensus_test!( + $name, + contract_name: $contract_name, + contract_code: $contract_code, + function_name: "", // No function calls, just deploys + function_args: &[], // No function calls, just deploys + call_success: false, // No function calls, so this value is irrelevant + deploy_success: $deploy_success, + deploy_epochs: $deploy_epochs, + call_epochs: &[], // No function calls, just deploys + ); + }; +} + +/// The type of transaction to create. +pub enum TestTxSpec<'a> { + Transfer { + from: &'a StacksPrivateKey, + to: &'a PrincipalData, + amount: u64, + }, + ContractDeploy { + sender: &'a StacksPrivateKey, + name: &'a str, + code: &'a str, + }, + ContractCall { + sender: &'a StacksPrivateKey, + contract_addr: &'a StacksAddress, + contract_name: &'a str, + function_name: &'a str, + args: &'a [ClarityValue], + }, +} + +/// A helper to create transactions with incrementing nonces for each account. +pub struct TestTxFactory { + /// Map of address to next nonce + nonce_counter: HashMap, + /// The default chain ID to use for transactions + default_chain_id: u32, +} + +impl TestTxFactory { + /// Creates a new [`TransactionFactory`] with the specified default chain ID. + pub fn new(default_chain_id: u32) -> Self { + Self { + nonce_counter: HashMap::new(), + default_chain_id, + } + } + + /// Generates a new transaction of the specified type. + /// + /// Arguments: + /// - `tx_type`: The type of transaction to create. + /// + /// Returns: + /// A [`StacksTransaction`] representing the created transaction. + pub fn generate_tx(&mut self, tx_type: &TestTxSpec, increase_nonce: bool) -> StacksTransaction { + match tx_type { + TestTxSpec::Transfer { from, to, amount } => { + self.transfer(from, to, *amount, increase_nonce) + } + TestTxSpec::ContractDeploy { sender, name, code } => { + self.contract_deploy(sender, name, code, None, increase_nonce) + } + TestTxSpec::ContractCall { + sender, + contract_addr, + contract_name, + function_name, + args, + } => self.contract_call( + sender, + contract_addr, + contract_name, + function_name, + args, + increase_nonce, + ), + } + } + + /// Create a STX transfer transaction. + /// + /// Arguments: + /// - `from`: The sender's private key. + /// - `to`: The recipient's principal data. + /// - `amount`: The amount of STX to transfer. + /// + /// Returns: + /// A [`StacksTransaction`] representing the transfer. + /// + /// Note: The transaction fee is set to 180 micro-STX. + pub fn transfer( + &mut self, + from: &StacksPrivateKey, + to: &PrincipalData, + amount: u64, + increase_nonce: bool, + ) -> StacksTransaction { + let address = StacksAddress::p2pkh(false, &StacksPublicKey::from_private(from)); + let nonce = self.nonce_counter.entry(address).or_insert(0); + let tx = make_stacks_transfer_tx(from, *nonce, 180, self.default_chain_id, to, amount); + if increase_nonce { + *nonce += 1; + } + tx + } + + /// Create a contract deployment transaction. + /// + /// Arguments: + /// `sender`: The sender's private key. + /// `name`: The name of the contract. + /// `code`: The contract code as a string. + /// + /// Returns: + /// A [`StacksTransaction`] representing the contract deployment. + /// + /// Note: The transaction fee is set based on the contract code length. + pub fn contract_deploy( + &mut self, + sender: &StacksPrivateKey, + name: &str, + code: &str, + version: Option, + increase_nonce: bool, + ) -> StacksTransaction { + let address = StacksAddress::p2pkh(false, &StacksPublicKey::from_private(sender)); + let nonce = self.nonce_counter.entry(address).or_insert(0); + let tx_bytes = make_contract_publish_versioned( + sender, + *nonce, + (code.len() * 100) as u64, + self.default_chain_id, + name, + code, + version, + ); + if increase_nonce { + *nonce += 1; + } + StacksTransaction::consensus_deserialize(&mut tx_bytes.as_slice()).unwrap() + } + + /// Create a contract call transaction. + /// + /// Arguments: + /// `sender`: The sender's private key. + /// `contract_addr`: The address of the contract. + /// `contract_name`: The name of the contract. + /// `function_name`: The name of the function to call. + /// `args`: The arguments to pass to the function. + /// + /// Returns: + /// A [`StacksTransaction`] representing the contract call. + /// + /// Note: The transaction fee is set to 200 micro-STX. + pub fn contract_call( + &mut self, + sender: &StacksPrivateKey, + contract_addr: &StacksAddress, + contract_name: &str, + function_name: &str, + args: &[ClarityValue], + increase_nonce: bool, + ) -> StacksTransaction { + let address = StacksAddress::p2pkh(false, &StacksPublicKey::from_private(sender)); + let nonce = self.nonce_counter.entry(address).or_insert(0); + let tx_bytes = make_contract_call( + sender, + *nonce, + 200, + self.default_chain_id, + contract_addr, + contract_name, + function_name, + args, + ); + if increase_nonce { + *nonce += 1; + } + StacksTransaction::consensus_deserialize(&mut tx_bytes.as_slice()).unwrap() + } +} + fn epoch_3_0_onwards(first_burnchain_height: u64) -> EpochList { info!("StacksEpoch unit_test first_burn_height = {first_burnchain_height}"); @@ -164,12 +615,51 @@ fn epoch_3_0_onwards(first_burnchain_height: u64) -> EpochList { /// Represents the expected output of a transaction in a test. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct ExpectedTransactionOutput { + /// The transaction that was executed. + /// `None` for bitcoin transactions. + #[serde(serialize_with = "serialize_opt_tx_payload")] + pub tx: Option, /// The expected return value of the transaction. pub return_type: ClarityValue, /// The expected execution cost of the transaction. pub cost: ExecutionCost, } +/// Custom serializer for `Option` to improve snapshot readability. +/// This avoids large diffs in snapshots due to code body changes and focuses on key fields. +fn serialize_opt_tx_payload( + value: &Option, + serializer: S, +) -> Result +where + S: Serializer, +{ + let changed = match value { + None => "BitcoinTx".to_string(), + Some(TransactionPayload::TokenTransfer(sender, amount, memo)) => { + format!("TokenTransfer(from: {sender}, amount: {amount}, memo: {memo})") + } + Some(TransactionPayload::SmartContract( + TransactionSmartContract { name, code_body }, + clarity_version, + )) => { + format!("SmartContract(name: {name}, code_body: [..], clarity_version: {clarity_version:?})") + } + Some(TransactionPayload::ContractCall(TransactionContractCall { + address, + contract_name, + function_name, + function_args, + })) => { + format!("ContractCall(address: {address}, contract_name: {contract_name}, function_name: {function_name}, function_args: [{function_args:?}])") + } + Some(payload) => { + format!("{payload:?}") + } + }; + serializer.serialize_str(&changed) +} + /// Represents the expected outputs for a block's execution. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct ExpectedBlockOutput { @@ -202,9 +692,16 @@ impl ExpectedResult { let transactions: Vec = epoch_receipt .tx_receipts .iter() - .map(|r| ExpectedTransactionOutput { - return_type: r.result.clone(), - cost: r.execution_cost.clone(), + .map(|r| { + let tx = match &r.transaction { + TransactionOrigin::Stacks(tx) => Some(tx.payload.clone()), + TransactionOrigin::Burn(..) => None, + }; + ExpectedTransactionOutput { + tx, + return_type: r.result.clone(), + cost: r.execution_cost.clone(), + } }) .collect(); let total_block_cost = epoch_receipt.anchored_block_cost.clone(); @@ -520,7 +1017,7 @@ fn test_append_empty_blocks() { }]; let mut epoch_blocks = HashMap::new(); for epoch in EPOCHS_TO_TEST { - epoch_blocks.insert(epoch, empty_test_blocks.clone()); + epoch_blocks.insert(*epoch, empty_test_blocks.clone()); } let test_vector = ConsensusTestVector { @@ -572,7 +1069,7 @@ fn test_append_stx_transfers_success() { }) .collect(); - epoch_blocks.insert(epoch, vec![TestBlock { transactions }]); + epoch_blocks.insert(*epoch, vec![TestBlock { transactions }]); } let test_vector = ConsensusTestVector { @@ -584,231 +1081,29 @@ fn test_append_stx_transfers_success() { insta::assert_ron_snapshot!(result); } -#[test] -fn test_append_chainstate_error_expression_stack_depth_too_deep() { - let exceeds_repeat_factor = AST_CALL_STACK_DEPTH_BUFFER + (MAX_CALL_STACK_DEPTH as u64); - let tx_exceeds_body_start = "{ a : ".repeat(exceeds_repeat_factor as usize); - let tx_exceeds_body_end = "} ".repeat(exceeds_repeat_factor as usize); - let tx_exceeds_body = format!("{tx_exceeds_body_start}u1 {tx_exceeds_body_end}"); - - let tx_fee = (tx_exceeds_body.len() * 100) as u64; - let tx_bytes = make_contract_publish( - &FAUCET_PRIV_KEY, - 0, - tx_fee, - CHAIN_ID_TESTNET, - "test-exceeds", - &tx_exceeds_body, - ); - - let tx = StacksTransaction::consensus_deserialize(&mut &tx_bytes[..]).unwrap(); - let test_blocks = vec![TestBlock { - transactions: vec![tx.clone()], - }]; - let mut epoch_blocks = HashMap::new(); - for epoch in EPOCHS_TO_TEST { - epoch_blocks.insert(epoch, test_blocks.clone()); - } - - let test_vector = ConsensusTestVector { - initial_balances: vec![], - epoch_blocks, - }; - let result = ConsensusTest::new(function_name!(), test_vector).run(); - insta::assert_ron_snapshot!(result); -} - -#[test] -fn test_append_block_with_contract_upload_success() { - // build transactions per epoch, incrementing nonce per sender - let mut epoch_blocks = HashMap::new(); +// Example of using the `contract_consensus_test!` macro +// Deploys a contract to each epoch, for each Clarity version, +// then calls a function in that contract and snapshots the results. +contract_call_consensus_test!( + successfully_deploy_and_call, + contract_name: "foo_contract", + contract_code: FOO_CONTRACT, + function_name: "bar", + function_args: &[ClarityValue::UInt(1)], + call_success: true, +); - EPOCHS_TO_TEST - .into_iter() - .enumerate() - .for_each(|(nonce, epoch)| { - // Can't deploy to the same contract location so make sure contract name changes - let contract_name = format!("test-contract-{nonce}"); - let contract_content = "(/ 1 1)"; - let tx_fee = (contract_content.len() * 100) as u64; - - let tx_bytes = make_contract_publish( - &FAUCET_PRIV_KEY, - nonce as u64, - tx_fee, - CHAIN_ID_TESTNET, - &contract_name, - contract_content, - ); - let tx = StacksTransaction::consensus_deserialize(&mut &tx_bytes[..]).unwrap(); - epoch_blocks.insert( - epoch, - vec![TestBlock { - transactions: vec![tx], - }], - ); - }); - - let test_vector = ConsensusTestVector { - initial_balances: vec![], - epoch_blocks, - }; - - let result = ConsensusTest::new(function_name!(), test_vector).run(); - insta::assert_ron_snapshot!(result, @r#" - [ - Success(ExpectedBlockOutput( - marf_hash: "ace4d5c5ffb440418fb30fe1999769ab7fff5a243b775b9961a1dfa77d7a1fab", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "cf7a58c3c15ae61b0861a77a9909e9b05fe35a8d23f974461fd1317693413d3c", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "ad7f9b2130fda2ca8f5c75237755ab7055f69f91d937b2d0653d52f515765e6f", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "25eff57753c490824fc0205b4493d7073e378f0d4648810454cc7e06276fe7da", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - )), - ] - "#); -} - -#[test] -fn test_append_block_with_contract_call_success() { - let tx_fee = (FOO_CONTRACT.len() * 100) as u64; - let mut nonce = 0; - // build transactions per epoch, incrementing nonce per sender - let mut epoch_blocks = HashMap::new(); - EPOCHS_TO_TEST.into_iter().for_each(|epoch| { - // we need to change the contract name across deploys since same sender - let contract_name = format!("foo_contract_{nonce}"); - let tx_bytes = make_contract_publish( - &FAUCET_PRIV_KEY, - nonce, - tx_fee, - CHAIN_ID_TESTNET, - &contract_name, - FOO_CONTRACT, - ); - nonce += 1; - let tx_contract_deploy = - StacksTransaction::consensus_deserialize(&mut tx_bytes.as_slice()).unwrap(); - - let tx_bytes = make_contract_call( - &FAUCET_PRIV_KEY, - nonce, - 200, - CHAIN_ID_TESTNET, - &to_addr(&FAUCET_PRIV_KEY), - &contract_name, - "bar", - &[ClarityValue::UInt(1)], - ); - nonce += 1; - let tx_contract_call = - StacksTransaction::consensus_deserialize(&mut tx_bytes.as_slice()).unwrap(); - - epoch_blocks.insert( - epoch, - vec![TestBlock { - transactions: vec![tx_contract_deploy, tx_contract_call], - }], - ); - }); - - let test_vector = ConsensusTestVector { - initial_balances: vec![], - epoch_blocks, - }; - - let result = ConsensusTest::new(function_name!(), test_vector).run(); - insta::assert_ron_snapshot!(result); -} +// Example of using the `contract_deploy_consensus_test!` macro +// Deploys a contract that exceeds the maximum allowed stack depth +// and verifies that deployment fails with the expected error. +contract_deploy_consensus_test!( + chainstate_error_expression_stack_depth_too_deep, + contract_name: "test-exceeds", + contract_code: &{ + let exceeds_repeat_factor = AST_CALL_STACK_DEPTH_BUFFER + (MAX_CALL_STACK_DEPTH as u64); + let tx_exceeds_body_start = "{ a : ".repeat(exceeds_repeat_factor as usize); + let tx_exceeds_body_end = "} ".repeat(exceeds_repeat_factor as usize); + format!("{tx_exceeds_body_start}u1 {tx_exceeds_body_end}") + }, + deploy_success: false, +); diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap deleted file mode 100644 index 2c231d7026..0000000000 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap +++ /dev/null @@ -1,158 +0,0 @@ ---- -source: stackslib/src/chainstate/tests/consensus.rs -expression: result ---- -[ - Success(ExpectedBlockOutput( - marf_hash: "2149237f0e2a3407eed8733d38bce3db1f3ee1c14ed903c21f59546773174f4f", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "4742e535aebef843720867558b9e2be6148e95157f1fc259e24d162b6c5b78b0", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "75b37d37b1f171eb01fa71a1629e5cab10f2c5cb852b2532b0d4bd311bc94960", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "eabaa1042075ab7afd7721584a590ee8f8542ad4743adc41ed3b1dbe9078a5b4", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 11968, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: UInt(1), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 103, - read_count: 3, - runtime: 499, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), -] diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_chainstate_error_expression_stack_depth_too_deep.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_chainstate_error_expression_stack_depth_too_deep.snap deleted file mode 100644 index 6089465bfa..0000000000 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_chainstate_error_expression_stack_depth_too_deep.snap +++ /dev/null @@ -1,10 +0,0 @@ ---- -source: stackslib/src/chainstate/tests/consensus.rs -expression: result ---- -[ - Failure("Invalid Stacks block a60c62267d58f1ea29c64b2f86d62cf210ff5ab14796abfa947ca6d95007d440: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), - Failure("Invalid Stacks block 238f2ce280580228f19c8122a9bdd0c61299efabe59d8c22c315ee40a865cc7b: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), - Failure("Invalid Stacks block b5dd8cdc0f48b30d355a950077f7c9b20bf01062e9c96262c28f17fff55a2b0f: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), - Failure("Invalid Stacks block cfbddc874c465753158a065eff61340e933d33671633843dde0fbd2bfaaac7a4: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), -] diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_empty_blocks.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_empty_blocks.snap index ea2c09ad3e..dc230e5b03 100644 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_empty_blocks.snap +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_empty_blocks.snap @@ -5,6 +5,4 @@ expression: result [ Failure("Invalid Nakamoto block: failed static transaction checks"), Failure("Invalid Nakamoto block: failed static transaction checks"), - Failure("Invalid Nakamoto block: failed static transaction checks"), - Failure("Invalid Nakamoto block: failed static transaction checks"), ] diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_stx_transfers_success.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_stx_transfers_success.snap index ef8280179a..78c4dd6433 100644 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_stx_transfers_success.snap +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_stx_transfers_success.snap @@ -4,9 +4,10 @@ expression: result --- [ Success(ExpectedBlockOutput( - marf_hash: "cc77d584dea4a29e4d15efffc3306a0e6513d5b516903121c3c149cd85600d5d", + marf_hash: "95999ab12ae2162f2dd25c4a7f7807017b3b5d20f28a53248e37c9864f923718", transactions: [ ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -20,6 +21,7 @@ expression: result ), ), ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -33,6 +35,7 @@ expression: result ), ), ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -55,111 +58,10 @@ expression: result ), )), Success(ExpectedBlockOutput( - marf_hash: "8e80ece06d148b967241484040d26041c817ad9d8753a5d8d2afd284d0e172bc", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "aeb567f75a6a551252cedbbd882060d46dda38f0d949431b503fd435664338da", - transactions: [ - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ExpectedTransactionOutput( - return_type: Response(ResponseData( - committed: true, - data: Bool(true), - )), - cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - ), - ], - total_block_cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "39a1ec92bc388262902593e82da7af6e0cc12412bd566974cebb7f7e9f4e67ce", + marf_hash: "95a3a9e47d70f9dcfeac45e88f84067c0bdfce2e6fdd570b8a7b4faf0a829683", transactions: [ ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -173,6 +75,7 @@ expression: result ), ), ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -186,6 +89,7 @@ expression: result ), ), ExpectedTransactionOutput( + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", return_type: Response(ResponseData( committed: true, data: Bool(true), diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep__t__consensus__t.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep__t__consensus__t.snap new file mode 100644 index 0000000000..a65b0e12bd --- /dev/null +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep__t__consensus__t.snap @@ -0,0 +1,13 @@ +--- +source: stackslib/src/chainstate/tests/consensus.rs +expression: result +--- +[ + Failure("Invalid Stacks block 7e31cbb71c79284d65fcf9ed65e7263e6320f267f8b29eb31aca3a8fcb65302b: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block 1204d27abf8c5274ca561a1f9d14c7d64c3f802ff2b78a164d7d29eb8808d547: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block 435d0c567d8f970c7fde521b4b22e270e78ffbb8c8b09e33bbc6d5b4e7d0257f: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block 7e590f67b60ca3f911c05d60857baaeb4bb55aa15d2cf48033c2116ee99b4b21: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block 6b2d7ce1abaf86eb40ae02f4ba2e091821de1b7451bf4125396d2b7972d27f54: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block c22bfe8a5cd9b5c9f91b03f84144e7f7931364f6a6ab3f10384f6ffea2893602: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), + Failure("Invalid Stacks block e106834a8fbc9258c4776c9b647ed2ba3c536616a3f3d9f47586c5e61391caeb: ClarityError(Parse(ParseError { err: ExpressionStackDepthTooDeep, pre_expressions: None, diagnostic: Diagnostic { level: Error, message: \"AST has too deep of an expression nesting. The maximum stack depth is 64\", spans: [], suggestion: None } }))"), +] diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__successfully_deploy_and_call__t__consensus__t.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__successfully_deploy_and_call__t__consensus__t.snap new file mode 100644 index 0000000000..0741b80b67 --- /dev/null +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__successfully_deploy_and_call__t__consensus__t.snap @@ -0,0 +1,916 @@ +--- +source: stackslib/src/chainstate/tests/consensus.rs +expression: result +--- +[ + Success(ExpectedBlockOutput( + marf_hash: "7dc0aaa26bad4b0300a451df39c8ce76beff0b49da2db3fce47d63b87509c32e", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_0-Clarity1, code_body: [..], clarity_version: Some(Clarity1))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "4e611b18dc48b4ad2825a92431834e3bab0c69393e99a0fd6e5c18c4023a7705", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_0-Clarity2, code_body: [..], clarity_version: Some(Clarity2))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "46da815cdf0c9816d304feb9771763a4ff424b8362e559bbe0981305e6efd889", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_0-Clarity3, code_body: [..], clarity_version: Some(Clarity3))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "5fa759b7495ff89f5274d907b105f9afdfaa7f78942952b60a53b2c921e19607", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_1-Clarity1, code_body: [..], clarity_version: Some(Clarity1))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "159b15f8004355f25117d9a35d11a55f38c80c7886b9cba5ed63a454fc9a0112", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_1-Clarity2, code_body: [..], clarity_version: Some(Clarity2))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "ed275e6d1c8a6cf8afa1c0836aa00fb02e63b3a3cd263137ed4627e8fa23d50c", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_1-Clarity3, code_body: [..], clarity_version: Some(Clarity3))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "68b0d2bb6af72ff3d906da9fb1647f82b689fb7eefb88bff0c3d7324811bc7ff", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_2-Clarity1, code_body: [..], clarity_version: Some(Clarity1))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "2df07ee1b39c63c331bd882265dd335326f179cb46ac59229238f70a55af7926", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_2-Clarity2, code_body: [..], clarity_version: Some(Clarity2))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "8b4b06c870fd5b66e33fe4f1496509cc182827c2e175851d31b85ef00e161625", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_2-Clarity3, code_body: [..], clarity_version: Some(Clarity3))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "ed3ac24606bfab532195a58a924461dadda0c0e5e52c58d50004293f10a9ffa8", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "af5b3fcf2446019e5179753ca3d5a9c87bfd4992db44f23ff265d713051684fc", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "ab1b2f5cc50cbc4a44efacfa273bebc6a8613324e8c41fd092cd99813f7a5641", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "38b0d2fe231731c95ab452ed2e048abfafaf163416a6304af8845d5963fb4347", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "34f0b0577b92091983d86b293c3c78ce83a129fa94bc125bec5c8ebf08f91308", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "a9cf5345902cba7d1529cc72f23a1ceed8d0addcbc2d608163513233fcf76f1d", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "c290afd1e6546e3efa21a1403dd0cd2845a9b5dffd288c907ef2ff40b5328e5f", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "d616f061a5fb3377b12d60a6af69d280bfc3df72f5d00bf4dff0063003a39500", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "677f80720b7d3ab147d595942e54ab6d1c16bf91628ca1d9b9fbf18a4456ca3f", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "b0707705e6a4c790790a58f33781de8102b3b830bf7613bd2fd0771189a23329", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity1, code_body: [..], clarity_version: Some(Clarity1))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "c02832ff84481e3b7d6a9e44a82b72c947e5b7f4ae1425d9c6e29a0cc2ffaec2", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity2, code_body: [..], clarity_version: Some(Clarity2))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "144d1aee7e07b3cea6732f37745664a024f69fd1cb74d680bb562937377b895d", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity3, code_body: [..], clarity_version: Some(Clarity3))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "1e756d1ec2dd74a154cd6483bac84a536296e1c2dee2e83d3a10d8ec6292a38a", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity4, code_body: [..], clarity_version: Some(Clarity4))", + return_type: Response(ResponseData( + committed: true, + data: Bool(true), + )), + cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 121, + write_count: 2, + read_length: 1, + read_count: 1, + runtime: 11968, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "1a751e3e570a813befe3a95ee4ccff5fa1471d837fe2c8421321682e59921758", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "a37b89caef81e7455f89e676aa369f56df2995393135fe91b13cc69d1e36a052", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "d8451e1bfd0760ef7eb56b122658f1354bc1768d2f8e148e422222c1af65d6e0", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "355e9e4f69a831bf12f77e40691e84ccb0569ffd53ddd73e4dc3b643d1443f89", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "9f35d6a18d26488f34bb4634e6c56394c5ae284238c32f1a39ba8bf987c61870", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "2b0efb70c1e2e940ee46030933a77b937dc2b05ba8b20da4ab7a3407db94e112", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "c6174bdd30d2447fa9ee46d847f32a83aa205fd9d1b10266254f9a6bda5fc4a8", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "413a27b671d880499abc3904e1a676547a6134a003771d46edd76c2730025ce6", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "14c4207c11c61c532a9496dc3fdea0b86dbef06dd79498e3991e4e08f72b5724", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "6b4bd51b701c4d7ce33750827af57a2d64962b350286f96d63d68f8c7d914af4", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "a04290f7f34bc910f9b8d0452c247d545001e710368ec4ccd099e74410e6e52f", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "b540c4c0855a87084b71b6a2f1fb8b3ecbf171b0ec42b432d54bd0bdf3bac9cb", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), + Success(ExpectedBlockOutput( + marf_hash: "1332e7be69e17dac916335f58330dffa343e69b1c98d5c2066ec8c26a88e3e7a", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity4, function_name: bar, function_args: [[UInt(1)]])", + return_type: Response(ResponseData( + committed: true, + data: UInt(1), + )), + cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + ), + ], + total_block_cost: ExecutionCost( + write_length: 0, + write_count: 0, + read_length: 103, + read_count: 3, + runtime: 499, + ), + )), +]