Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add use_durable_nonce option #27151

Merged
merged 6 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 97 additions & 38 deletions bench-tps/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use {
log::*,
rand::distributions::{Distribution, Uniform},
rayon::prelude::*,
solana_client::{nonce_utils, rpc_request::MAX_MULTIPLE_ACCOUNTS},
solana_metrics::{self, datapoint_info},
solana_sdk::{
account::Account,
clock::{DEFAULT_MS_PER_SLOT, DEFAULT_S_PER_SLOT, MAX_PROCESSING_AGE},
compute_budget::ComputeBudgetInstruction,
hash::Hash,
Expand All @@ -23,7 +25,7 @@ use {
transaction::Transaction,
},
std::{
collections::VecDeque,
collections::{HashSet, VecDeque},
process::exit,
sync::{
atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering},
Expand Down Expand Up @@ -539,16 +541,64 @@ fn transfer_with_compute_unit_price(
Transaction::new(&[from_keypair], message, recent_blockhash)
}

fn get_nonce_blockhash<T: 'static + BenchTpsClient + Send + Sync + ?Sized>(
client: Arc<T>,
nonce_account_pubkey: Pubkey,
) -> Hash {
let nonce_account = client
.get_account(&nonce_account_pubkey)
.unwrap_or_else(|error| panic!("{:?}", error));
let nonce_data = solana_rpc_client_nonce_utils::data_from_account(&nonce_account)
.unwrap_or_else(|error| panic!("{:?}", error));
nonce_data.blockhash()
fn get_nonce_accounts<T: 'static + BenchTpsClient + Send + Sync + ?Sized>(
client: &Arc<T>,
nonce_pubkeys: &[Pubkey],
) -> Vec<Option<Account>> {
// get_multiple_accounts supports maximum MAX_MULTIPLE_ACCOUNTS pubkeys in request
assert!(nonce_pubkeys.len() <= MAX_MULTIPLE_ACCOUNTS);
loop {
joncinque marked this conversation as resolved.
Show resolved Hide resolved
match client.get_multiple_accounts(nonce_pubkeys) {
Ok(nonce_accounts) => {
return nonce_accounts;
}
Err(err) => {
info!("Couldn't get durable nonce account: {:?}", err);
sleep(Duration::from_secs(1));
joncinque marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

fn get_nonce_blockhashes<T: 'static + BenchTpsClient + Send + Sync + ?Sized>(
client: &Arc<T>,
nonce_pubkeys: &[Pubkey],
) -> Vec<Hash> {
let num_accounts = nonce_pubkeys.len();
let mut blockhashes = vec![Hash::default(); num_accounts];
let mut unprocessed = (0..num_accounts).collect::<HashSet<_>>();

let mut request_pubkeys = Vec::<Pubkey>::with_capacity(num_accounts);
let mut request_indexes = Vec::<usize>::with_capacity(num_accounts);

while !unprocessed.is_empty() {
for i in &unprocessed {
request_pubkeys.push(nonce_pubkeys[*i]);
request_indexes.push(*i);
}

let num_unprocessed_before = unprocessed.len();
let accounts: Vec<Option<Account>> = nonce_pubkeys
.chunks(MAX_MULTIPLE_ACCOUNTS)
.flat_map(|pubkeys| get_nonce_accounts(client, pubkeys))
.collect();

for (account, index) in accounts.iter().zip(request_indexes.iter()) {
if let Some(nonce_account) = account {
let nonce_data = nonce_utils::data_from_account(nonce_account).unwrap();
blockhashes[*index] = nonce_data.blockhash();
unprocessed.remove(index);
}
}
let num_unprocessed_after = unprocessed.len();
debug!(
"Received {} durable nonce accounts",
num_unprocessed_before - num_unprocessed_after
);
request_pubkeys.clear();
request_indexes.clear();
}
blockhashes
}

fn generate_nonced_system_txs<T: 'static + BenchTpsClient + Send + Sync + ?Sized>(
Expand All @@ -561,34 +611,43 @@ fn generate_nonced_system_txs<T: 'static + BenchTpsClient + Send + Sync + ?Sized
) -> Vec<TimestampedTransaction> {
let length = source.len();
let mut transactions: Vec<TimestampedTransaction> = Vec::with_capacity(length);
for i in 0..length {
let (from, to, nonce, nonce_blockhash) = if !reclaim {
(
source[i],
dest[i],
source_nonce[i],
get_nonce_blockhash(client.clone(), source_nonce[i].pubkey()),
)
} else {
(
dest[i],
source[i],
dest_nonce[i],
get_nonce_blockhash(client.clone(), dest_nonce[i].pubkey()),
)
};
if !reclaim {
let pubkeys: Vec<Pubkey> = source_nonce
.iter()
.map(|keypair| keypair.pubkey())
.collect();

transactions.push((
system_transaction::nonced_transfer(
from,
&to.pubkey(),
1,
&nonce.pubkey(),
from,
nonce_blockhash,
),
None,
));
let blockhashes: Vec<Hash> = get_nonce_blockhashes(&client, &pubkeys);
for i in 0..length {
transactions.push((
system_transaction::nonced_transfer(
source[i],
&dest[i].pubkey(),
1,
&source_nonce[i].pubkey(),
source[i],
blockhashes[i],
),
None,
));
}
} else {
let pubkeys: Vec<Pubkey> = dest_nonce.iter().map(|keypair| keypair.pubkey()).collect();
let blockhashes: Vec<Hash> = get_nonce_blockhashes(&client, &pubkeys);

for i in 0..length {
transactions.push((
system_transaction::nonced_transfer(
dest[i],
&source[i].pubkey(),
1,
&dest_nonce[i].pubkey(),
dest[i],
blockhashes[i],
),
None,
));
}
}
transactions
}
Expand Down
9 changes: 9 additions & 0 deletions bench-tps/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
.takes_value(false)
.help("Sets random compute-unit-price in range [0..100] to transfer transactions"),
)
.arg(
Arg::with_name("use_durable_nonce")
.long("use-durable-nonce")
.help("Use durable transaction nonce instead of recent blockhash"),
)
}

/// Parses a clap `ArgMatches` structure into a `Config`
Expand Down Expand Up @@ -447,5 +452,9 @@ pub fn extract_args(matches: &ArgMatches) -> Config {
args.use_randomized_compute_unit_price = true;
}

if matches.is_present("use_durable_nonce") {
args.use_durable_nonce = true;
}

args
}
1 change: 1 addition & 0 deletions bench-tps/src/send_batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub fn generate_durable_nonce_accounts<T: 'static + BenchTpsClient + Send + Sync
let (mut nonce_keypairs, _extra) = generate_keypairs(seed_keypair, count as u64);
nonce_keypairs.truncate(count);

info!("Creating {} nonce accounts...", count);
let to_fund: Vec<NonceCreateSigners> = authority_keypairs
.iter()
.zip(nonce_keypairs.iter())
Expand Down