randomize tx ordering (#4978)
Summary of Changes: This change adds functionality to randomize tx execution for every entry. It does this by implementing OrderedIterator that iterates tx slice as per the order specified. The order is generated randomly for every entry.
This commit is contained in:
@@ -10,14 +10,18 @@ use rand::{thread_rng, Rng};
|
||||
use rayon::prelude::*;
|
||||
use solana_core::banking_stage::{create_test_recorder, BankingStage};
|
||||
use solana_core::blocktree::{get_tmp_ledger_path, Blocktree};
|
||||
use solana_core::blocktree_processor::process_entries;
|
||||
use solana_core::cluster_info::ClusterInfo;
|
||||
use solana_core::cluster_info::Node;
|
||||
use solana_core::entry::next_hash;
|
||||
use solana_core::entry::Entry;
|
||||
use solana_core::genesis_utils::{create_genesis_block, GenesisBlockInfo};
|
||||
use solana_core::packet::to_packets_chunked;
|
||||
use solana_core::poh_recorder::WorkingBankEntries;
|
||||
use solana_core::service::Service;
|
||||
use solana_core::test_tx::test_tx;
|
||||
use solana_runtime::bank::Bank;
|
||||
use solana_sdk::genesis_block::GenesisBlock;
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::Keypair;
|
||||
@@ -264,3 +268,83 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) {
|
||||
fn bench_banking_stage_multi_programs(bencher: &mut Bencher) {
|
||||
bench_banking(bencher, TransactionType::Programs);
|
||||
}
|
||||
|
||||
fn simulate_process_entries(
|
||||
randomize_txs: bool,
|
||||
mint_keypair: &Keypair,
|
||||
mut tx_vector: Vec<Transaction>,
|
||||
genesis_block: &GenesisBlock,
|
||||
keypairs: &Vec<Keypair>,
|
||||
initial_lamports: u64,
|
||||
num_accounts: usize,
|
||||
) {
|
||||
let bank = Bank::new(genesis_block);
|
||||
|
||||
for i in 0..(num_accounts / 2) {
|
||||
bank.transfer(initial_lamports, mint_keypair, &keypairs[i * 2].pubkey())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
for i in (0..num_accounts).step_by(2) {
|
||||
tx_vector.push(system_transaction::transfer(
|
||||
&keypairs[i],
|
||||
&keypairs[i + 1].pubkey(),
|
||||
initial_lamports,
|
||||
bank.last_blockhash(),
|
||||
));
|
||||
}
|
||||
|
||||
// Transfer lamports to each other
|
||||
let entry = Entry {
|
||||
num_hashes: 1,
|
||||
hash: next_hash(&bank.last_blockhash(), 1, &tx_vector),
|
||||
transactions: tx_vector,
|
||||
};
|
||||
process_entries(&bank, &vec![entry], randomize_txs).unwrap();
|
||||
}
|
||||
|
||||
fn bench_process_entries(randomize_txs: bool, bencher: &mut Bencher) {
|
||||
// entropy multiplier should be big enough to provide sufficient entropy
|
||||
// but small enough to not take too much time while executing the test.
|
||||
let entropy_multiplier: usize = 25;
|
||||
let initial_lamports = 100;
|
||||
|
||||
// number of accounts need to be in multiple of 4 for correct
|
||||
// execution of the test.
|
||||
let num_accounts = entropy_multiplier * 4;
|
||||
let GenesisBlockInfo {
|
||||
genesis_block,
|
||||
mint_keypair,
|
||||
..
|
||||
} = create_genesis_block((num_accounts + 1) as u64 * initial_lamports);
|
||||
|
||||
let mut keypairs: Vec<Keypair> = vec![];
|
||||
let tx_vector: Vec<Transaction> = Vec::with_capacity(num_accounts / 2);
|
||||
|
||||
for _ in 0..num_accounts {
|
||||
let keypair = Keypair::new();
|
||||
keypairs.push(keypair);
|
||||
}
|
||||
|
||||
bencher.iter(|| {
|
||||
simulate_process_entries(
|
||||
randomize_txs,
|
||||
&mint_keypair,
|
||||
tx_vector.clone(),
|
||||
&genesis_block,
|
||||
&keypairs,
|
||||
initial_lamports,
|
||||
num_accounts,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_process_entries_without_order_shuffeling(bencher: &mut Bencher) {
|
||||
bench_process_entries(false, bencher);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_process_entries_with_order_shuffeling(bencher: &mut Bencher) {
|
||||
bench_process_entries(true, bencher);
|
||||
}
|
||||
|
Reference in New Issue
Block a user