add withdraw durable nonce (#26829)
* add withdraw durable nonce * Use Pubkey instead of Keypair in bench-tps withdraw Before &Keypair was passed although it is not necessary because nonce doesn't sign withdraw account transactions anyways.
This commit is contained in:
parent
c7462b7a52
commit
ddfa64dcd9
|
@ -924,5 +924,6 @@ mod tests {
|
||||||
rent
|
rent
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
withdraw_durable_nonce_accounts(client, &authority_keypairs, &nonce_keypairs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,17 +109,35 @@ pub fn generate_durable_nonce_accounts<T: 'static + BenchTpsClient + Send + Sync
|
||||||
let (mut nonce_keypairs, _extra) = generate_keypairs(seed_keypair, count as u64);
|
let (mut nonce_keypairs, _extra) = generate_keypairs(seed_keypair, count as u64);
|
||||||
nonce_keypairs.truncate(count);
|
nonce_keypairs.truncate(count);
|
||||||
|
|
||||||
let to_fund: Vec<(&Keypair, &Keypair)> = authority_keypairs
|
let to_fund: Vec<NonceCreateSigners> = authority_keypairs
|
||||||
.iter()
|
.iter()
|
||||||
.zip(nonce_keypairs.iter())
|
.zip(nonce_keypairs.iter())
|
||||||
|
.map(|x| NonceCreateSigners(x.0, x.1))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
to_fund.chunks(FUND_CHUNK_LEN).for_each(|chunk| {
|
to_fund.chunks(FUND_CHUNK_LEN).for_each(|chunk| {
|
||||||
NonceContainer::with_capacity(chunk.len()).create_accounts(&client, chunk, nonce_rent);
|
NonceCreateContainer::with_capacity(chunk.len())
|
||||||
|
.create_accounts(&client, chunk, nonce_rent);
|
||||||
});
|
});
|
||||||
nonce_keypairs
|
nonce_keypairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn withdraw_durable_nonce_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
||||||
|
client: Arc<T>,
|
||||||
|
authority_keypairs: &[Keypair],
|
||||||
|
nonce_keypairs: &[Keypair],
|
||||||
|
) {
|
||||||
|
let to_withdraw: Vec<NonceWithdrawSigners> = authority_keypairs
|
||||||
|
.iter()
|
||||||
|
.zip(nonce_keypairs.iter())
|
||||||
|
.map(|x| NonceWithdrawSigners(x.0, x.1.pubkey()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
to_withdraw.chunks(FUND_CHUNK_LEN).for_each(|chunk| {
|
||||||
|
NonceWithdrawContainer::with_capacity(chunk.len()).withdraw_accounts(&client, chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const MAX_SPENDS_PER_TX: u64 = 4;
|
const MAX_SPENDS_PER_TX: u64 = 4;
|
||||||
|
|
||||||
// Size of the chunk of transactions
|
// Size of the chunk of transactions
|
||||||
|
@ -144,6 +162,11 @@ fn verify_funding_transfer<T: BenchTpsClient>(
|
||||||
/// Helper trait to encapsulate common logic for sending transactions batch
|
/// Helper trait to encapsulate common logic for sending transactions batch
|
||||||
///
|
///
|
||||||
trait SendBatchTransactions<'a, T: Sliceable + Send + Sync> {
|
trait SendBatchTransactions<'a, T: Sliceable + Send + Sync> {
|
||||||
|
fn make<V: Send + Sync, F: Fn(&V) -> (T, Transaction) + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
chunk: &[V],
|
||||||
|
create_transaction: F,
|
||||||
|
);
|
||||||
fn send_transactions<C, F>(&mut self, client: &Arc<C>, to_lamports: u64, log_progress: F)
|
fn send_transactions<C, F>(&mut self, client: &Arc<C>, to_lamports: u64, log_progress: F)
|
||||||
where
|
where
|
||||||
C: 'static + BenchTpsClient + Send + Sync,
|
C: 'static + BenchTpsClient + Send + Sync,
|
||||||
|
@ -170,6 +193,18 @@ impl<'a, T: Sliceable + Send + Sync> SendBatchTransactions<'a, T> for Vec<(T, Tr
|
||||||
where
|
where
|
||||||
<T as Sliceable>::Slice: Signers,
|
<T as Sliceable>::Slice: Signers,
|
||||||
{
|
{
|
||||||
|
fn make<V: Send + Sync, F: Fn(&V) -> (T, Transaction) + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
chunk: &[V],
|
||||||
|
create_transaction: F,
|
||||||
|
) {
|
||||||
|
let mut make_txs = Measure::start("make_txs");
|
||||||
|
let txs: Vec<(T, Transaction)> = chunk.par_iter().map(create_transaction).collect();
|
||||||
|
make_txs.stop();
|
||||||
|
debug!("make {} unsigned txs: {}us", txs.len(), make_txs.as_us());
|
||||||
|
self.extend(txs);
|
||||||
|
}
|
||||||
|
|
||||||
fn send_transactions<C, F>(&mut self, client: &Arc<C>, to_lamports: u64, log_progress: F)
|
fn send_transactions<C, F>(&mut self, client: &Arc<C>, to_lamports: u64, log_progress: F)
|
||||||
where
|
where
|
||||||
C: 'static + BenchTpsClient + Send + Sync,
|
C: 'static + BenchTpsClient + Send + Sync,
|
||||||
|
@ -312,7 +347,6 @@ trait FundingTransactions<'a>: SendBatchTransactions<'a, FundingSigners<'a>> {
|
||||||
to_fund: &FundingChunk<'a>,
|
to_fund: &FundingChunk<'a>,
|
||||||
to_lamports: u64,
|
to_lamports: u64,
|
||||||
);
|
);
|
||||||
fn make(&mut self, to_fund: &FundingChunk<'a>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FundingTransactions<'a> for FundingContainer<'a> {
|
impl<'a> FundingTransactions<'a> for FundingContainer<'a> {
|
||||||
|
@ -322,7 +356,11 @@ impl<'a> FundingTransactions<'a> for FundingContainer<'a> {
|
||||||
to_fund: &FundingChunk<'a>,
|
to_fund: &FundingChunk<'a>,
|
||||||
to_lamports: u64,
|
to_lamports: u64,
|
||||||
) {
|
) {
|
||||||
self.make(to_fund);
|
self.make(to_fund, |(k, t)| -> (FundingSigners<'a>, Transaction) {
|
||||||
|
let instructions = system_instruction::transfer_many(&k.pubkey(), t);
|
||||||
|
let message = Message::new(&instructions, Some(&k.pubkey()));
|
||||||
|
(*k, Transaction::new_unsigned(message))
|
||||||
|
});
|
||||||
|
|
||||||
let log_progress = |tries: usize, batch_len: usize| {
|
let log_progress = |tries: usize, batch_len: usize| {
|
||||||
info!(
|
info!(
|
||||||
|
@ -339,28 +377,15 @@ impl<'a> FundingTransactions<'a> for FundingContainer<'a> {
|
||||||
};
|
};
|
||||||
self.send_transactions(client, to_lamports, log_progress);
|
self.send_transactions(client, to_lamports, log_progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make(&mut self, to_fund: &FundingChunk<'a>) {
|
|
||||||
let mut make_txs = Measure::start("make_txs");
|
|
||||||
let to_fund_txs: FundingContainer<'a> = to_fund
|
|
||||||
.par_iter()
|
|
||||||
.map(|(k, t)| {
|
|
||||||
let instructions = system_instruction::transfer_many(&k.pubkey(), t);
|
|
||||||
let message = Message::new(&instructions, Some(&k.pubkey()));
|
|
||||||
(*k, Transaction::new_unsigned(message))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
make_txs.stop();
|
|
||||||
debug!(
|
|
||||||
"make {} unsigned txs: {}us",
|
|
||||||
to_fund_txs.len(),
|
|
||||||
make_txs.as_us()
|
|
||||||
);
|
|
||||||
self.extend(to_fund_txs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Sliceable for (&'a Keypair, &'a Keypair) {
|
// Introduce a new structure to specify Sliceable implementations
|
||||||
|
// which uses both Keypairs to sign the transaction
|
||||||
|
struct NonceCreateSigners<'a>(&'a Keypair, &'a Keypair);
|
||||||
|
type NonceCreateChunk<'a> = [NonceCreateSigners<'a>];
|
||||||
|
type NonceCreateContainer<'a> = Vec<(NonceCreateSigners<'a>, Transaction)>;
|
||||||
|
|
||||||
|
impl<'a> Sliceable for NonceCreateSigners<'a> {
|
||||||
type Slice = [&'a Keypair; 2];
|
type Slice = [&'a Keypair; 2];
|
||||||
fn as_slice(&self) -> Self::Slice {
|
fn as_slice(&self) -> Self::Slice {
|
||||||
[self.0, self.1]
|
[self.0, self.1]
|
||||||
|
@ -370,28 +395,36 @@ impl<'a> Sliceable for (&'a Keypair, &'a Keypair) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type NonceSigners<'a> = (&'a Keypair, &'a Keypair);
|
trait NonceTransactions<'a>: SendBatchTransactions<'a, NonceCreateSigners<'a>> {
|
||||||
type NonceChunk<'a> = [NonceSigners<'a>];
|
|
||||||
type NonceContainer<'a> = Vec<(NonceSigners<'a>, Transaction)>;
|
|
||||||
|
|
||||||
trait CreateNonceTransactions<'a>: SendBatchTransactions<'a, (&'a Keypair, &'a Keypair)> {
|
|
||||||
fn create_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
fn create_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
client: &Arc<T>,
|
client: &Arc<T>,
|
||||||
to_fund: &'a NonceChunk<'a>,
|
to_fund: &'a NonceCreateChunk<'a>,
|
||||||
nonce_rent: u64,
|
nonce_rent: u64,
|
||||||
);
|
);
|
||||||
fn make(&mut self, nonce_rent: u64, to_fund: &'a NonceChunk<'a>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CreateNonceTransactions<'a> for NonceContainer<'a> {
|
impl<'a> NonceTransactions<'a> for NonceCreateContainer<'a> {
|
||||||
fn create_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
fn create_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
||||||
&mut self,
|
&mut self,
|
||||||
client: &Arc<T>,
|
client: &Arc<T>,
|
||||||
to_fund: &'a NonceChunk<'a>,
|
to_fund: &'a NonceCreateChunk<'a>,
|
||||||
nonce_rent: u64,
|
nonce_rent: u64,
|
||||||
) {
|
) {
|
||||||
self.make(nonce_rent, to_fund);
|
self.make(to_fund, |kp| -> (NonceCreateSigners<'a>, Transaction) {
|
||||||
|
let authority = kp.0;
|
||||||
|
let nonce: &Keypair = kp.1;
|
||||||
|
let instructions = system_instruction::create_nonce_account(
|
||||||
|
&authority.pubkey(),
|
||||||
|
&nonce.pubkey(),
|
||||||
|
&authority.pubkey(),
|
||||||
|
nonce_rent,
|
||||||
|
);
|
||||||
|
(
|
||||||
|
NonceCreateSigners(authority, nonce),
|
||||||
|
Transaction::new_with_payer(&instructions, Some(&authority.pubkey())),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let log_progress = |tries: usize, batch_len: usize| {
|
let log_progress = |tries: usize, batch_len: usize| {
|
||||||
info!(
|
info!(
|
||||||
|
@ -402,30 +435,69 @@ impl<'a> CreateNonceTransactions<'a> for NonceContainer<'a> {
|
||||||
};
|
};
|
||||||
self.send_transactions(client, nonce_rent, log_progress);
|
self.send_transactions(client, nonce_rent, log_progress);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn make(&mut self, nonce_rent: u64, to_fund: &'a NonceChunk<'a>) {
|
// Only Pubkey is required for nonce because it doesn't sign withdraw account transaction
|
||||||
let mut make_txs = Measure::start("make_txs");
|
struct NonceWithdrawSigners<'a>(&'a Keypair, Pubkey);
|
||||||
let to_fund_txs: NonceContainer = to_fund
|
type NonceWithdrawChunk<'a> = [NonceWithdrawSigners<'a>];
|
||||||
.par_iter()
|
type NonceWithdrawContainer<'a> = Vec<(NonceWithdrawSigners<'a>, Transaction)>;
|
||||||
.map(|(authority, nonce)| {
|
|
||||||
let instructions = system_instruction::create_nonce_account(
|
impl<'a> Sliceable for NonceWithdrawSigners<'a> {
|
||||||
&authority.pubkey(),
|
type Slice = [&'a Keypair; 1];
|
||||||
&nonce.pubkey(),
|
fn as_slice(&self) -> Self::Slice {
|
||||||
&authority.pubkey(),
|
[self.0]
|
||||||
nonce_rent,
|
}
|
||||||
);
|
fn get_pubkey(&self) -> Pubkey {
|
||||||
(
|
self.0.pubkey()
|
||||||
(*authority, *nonce),
|
}
|
||||||
Transaction::new_with_payer(&instructions, Some(&authority.pubkey())),
|
}
|
||||||
)
|
|
||||||
})
|
trait NonceWithdrawTransactions<'a>: SendBatchTransactions<'a, NonceWithdrawSigners<'a>> {
|
||||||
.collect();
|
fn withdraw_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
||||||
make_txs.stop();
|
&mut self,
|
||||||
debug!(
|
client: &Arc<T>,
|
||||||
"make {} unsigned txs: {}us",
|
to_withdraw: &'a NonceWithdrawChunk<'a>,
|
||||||
to_fund_txs.len(),
|
);
|
||||||
make_txs.as_us()
|
}
|
||||||
);
|
impl<'a> NonceWithdrawTransactions<'a> for NonceWithdrawContainer<'a> {
|
||||||
self.extend(to_fund_txs);
|
fn withdraw_accounts<T: 'static + BenchTpsClient + Send + Sync>(
|
||||||
|
&mut self,
|
||||||
|
client: &Arc<T>,
|
||||||
|
to_withdraw: &'a NonceWithdrawChunk<'a>,
|
||||||
|
) {
|
||||||
|
self.make(
|
||||||
|
to_withdraw,
|
||||||
|
|kp| -> (NonceWithdrawSigners<'a>, Transaction) {
|
||||||
|
let authority = kp.0;
|
||||||
|
let nonce_pubkey: Pubkey = kp.1;
|
||||||
|
let nonce_balance = client.get_balance(&nonce_pubkey).unwrap();
|
||||||
|
let instructions = vec![
|
||||||
|
system_instruction::withdraw_nonce_account(
|
||||||
|
&nonce_pubkey,
|
||||||
|
&authority.pubkey(),
|
||||||
|
&authority.pubkey(),
|
||||||
|
nonce_balance,
|
||||||
|
);
|
||||||
|
1
|
||||||
|
];
|
||||||
|
(
|
||||||
|
NonceWithdrawSigners(authority, nonce_pubkey),
|
||||||
|
Transaction::new_with_payer(&instructions, Some(&authority.pubkey())),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let log_progress = |tries: usize, batch_len: usize| {
|
||||||
|
info!(
|
||||||
|
"@ {} {} accounts",
|
||||||
|
if tries == 0 {
|
||||||
|
"withdrawing"
|
||||||
|
} else {
|
||||||
|
" retrying"
|
||||||
|
},
|
||||||
|
batch_len,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
self.send_transactions(client, 0, log_progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue