diff --git a/crates/blockifier/bench/blockifier_bench.rs b/crates/blockifier/bench/blockifier_bench.rs index 4400a00a22..39099eca6b 100644 --- a/crates/blockifier/bench/blockifier_bench.rs +++ b/crates/blockifier/bench/blockifier_bench.rs @@ -8,16 +8,19 @@ //! Run the benchmarks using `cargo bench --bench blockifier_bench`. use blockifier::abi::abi_utils::selector_from_name; -use blockifier::context::BlockContext; +use blockifier::blockifier::config::TransactionExecutorConfig; +use blockifier::blockifier::transaction_executor::TransactionExecutor; +use blockifier::bouncer::BouncerConfig; +use blockifier::context::{BlockContext, ChainInfo}; use blockifier::invoke_tx_args; -use blockifier::state::cached_state::CachedState; use blockifier::test_utils::contracts::FeatureContract; use blockifier::test_utils::dict_state_reader::DictStateReader; use blockifier::test_utils::initial_test_state::test_state; use blockifier::test_utils::invoke::invoke_tx; use blockifier::test_utils::{CairoVersion, NonceManager, BALANCE, MAX_FEE}; use blockifier::transaction::account_transaction::AccountTransaction; -use blockifier::transaction::transactions::ExecutableTransaction; +use blockifier::transaction::constants::TRANSFER_ENTRY_POINT_NAME; +use blockifier::transaction::transaction_execution::Transaction; use criterion::{criterion_group, criterion_main, Criterion}; use rand::{Rng, SeedableRng}; use starknet_api::core::ContractAddress; @@ -26,63 +29,85 @@ use starknet_api::transaction::{Calldata, Fee, TransactionVersion}; use starknet_api::{calldata, stark_felt}; const N_ACCOUNTS: u16 = 10000; +const CHUNK_SIZE: usize = 10; const RANDOMIZATION_SEED: u64 = 0; const CHARGE_FEE: bool = false; -const RUN_VALIDATION: bool = false; const TRANSACTION_VERSION: TransactionVersion = TransactionVersion(StarkFelt::ONE); pub fn transfers_benchmark(c: &mut Criterion) { - let account_contract = FeatureContract::AccountWithLongValidate(CairoVersion::Cairo0); - let block_context = &BlockContext::create_for_account_testing(); - let mut state = - test_state(block_context.chain_info(), BALANCE * 1000, &[(account_contract, N_ACCOUNTS)]); + let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); + let block_context = BlockContext::create_for_account_testing(); + let chain_info = &block_context.chain_info().clone(); + let state = test_state(chain_info, BALANCE * 1000, &[(account_contract, N_ACCOUNTS)]); + // TODO(Avi, 20/05/2024): Enable concurrency. + let executor_config = TransactionExecutorConfig::default(); + let executor = + &mut TransactionExecutor::new(state, block_context, BouncerConfig::max(), executor_config); let accounts = (0..N_ACCOUNTS) .map(|instance_id| account_contract.get_instance_address(instance_id)) .collect::>(); let nonce_manager = &mut NonceManager::default(); - let mut sender_account = 0; + let mut first_sender_index = 0; let mut random_generator = rand::rngs::StdRng::seed_from_u64(RANDOMIZATION_SEED); - let mut recipient_account = random_generator.gen::() % accounts.len(); // Create a benchmark group called "transfers", which iterates over the accounts round-robin // and performs transfers. c.bench_function("transfers", |benchmark| { benchmark.iter(|| { - do_transfer( - sender_account, - recipient_account, + execute_chunk_of_transfers( + first_sender_index, + &mut random_generator, &accounts, nonce_manager, - block_context, - &mut state, + chain_info, + executor, ); - sender_account = (sender_account + 1) % accounts.len(); - recipient_account = random_generator.gen::() % accounts.len(); + first_sender_index = (first_sender_index + CHUNK_SIZE) % accounts.len(); }) }); } -fn do_transfer( - sender_account: usize, - recipient_account: usize, +fn execute_chunk_of_transfers( + first_sender_index: usize, + random_generator: &mut rand::rngs::StdRng, accounts: &[ContractAddress], nonce_manager: &mut NonceManager, - block_context: &BlockContext, - state: &mut CachedState, + chain_info: &ChainInfo, + executor: &mut TransactionExecutor, ) { - let sender_address = accounts[sender_account]; - let recipient_account_address = accounts[recipient_account]; + let mut chunk: Vec = Vec::with_capacity(CHUNK_SIZE); + let mut sender_index = first_sender_index; + for _ in 0..CHUNK_SIZE { + let recipient_index = random_generator.gen::() % accounts.len(); + let account_tx = + generate_transfer(accounts, sender_index, recipient_index, nonce_manager, chain_info); + chunk.push(Transaction::AccountTransaction(account_tx)); + sender_index = (sender_index + 1) % accounts.len(); + } + let results = executor.execute_txs(&chunk, CHARGE_FEE); + assert_eq!(results.len(), CHUNK_SIZE); + for result in results { + assert!(result.is_ok_and(|execution_info| execution_info.revert_error.is_none())); + } + // TODO(Avi, 01/06/2024): Run the same transactions concurrently on a new state and compare the + // state diffs. +} + +fn generate_transfer( + accounts: &[ContractAddress], + sender_index: usize, + recipient_index: usize, + nonce_manager: &mut NonceManager, + chain_info: &ChainInfo, +) -> AccountTransaction { + let sender_address = accounts[sender_index]; + let recipient_account_address = accounts[recipient_index]; let nonce = nonce_manager.next(sender_address); - let entry_point_selector = - selector_from_name(blockifier::transaction::constants::TRANSFER_ENTRY_POINT_NAME); + let entry_point_selector = selector_from_name(TRANSFER_ENTRY_POINT_NAME); let contract_address = match TRANSACTION_VERSION { - TransactionVersion::ONE => { - *block_context.chain_info().fee_token_addresses.eth_fee_token_address.0.key() - } - TransactionVersion::THREE => { - *block_context.chain_info().fee_token_addresses.strk_fee_token_address.0.key() - } + TransactionVersion::ONE => *chain_info.fee_token_addresses.eth_fee_token_address.0.key(), + TransactionVersion::THREE => *chain_info.fee_token_addresses.strk_fee_token_address.0.key(), _ => panic!("Unsupported transaction version: {TRANSACTION_VERSION:?}"), }; @@ -102,10 +127,7 @@ fn do_transfer( version: TRANSACTION_VERSION, nonce, }); - let account_tx = AccountTransaction::Invoke(tx); - let charge_fee = CHARGE_FEE; - let validate = RUN_VALIDATION; - account_tx.execute(state, block_context, charge_fee, validate).unwrap(); + AccountTransaction::Invoke(tx) } criterion_group!(benches, transfers_benchmark);