Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
perf(execution): support executing tx chunks in the transfers benchma…
Browse files Browse the repository at this point in the history
…rk (#1883)
  • Loading branch information
avi-starkware authored May 8, 2024
1 parent 4f490bb commit 3a6c5f2
Showing 1 changed file with 58 additions and 36 deletions.
94 changes: 58 additions & 36 deletions crates/blockifier/bench/blockifier_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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::<Vec<_>>();
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::<usize>() % 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::<usize>() % 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<DictStateReader>,
chain_info: &ChainInfo,
executor: &mut TransactionExecutor<DictStateReader>,
) {
let sender_address = accounts[sender_account];
let recipient_account_address = accounts[recipient_account];
let mut chunk: Vec<Transaction> = Vec::with_capacity(CHUNK_SIZE);
let mut sender_index = first_sender_index;
for _ in 0..CHUNK_SIZE {
let recipient_index = random_generator.gen::<usize>() % 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:?}"),
};

Expand All @@ -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);
Expand Down

0 comments on commit 3a6c5f2

Please sign in to comment.