From 10acd4ed16e7867f1e361b2e3e4208d071765beb Mon Sep 17 00:00:00 2001 From: Yair Bakalchuk Date: Tue, 17 Dec 2024 11:08:16 +0200 Subject: [PATCH 1/2] feat(mempool_test_utils): util to generate deploy account txs --- .../src/starknet_api_test_utils.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/mempool_test_utils/src/starknet_api_test_utils.rs b/crates/mempool_test_utils/src/starknet_api_test_utils.rs index df65cf2813..120c6138c3 100644 --- a/crates/mempool_test_utils/src/starknet_api_test_utils.rs +++ b/crates/mempool_test_utils/src/starknet_api_test_utils.rs @@ -188,6 +188,8 @@ type SharedNonceManager = Rc>; /// let undeployed_account = tx_generator.account_with_id(2).account; /// // Generate a transfer to fund the undeployed account. /// let transfer_tx = tx_generator.account_with_id_mut(0).generate_transfer(&undeployed_account); +/// // Generate a deploy account transaction for the undeployed account. +/// let deploy_account_tx = tx_generator.account_with_id_mut(2).generate_deploy_account(); /// ``` // Note: when moving this to starknet api crate, see if blockifier's // [blockifier::transaction::test_utils::FaultyAccountTxCreatorArgs] can be made to use this. @@ -271,6 +273,7 @@ impl MultiAccountTransactionGenerator { pub struct AccountTransactionGenerator { pub account: Contract, nonce_manager: SharedNonceManager, + contract_address_salt: ContractAddressSalt, } impl AccountTransactionGenerator { @@ -351,6 +354,22 @@ impl AccountTransactionGenerator { rpc_invoke_tx(invoke_args) } + pub fn generate_deploy_account(&mut self) -> RpcTransaction { + assert!( + !self.is_deployed(), + "Cannot deploy an already deployed account: the first transaction of every account \ + must be a deploy account transaction." + ); + let nonce = self.next_nonce(); + assert_eq!(nonce, nonce!(0), "The deploy account tx should have nonce 0."); + let deploy_account_args = deploy_account_tx_args!( + class_hash: self.account.class_hash(), + resource_bounds: test_valid_resource_bounds(), + contract_address_salt: ContractAddressSalt(self.contract_address_salt.0) + ); + rpc_deploy_account_tx(deploy_account_args) + } + pub fn sender_address(&self) -> ContractAddress { self.account.sender_address } @@ -379,6 +398,7 @@ impl AccountTransactionGenerator { let mut account_tx_generator = Self { account: Contract::new_for_account(account, &default_deploy_account_tx), nonce_manager, + contract_address_salt, }; if is_deployed { // Bump the account nonce after transaction creation. From 8f67a1011403013f020104d902ec581467647f04 Mon Sep 17 00:00:00 2001 From: Yair Bakalchuk Date: Tue, 17 Dec 2024 14:57:57 +0200 Subject: [PATCH 2/2] test(starknet_integration_tests): fund contract address for deployment --- .../src/starknet_api_test_utils.rs | 7 ++-- .../starknet_integration_tests/src/utils.rs | 6 ++-- .../tests/end_to_end_flow_test.rs | 32 +++++++++++++++++-- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/crates/mempool_test_utils/src/starknet_api_test_utils.rs b/crates/mempool_test_utils/src/starknet_api_test_utils.rs index 120c6138c3..a0df392623 100644 --- a/crates/mempool_test_utils/src/starknet_api_test_utils.rs +++ b/crates/mempool_test_utils/src/starknet_api_test_utils.rs @@ -209,7 +209,7 @@ impl MultiAccountTransactionGenerator { /// Registers a new account with the given contract, assuming it is already deployed. /// Note: the state should reflect that the account is already deployed. - pub fn register_deployed_account(&mut self, account_contract: FeatureContract) { + pub fn register_deployed_account(&mut self, account_contract: FeatureContract) -> AccountId { let new_account_id = self.account_tx_generators.len(); let salt = ContractAddressSalt(new_account_id.into()); let (account_tx_generator, _default_deploy_account_tx) = AccountTransactionGenerator::new( @@ -219,6 +219,7 @@ impl MultiAccountTransactionGenerator { true, ); self.account_tx_generators.push(account_tx_generator); + new_account_id } /// Registers a new undeployed account with the given contract. @@ -226,7 +227,8 @@ impl MultiAccountTransactionGenerator { &mut self, account_contract: FeatureContract, contract_address_salt: ContractAddressSalt, - ) { + ) -> AccountId { + let new_account_id = self.account_tx_generators.len(); let (account_tx_generator, _default_deploy_account_tx) = AccountTransactionGenerator::new( account_contract, self.nonce_manager.clone(), @@ -234,6 +236,7 @@ impl MultiAccountTransactionGenerator { false, ); self.account_tx_generators.push(account_tx_generator); + new_account_id } pub fn account_with_id_mut( diff --git a/crates/starknet_integration_tests/src/utils.rs b/crates/starknet_integration_tests/src/utils.rs index 7fbc508388..cef1113797 100644 --- a/crates/starknet_integration_tests/src/utils.rs +++ b/crates/starknet_integration_tests/src/utils.rs @@ -40,6 +40,9 @@ use starknet_state_sync::config::StateSyncConfig; use starknet_types_core::felt::Felt; use url::Url; +pub const ACCOUNT_ID_0: AccountId = 0; +pub const ACCOUNT_ID_1: AccountId = 1; + pub fn create_chain_info() -> ChainInfo { let mut chain_info = ChainInfo::create_for_testing(); // Note that the chain_id affects hashes of transactions and blocks, therefore affecting the @@ -174,9 +177,6 @@ pub fn create_integration_test_tx_generator() -> MultiAccountTransactionGenerato pub fn create_txs_for_integration_test( tx_generator: &mut MultiAccountTransactionGenerator, ) -> Vec { - const ACCOUNT_ID_0: AccountId = 0; - const ACCOUNT_ID_1: AccountId = 1; - // Create RPC transactions. let account0_invoke_nonce1 = tx_generator.account_with_id_mut(ACCOUNT_ID_0).generate_invoke_with_tip(2); diff --git a/crates/starknet_integration_tests/tests/end_to_end_flow_test.rs b/crates/starknet_integration_tests/tests/end_to_end_flow_test.rs index 099bc01a55..ef19845443 100644 --- a/crates/starknet_integration_tests/tests/end_to_end_flow_test.rs +++ b/crates/starknet_integration_tests/tests/end_to_end_flow_test.rs @@ -1,5 +1,7 @@ use std::collections::HashSet; +use blockifier::test_utils::contracts::FeatureContract; +use blockifier::test_utils::{CairoVersion, RunnableCairo1}; use futures::StreamExt; use mempool_test_utils::starknet_api_test_utils::MultiAccountTransactionGenerator; use papyrus_consensus::types::ValidatorId; @@ -15,6 +17,8 @@ use papyrus_storage::test_utils::CHAIN_ID_FOR_TESTS; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; use starknet_api::block::{BlockHash, BlockNumber}; +use starknet_api::rpc_transaction::RpcTransaction; +use starknet_api::transaction::fields::ContractAddressSalt; use starknet_api::transaction::TransactionHash; use starknet_integration_tests::flow_test_setup::{FlowSequencerSetup, FlowTestSetup}; use starknet_integration_tests::test_identifiers::TestIdentifier; @@ -23,13 +27,15 @@ use starknet_integration_tests::utils::{ create_txs_for_integration_test, run_integration_test_scenario, test_tx_hashes_for_integration_test, + ACCOUNT_ID_0, }; use starknet_sequencer_infra::trace_util::configure_tracing; use starknet_types_core::felt::Felt; use tracing::debug; const INITIAL_HEIGHT: BlockNumber = BlockNumber(0); -const LAST_HEIGHT: BlockNumber = BlockNumber(2); +const LAST_HEIGHT: BlockNumber = BlockNumber(3); +const NEW_ACCOUNT_SALT: ContractAddressSalt = ContractAddressSalt(Felt::THREE); #[fixture] fn tx_generator() -> MultiAccountTransactionGenerator { @@ -65,6 +71,9 @@ async fn end_to_end_flow(mut tx_generator: MultiAccountTransactionGenerator) { Felt::from_hex_unchecked( "0x79b59c5036c9427b5194796ede67bdfffed1f311a77382d715174fcfcc33003", ), + Felt::from_hex_unchecked( + "0x36e1f3e0c71b77474494a5baa0a04a4e406626141eba2b2944e4b568f70ff48", + ), ]; let sequencers = [&mock_running_system.sequencer_0, &mock_running_system.sequencer_1]; @@ -75,10 +84,10 @@ async fn end_to_end_flow(mut tx_generator: MultiAccountTransactionGenerator) { expected_proposer_iter.next().unwrap(); let create_rpc_txs_scenarios = - [create_txs_for_integration_test, create_txs_for_integration_test]; + [create_txs_for_integration_test, create_txs_for_integration_test, fund_new_account]; let test_tx_hashes_scenarios = - [test_tx_hashes_for_integration_test, test_tx_hashes_for_integration_test]; + [test_tx_hashes_for_integration_test, test_tx_hashes_for_integration_test, test_funding]; assert_eq!( n_heights, @@ -227,3 +236,20 @@ async fn listen_to_broadcasted_messages( "Unexpected transactions" ); } + +fn fund_new_account(tx_generator: &mut MultiAccountTransactionGenerator) -> Vec { + let new_account_id = tx_generator.register_undeployed_account( + FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1(RunnableCairo1::Casm)), + NEW_ACCOUNT_SALT, + ); + + let to = tx_generator.account_with_id(new_account_id).account; + + let funding_tx = tx_generator.account_with_id_mut(ACCOUNT_ID_0).generate_transfer(&to); + vec![funding_tx] +} + +fn test_funding(tx_hashes: &[TransactionHash]) -> Vec { + assert_eq!(tx_hashes.len(), 1, "Expected a single transaction"); + tx_hashes.to_vec() +}