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

Commit

Permalink
refactor: refactor the benchmark logic into a struct to be reusable (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
avi-starkware authored Jun 5, 2024
1 parent 28745a3 commit cfb9c07
Showing 1 changed file with 92 additions and 79 deletions.
171 changes: 92 additions & 79 deletions crates/blockifier/bench/blockifier_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,99 +35,112 @@ const CHARGE_FEE: bool = false;
const TRANSACTION_VERSION: TransactionVersion = TransactionVersion(StarkFelt::ONE);

pub fn transfers_benchmark(c: &mut Criterion) {
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 first_sender_index = 0;
let mut random_generator = rand::rngs::StdRng::seed_from_u64(RANDOMIZATION_SEED);
let mut transfers_simulator = TransfersGenerator::new();
// Create a benchmark group called "transfers", which iterates over the accounts round-robin
// and performs transfers.
c.bench_function("transfers", |benchmark| {
benchmark.iter(|| {
execute_chunk_of_transfers(
first_sender_index,
&mut random_generator,
&accounts,
nonce_manager,
chain_info,
executor,
);
first_sender_index = (first_sender_index + CHUNK_SIZE) % accounts.len();
transfers_simulator.execute_chunk_of_transfers();
})
});
}
pub struct TransfersGenerator {
account_addresses: Vec<ContractAddress>,
chain_info: ChainInfo,
executor: TransactionExecutor<DictStateReader>,
nonce_manager: NonceManager,
recipient_generator: rand::rngs::StdRng,
sender_index: usize,
}

fn execute_chunk_of_transfers(
first_sender_index: usize,
random_generator: &mut rand::rngs::StdRng,
accounts: &[ContractAddress],
nonce_manager: &mut NonceManager,
chain_info: &ChainInfo,
executor: &mut TransactionExecutor<DictStateReader>,
) {
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();
impl TransfersGenerator {
pub fn new() -> Self {
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 =
TransactionExecutor::new(state, block_context, BouncerConfig::max(), executor_config);
let account_addresses = (0..N_ACCOUNTS)
.map(|instance_id| account_contract.get_instance_address(instance_id))
.collect::<Vec<_>>();
let nonce_manager = NonceManager::default();
let random_generator = rand::rngs::StdRng::seed_from_u64(RANDOMIZATION_SEED);
Self {
account_addresses,
nonce_manager,
chain_info,
executor,
sender_index: 0,
recipient_generator: random_generator,
}
}
let results = executor.execute_txs(&chunk, CHARGE_FEE);
assert_eq!(results.len(), CHUNK_SIZE);
for result in results {
assert!(!result.unwrap().is_reverted());

pub fn execute_chunk_of_transfers(&mut self) {
let mut chunk: Vec<Transaction> = Vec::with_capacity(CHUNK_SIZE);
for _ in 0..CHUNK_SIZE {
let sender_address = self.account_addresses[self.sender_index];
self.sender_index = (self.sender_index + 1) % self.account_addresses.len();
let recipient_index =
self.recipient_generator.gen::<usize>() % self.account_addresses.len();
let recipient_address = self.account_addresses[recipient_index];

let account_tx = self.generate_transfer(sender_address, recipient_address);
chunk.push(Transaction::AccountTransaction(account_tx));
}
let results = self.executor.execute_txs(&chunk, CHARGE_FEE);
assert_eq!(results.len(), CHUNK_SIZE);
for result in results {
assert!(!result.unwrap().is_reverted());
}
// TODO(Avi, 01/06/2024): Run the same transactions concurrently on a new state and compare
// the state diffs.
}
// 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);
pub fn generate_transfer(
&mut self,
sender_address: ContractAddress,
recipient_address: ContractAddress,
) -> AccountTransaction {
let nonce = self.nonce_manager.next(sender_address);

let entry_point_selector = selector_from_name(TRANSFER_ENTRY_POINT_NAME);
let contract_address = match TRANSACTION_VERSION {
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:?}"),
};
let entry_point_selector = selector_from_name(TRANSFER_ENTRY_POINT_NAME);
let contract_address = match TRANSACTION_VERSION {
TransactionVersion::ONE => {
*self.chain_info.fee_token_addresses.eth_fee_token_address.0.key()
}
TransactionVersion::THREE => {
*self.chain_info.fee_token_addresses.strk_fee_token_address.0.key()
}
_ => panic!("Unsupported transaction version: {TRANSACTION_VERSION:?}"),
};

let execute_calldata = calldata![
contract_address, // Contract address.
entry_point_selector.0, // EP selector.
stark_felt!(3_u8), // Calldata length.
*recipient_account_address.0.key(), // Calldata: recipient.
stark_felt!(1_u8), // Calldata: lsb amount.
stark_felt!(0_u8) // Calldata: msb amount.
];
let execute_calldata = calldata![
contract_address, // Contract address.
entry_point_selector.0, // EP selector.
stark_felt!(3_u8), // Calldata length.
*recipient_address.0.key(), // Calldata: recipient.
stark_felt!(1_u8), // Calldata: lsb amount.
stark_felt!(0_u8) // Calldata: msb amount.
];

let tx = invoke_tx(invoke_tx_args! {
max_fee: Fee(MAX_FEE),
sender_address,
calldata: execute_calldata,
version: TRANSACTION_VERSION,
nonce,
});
AccountTransaction::Invoke(tx)
let tx = invoke_tx(invoke_tx_args! {
max_fee: Fee(MAX_FEE),
sender_address,
calldata: execute_calldata,
version: TRANSACTION_VERSION,
nonce,
});
AccountTransaction::Invoke(tx)
}
}

impl Default for TransfersGenerator {
fn default() -> Self {
Self::new()
}
}

criterion_group!(benches, transfers_benchmark);
Expand Down

0 comments on commit cfb9c07

Please sign in to comment.