diff --git a/clarity/src/vm/version.rs b/clarity/src/vm/version.rs index 41226cfad97..445a957d2d2 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 ffe1477d514..19db0e515c4 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/src/chainstate/tests/consensus.rs b/stackslib/src/chainstate/tests/consensus.rs index c0fc6732bc6..8580e7ffdbf 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,7 +30,7 @@ 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 clarity::vm::{ClarityVersion, Value as ClarityValue, MAX_CALL_STACK_DEPTH}; use serde::{Deserialize, Serialize, Serializer}; use stacks_common::bitvec::BitVec; @@ -38,29 +38,29 @@ 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 +70,479 @@ 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, + ], + } +} + +/// Executes a consensus test for a contract function across multiple Stacks epochs. +/// +/// This helper automates deploying a contract and invoking one of its public functions +/// across different epochs and Clarity versions, ensuring consistent consensus behavior. +/// +/// # Behavior +/// +/// The function performs two main phases: +/// 1. **Deployment:** Deploys `contract_code` in each epoch listed in `deploy_epochs` for all +/// applicable Clarity versions. +/// 2. **Execution:** Calls `function_name` in each epoch listed in `call_epochs` on every +/// previously deployed contract. +/// +/// ## Example +/// If `deploy_epochs` = `[2.0, 3.0]` and `call_epochs` = `[3.1]`, the following sequence occurs: +/// - Deploy contract in epoch 2.0 with Clarity 1. +/// - Deploy contract in epoch 3.0 with Clarity 1, 2, and 3. +/// - Call the function in epoch 3.1 on all four deployed contracts. +/// +/// # Arguments +/// +/// * `contract_name` - Base name for the contract. +/// * `contract_code` - Clarity source code of the contract. +/// * `function_name` - Public function to invoke. +/// * `function_args` - Arguments to pass to the function call. +/// * `deploy_epochs` - Epochs during which the contract should be deployed. +/// * `call_epochs` - Epochs during which the function should be executed. +/// * `deploy_success` - Whether deployment blocks are expected to succeed. +/// * `call_success` - Whether call blocks are expected to succeed. +/// +/// # Returns +/// +/// A `Vec` with the outcome of each block for snapshot testing. +/// +/// # Panics +/// +/// * If `deploy_epochs` is empty. +/// * If any `call_epoch` precedes the earliest `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 executing a contract function across multiple Stacks epochs. +/// +/// This macro automates both contract deployment and function invocation across different +/// epochs and Clarity versions. +/// It simplifies the setup of consensus-critical tests involving versioned smart contracts. +/// +/// # Behavior +/// +/// - **Deployment:** Deploys `contract_code` in each epoch specified in `deploy_epochs` +/// for every applicable [`ClarityVersion`]. +/// - **Execution:** Calls `function_name` in each epoch from `call_epochs` on all previously +/// deployed contract instances. +/// - **Structure:** Each deployment and function call is executed in its own block, ensuring +/// clear separation between transactions. +/// +/// # Arguments +/// +/// * `$name` — Name of the generated test function. +/// * `contract_name` — The name of the contract. +/// * `contract_code` — The Clarity source code for the contract. +/// * `function_name` — The public function to call. +/// * `function_args` — Function arguments, provided as a slice of [`ClarityValue`]. +/// * `call_success` — Whether function call blocks are expected to succeed. +/// * `deploy_success` — *(optional)* Whether deployment blocks are expected to succeed. Defaults to `true`. +/// * `deploy_epochs` — *(optional)* Epochs in which to deploy the contract. Defaults to all epochs ≥ 3.0. +/// * `call_epochs` — *(optional)* Epochs in which to call the function. 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: &[], +/// call_success: true, +/// ); +/// ``` +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,)? + ) => { + #[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 Stacks epochs. +/// +/// This macro automates deploying a contract across different Stacks epochs and +/// Clarity versions, validating deployment success and ensuring consistent results +/// across protocol upgrades. It is primarily used for consensus-critical testing of +/// contract deployment behavior. +/// +/// # Behavior +/// +/// - **Deployment:** Deploys `contract_code` in each epoch specified by `deploy_epochs` +/// for all applicable [`ClarityVersion`]s. +/// - **Structure:** Each deployment is executed in its own block, ensuring clear +/// separation between transactions. +/// +/// # Arguments +/// +/// * `$name` — Name of the generated test function. +/// * `contract_name` — Name of the contract being tested. +/// * `contract_code` — The Clarity source code of the contract. +/// * `deploy_success` — Whether deployment blocks are expected to succeed. +/// * `deploy_epochs` — *(optional)* Epochs in which to deploy the contract. 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}"); @@ -161,6 +634,41 @@ fn epoch_3_0_onwards(first_burnchain_height: u64) -> EpochList { ]) } +/// 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) +} + /// Serialize an optional string field appending a non-consensus breaking info message. fn serialize_opt_string_ncb(value: &Option, serializer: S) -> Result where @@ -177,13 +685,17 @@ where /// 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 possible Clarity VM error message associated to the transaction (non-consensus breaking) + #[serde(serialize_with = "serialize_opt_string_ncb")] + pub vm_error: Option, /// The expected return value of the transaction. pub return_type: ClarityValue, /// The expected execution cost of the transaction. pub cost: ExecutionCost, - /// The possible Clarity VM error message associated to the transaction (non-consensus breaking) - #[serde(serialize_with = "serialize_opt_string_ncb")] - pub vm_error: Option, } /// Represents the expected outputs for a block's execution. @@ -218,10 +730,17 @@ impl ExpectedResult { let transactions: Vec = epoch_receipt .tx_receipts .iter() - .map(|r| ExpectedTransactionOutput { - return_type: r.result.clone(), - cost: r.execution_cost.clone(), - vm_error: r.vm_error.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(), + vm_error: r.vm_error.clone(), + } }) .collect(); let total_block_cost = epoch_receipt.anchored_block_cost.clone(); @@ -537,7 +1056,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 { @@ -589,7 +1108,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 { @@ -601,235 +1120,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(); - - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - total_block_cost: ExecutionCost( - write_length: 13, - write_count: 2, - read_length: 1, - read_count: 1, - runtime: 8114, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "c72ff94259d531c853a2b3a5ae3d8a8d5a87014337451a09cbce09fa6c43e228", - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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, - }; +// Example of using the `contract_call_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, +); - 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 97929146df4..00000000000 --- a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__append_block_with_contract_call_success.snap +++ /dev/null @@ -1,166 +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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - total_block_cost: ExecutionCost( - write_length: 121, - write_count: 2, - read_length: 104, - read_count: 4, - runtime: 12467, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "c2e7ab1e81196330a7c375ee676efd05e1c162b5667ec2d5fd2e072ebebc8fd5", - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - 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, - ), - vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - 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 a3ace14e238..00000000000 --- 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 cdfe1ac0e60b459fc417de8ce0678d360fa9f43df512e90fcefc5108f6e5bc17: 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 ea2c09ad3ee..dc230e5b03f 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 0bc4fed2e49..7544bba771f 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,23 +4,11 @@ expression: result --- [ Success(ExpectedBlockOutput( - marf_hash: "cc77d584dea4a29e4d15efffc3306a0e6513d5b516903121c3c149cd85600d5d", + marf_hash: "95999ab12ae2162f2dd25c4a7f7807017b3b5d20f28a53248e37c9864f923718", 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -32,35 +20,10 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - total_block_cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "8e80ece06d148b967241484040d26041c817ad9d8753a5d8d2afd284d0e172bc", - transactions: [ - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -72,23 +35,10 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -100,7 +50,6 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), ], total_block_cost: ExecutionCost( @@ -112,23 +61,11 @@ expression: result ), )), Success(ExpectedBlockOutput( - marf_hash: "aeb567f75a6a551252cedbbd882060d46dda38f0d949431b503fd435664338da", + marf_hash: "7e9b86e5b0ff545908784c1c674d1354228ce2884395ced13f7c9e4eaa7ecfd0", 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -140,35 +77,10 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ], - total_block_cost: ExecutionCost( - write_length: 0, - write_count: 0, - read_length: 0, - read_count: 0, - runtime: 0, - ), - )), - Success(ExpectedBlockOutput( - marf_hash: "88bbf16581aeb1b8d38b0cff4ca1f852ce264744b1e62eb7c1a88167ce97f87b", - transactions: [ - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -180,23 +92,10 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), 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, - ), + tx: "TokenTransfer(from: ST000000000000000000002AMW42H, amount: 1000, memo: 00000000000000000000000000000000000000000000000000000000000000000000)", vm_error: "None [NON-CONSENSUS BREAKING]", - ), - ExpectedTransactionOutput( return_type: Response(ResponseData( committed: true, data: Bool(true), @@ -208,7 +107,6 @@ expression: result read_count: 0, runtime: 0, ), - vm_error: "None [NON-CONSENSUS BREAKING]", ), ], total_block_cost: ExecutionCost( diff --git a/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep.snap new file mode 100644 index 00000000000..e1f44a75010 --- /dev/null +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__chainstate_error_expression_stack_depth_too_deep.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 76cc5894a268fa256bb03bfd5e378de73db2a9ab1c88b9a0c0dca80c41782137: 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 e9b506ca1ce75c6ee393200d7ab89742e0dd74f64b1b3363fd98411d163251e7: 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 c1dfc3fad9244f636197bd062b88a8aee581a0df0f2632f7f4639ada153e88d6: 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 072ea79f6c9908c904a6c90881324c52ba67f7a27887e932571ac26e2ad03d19: 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.snap b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__successfully_deploy_and_call.snap new file mode 100644 index 00000000000..d905047da1b --- /dev/null +++ b/stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__consensus__successfully_deploy_and_call.snap @@ -0,0 +1,951 @@ +--- +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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "c0d6892c54926e704f2b79f5bfcea311b6ecbfd1709de05d8ed817f54f392e1c", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity1, code_body: [..], clarity_version: Some(Clarity1))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "bc08a038f2c9819baeb15f306063c351b2ad4d2b6297de98e5019c0655ac29d1", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity2, code_body: [..], clarity_version: Some(Clarity2))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "deda548b30bd858b6b42b638258ea0a45919972b339604544090af42f7c4330b", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity3, code_body: [..], clarity_version: Some(Clarity3))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "1f8603c7d580008f986774bc4a624d429d5b45b4a4385c14656a5398bf8a56ed", + transactions: [ + ExpectedTransactionOutput( + tx: "SmartContract(name: foo_contract-Epoch3_3-Clarity4, code_body: [..], clarity_version: Some(Clarity4))", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "59df1ff6ea26ae936061b8565b962dfbd0d9420efedbf9c9aefb43365e4da789", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "fb5d51ffb295367d9dcd567775618bd54b21c56a9503c2678fac49f53d5e23fa", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "505471f1004e5ab38ef24a05b22422b8d66c9313a85c1d9c3470204d7e38f422", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_0-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "5260eec1120a1caeaceb27842cb4e4a235cbb0791fb67682499bb3796d07c31a", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "105587537589f0bdad491c5cbcdfcffea475176a064c01ffd7f61a1eedd15af5", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "861d1186952ddb0e242bfbe997ea9860cc6739880b47a0c268d7211d54942740", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_1-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "235447452a8921fe9bbf8999194cd001e0ded05bfcbf220b5408be28a4b505f8", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "74ea86662425f6fe76a58bb677e85aaab12ca27b2ec9a2e0c69bbb401275a859", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "795d447db68ddb26b9fd4d091f9e0643c48d44cf34b4c584b916ffe4281c5041", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_2-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "228ad67aa6b7422fc7c8dbbc31c3e8e3042fe8c6bbd6d6a7407788b6d6902388", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity1, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "31234b0b5cbda935741846fc6aee0138858ee589a8610587485fe2ac6ccbde3b", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity2, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "5254245eb17bc1de6da56501a52b9a5f5fb8fd19c40eac285778a46eddc864c8", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity3, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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: "9a7ed0c58f9c0611f61c78a71741c7f0256402e5493843e6b1e327a8e7f2157c", + transactions: [ + ExpectedTransactionOutput( + tx: "ContractCall(address: ST1AW6EKPGT61SQ9FNVDS17RKNWT8ZP582VF9HSCP, contract_name: foo_contract-Epoch3_3-Clarity4, function_name: bar, function_args: [[UInt(1)]])", + vm_error: "None [NON-CONSENSUS BREAKING]", + 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, + ), + )), +]