소스 검색

Add handling to close accounts to many-accounts bench (#16199)

* gitignore farf

* Improve cli args

* Use derived addresses for accounts

* Add parameter to close every nth account created
Tyera Eulberg 4 년 전
부모
커밋
1d145e1fc2
2개의 변경된 파일145개의 추가작업 그리고 37개의 파일을 삭제
  1. 1 0
      accounts-cluster-bench/.gitignore
  2. 144 37
      accounts-cluster-bench/src/main.rs

+ 1 - 0
accounts-cluster-bench/.gitignore

@@ -0,0 +1 @@
+/farf/

+ 144 - 37
accounts-cluster-bench/src/main.rs

@@ -21,7 +21,6 @@ use solana_sdk::{
     transaction::Transaction,
     transaction::Transaction,
 };
 };
 use solana_transaction_status::parse_token::spl_token_v2_0_instruction;
 use solana_transaction_status::parse_token::spl_token_v2_0_instruction;
-use spl_token_v2_0::solana_program::pubkey::Pubkey as SplPubkey;
 use std::{
 use std::{
     net::SocketAddr,
     net::SocketAddr,
     process::exit,
     process::exit,
@@ -251,28 +250,38 @@ impl TransactionExecutor {
     }
     }
 }
 }
 
 
-fn make_message(
+struct SeedTracker {
+    max_created: Arc<AtomicU64>,
+    max_closed: Arc<AtomicU64>,
+}
+
+fn make_create_message(
     keypair: &Keypair,
     keypair: &Keypair,
+    base_keypair: &Keypair,
+    max_created_seed: Arc<AtomicU64>,
     num_instructions: usize,
     num_instructions: usize,
     balance: u64,
     balance: u64,
     maybe_space: Option<u64>,
     maybe_space: Option<u64>,
     mint: Option<Pubkey>,
     mint: Option<Pubkey>,
-) -> (Message, Vec<Keypair>) {
+) -> Message {
     let space = maybe_space.unwrap_or_else(|| thread_rng().gen_range(0, 1000));
     let space = maybe_space.unwrap_or_else(|| thread_rng().gen_range(0, 1000));
 
 
-    let (instructions, new_keypairs): (Vec<_>, Vec<_>) = (0..num_instructions)
+    let instructions: Vec<_> = (0..num_instructions)
         .into_iter()
         .into_iter()
         .map(|_| {
         .map(|_| {
-            let new_keypair = Keypair::new();
-
             let program_id = if mint.is_some() {
             let program_id = if mint.is_some() {
                 inline_spl_token_v2_0::id()
                 inline_spl_token_v2_0::id()
             } else {
             } else {
                 system_program::id()
                 system_program::id()
             };
             };
-            let mut instructions = vec![system_instruction::create_account(
+            let seed = max_created_seed.fetch_add(1, Ordering::Relaxed).to_string();
+            let to_pubkey =
+                Pubkey::create_with_seed(&base_keypair.pubkey(), &seed, &program_id).unwrap();
+            let mut instructions = vec![system_instruction::create_account_with_seed(
                 &keypair.pubkey(),
                 &keypair.pubkey(),
-                &new_keypair.pubkey(),
+                &to_pubkey,
+                &base_keypair.pubkey(),
+                &seed,
                 balance,
                 balance,
                 space,
                 space,
                 &program_id,
                 &program_id,
@@ -281,25 +290,69 @@ fn make_message(
                 instructions.push(spl_token_v2_0_instruction(
                 instructions.push(spl_token_v2_0_instruction(
                     spl_token_v2_0::instruction::initialize_account(
                     spl_token_v2_0::instruction::initialize_account(
                         &spl_token_v2_0::id(),
                         &spl_token_v2_0::id(),
-                        &spl_token_v2_0_pubkey(&new_keypair.pubkey()),
+                        &spl_token_v2_0_pubkey(&to_pubkey),
                         &spl_token_v2_0_pubkey(&mint_address),
                         &spl_token_v2_0_pubkey(&mint_address),
-                        &SplPubkey::new_unique(),
+                        &spl_token_v2_0_pubkey(&base_keypair.pubkey()),
                     )
                     )
                     .unwrap(),
                     .unwrap(),
                 ));
                 ));
             }
             }
 
 
-            (instructions, new_keypair)
+            instructions
         })
         })
-        .unzip();
+        .collect();
     let instructions: Vec<_> = instructions.into_iter().flatten().collect();
     let instructions: Vec<_> = instructions.into_iter().flatten().collect();
 
 
-    (
-        Message::new(&instructions, Some(&keypair.pubkey())),
-        new_keypairs,
-    )
+    Message::new(&instructions, Some(&keypair.pubkey()))
 }
 }
 
 
+fn make_close_message(
+    keypair: &Keypair,
+    base_keypair: &Keypair,
+    max_closed_seed: Arc<AtomicU64>,
+    num_instructions: usize,
+    balance: u64,
+    spl_token: bool,
+) -> Message {
+    let instructions: Vec<_> = (0..num_instructions)
+        .into_iter()
+        .map(|_| {
+            let program_id = if spl_token {
+                inline_spl_token_v2_0::id()
+            } else {
+                system_program::id()
+            };
+            let seed = max_closed_seed.fetch_add(1, Ordering::Relaxed).to_string();
+            let address =
+                Pubkey::create_with_seed(&base_keypair.pubkey(), &seed, &program_id).unwrap();
+            if spl_token {
+                spl_token_v2_0_instruction(
+                    spl_token_v2_0::instruction::close_account(
+                        &spl_token_v2_0::id(),
+                        &spl_token_v2_0_pubkey(&address),
+                        &spl_token_v2_0_pubkey(&keypair.pubkey()),
+                        &spl_token_v2_0_pubkey(&base_keypair.pubkey()),
+                        &[],
+                    )
+                    .unwrap(),
+                )
+            } else {
+                system_instruction::transfer_with_seed(
+                    &address,
+                    &base_keypair.pubkey(),
+                    seed,
+                    &program_id,
+                    &keypair.pubkey(),
+                    balance,
+                )
+            }
+        })
+        .collect();
+
+    Message::new(&instructions, Some(&keypair.pubkey()))
+}
+
+#[allow(clippy::too_many_arguments)]
 fn run_accounts_bench(
 fn run_accounts_bench(
     entrypoint_addr: SocketAddr,
     entrypoint_addr: SocketAddr,
     faucet_addr: SocketAddr,
     faucet_addr: SocketAddr,
@@ -307,6 +360,7 @@ fn run_accounts_bench(
     iterations: usize,
     iterations: usize,
     maybe_space: Option<u64>,
     maybe_space: Option<u64>,
     batch_size: usize,
     batch_size: usize,
+    close_nth: u64,
     maybe_lamports: Option<u64>,
     maybe_lamports: Option<u64>,
     num_instructions: usize,
     num_instructions: usize,
     mint: Option<Pubkey>,
     mint: Option<Pubkey>,
@@ -322,7 +376,8 @@ fn run_accounts_bench(
     let mut count = 0;
     let mut count = 0;
     let mut recent_blockhash = client.get_recent_blockhash().expect("blockhash");
     let mut recent_blockhash = client.get_recent_blockhash().expect("blockhash");
     let mut tx_sent_count = 0;
     let mut tx_sent_count = 0;
-    let mut total_account_count = 0;
+    let mut total_accounts_created = 0;
+    let mut total_accounts_closed = 0;
     let mut balance = client.get_balance(&keypair.pubkey()).unwrap_or(0);
     let mut balance = client.get_balance(&keypair.pubkey()).unwrap_or(0);
     let mut last_balance = Instant::now();
     let mut last_balance = Instant::now();
 
 
@@ -334,6 +389,12 @@ fn run_accounts_bench(
             .expect("min balance")
             .expect("min balance")
     });
     });
 
 
+    let base_keypair = Keypair::new();
+    let seed_tracker = SeedTracker {
+        max_created: Arc::new(AtomicU64::default()),
+        max_closed: Arc::new(AtomicU64::default()),
+    };
+
     info!("Starting balance: {}", balance);
     info!("Starting balance: {}", balance);
 
 
     let executor = TransactionExecutor::new(entrypoint_addr);
     let executor = TransactionExecutor::new(entrypoint_addr);
@@ -344,8 +405,15 @@ fn run_accounts_bench(
             last_blockhash = Instant::now();
             last_blockhash = Instant::now();
         }
         }
 
 
-        let (message, _keypairs) =
-            make_message(keypair, num_instructions, min_balance, maybe_space, mint);
+        let message = make_create_message(
+            keypair,
+            &base_keypair,
+            seed_tracker.max_created.clone(),
+            num_instructions,
+            min_balance,
+            maybe_space,
+            mint,
+        );
         let fee = recent_blockhash.1.calculate_fee(&message);
         let fee = recent_blockhash.1.calculate_fee(&message);
         let lamports = min_balance + fee;
         let lamports = min_balance + fee;
 
 
@@ -370,27 +438,55 @@ fn run_accounts_bench(
         if sigs_len < batch_size {
         if sigs_len < batch_size {
             let num_to_create = batch_size - sigs_len;
             let num_to_create = batch_size - sigs_len;
             info!("creating {} new", num_to_create);
             info!("creating {} new", num_to_create);
-            let (txs, _new_keypairs): (Vec<_>, Vec<_>) = (0..num_to_create)
+            let txs: Vec<_> = (0..num_to_create)
                 .into_par_iter()
                 .into_par_iter()
                 .map(|_| {
                 .map(|_| {
-                    let (message, new_keypairs) =
-                        make_message(keypair, num_instructions, min_balance, maybe_space, mint);
-                    let signers: Vec<&Keypair> = new_keypairs
-                        .iter()
-                        .chain(std::iter::once(keypair))
-                        .collect();
-                    (
-                        Transaction::new(&signers, message, recent_blockhash.0),
-                        new_keypairs,
-                    )
+                    let message = make_create_message(
+                        keypair,
+                        &base_keypair,
+                        seed_tracker.max_created.clone(),
+                        num_instructions,
+                        min_balance,
+                        maybe_space,
+                        mint,
+                    );
+                    let signers: Vec<&Keypair> = vec![keypair, &base_keypair];
+                    Transaction::new(&signers, message, recent_blockhash.0)
                 })
                 })
-                .unzip();
+                .collect();
             balance = balance.saturating_sub(lamports * txs.len() as u64);
             balance = balance.saturating_sub(lamports * txs.len() as u64);
             info!("txs: {}", txs.len());
             info!("txs: {}", txs.len());
             let new_ids = executor.push_transactions(txs);
             let new_ids = executor.push_transactions(txs);
             info!("ids: {}", new_ids.len());
             info!("ids: {}", new_ids.len());
             tx_sent_count += new_ids.len();
             tx_sent_count += new_ids.len();
-            total_account_count += num_instructions * new_ids.len();
+            total_accounts_created += num_instructions * new_ids.len();
+
+            if close_nth > 0 {
+                let expected_closed = total_accounts_created as u64 / close_nth;
+                if expected_closed > total_accounts_closed {
+                    let txs: Vec<_> = (0..expected_closed - total_accounts_closed)
+                        .into_par_iter()
+                        .map(|_| {
+                            let message = make_close_message(
+                                keypair,
+                                &base_keypair,
+                                seed_tracker.max_closed.clone(),
+                                1,
+                                min_balance,
+                                mint.is_some(),
+                            );
+                            let signers: Vec<&Keypair> = vec![keypair, &base_keypair];
+                            Transaction::new(&signers, message, recent_blockhash.0)
+                        })
+                        .collect();
+                    balance = balance.saturating_sub(fee * txs.len() as u64);
+                    info!("close txs: {}", txs.len());
+                    let new_ids = executor.push_transactions(txs);
+                    info!("close ids: {}", new_ids.len());
+                    tx_sent_count += new_ids.len();
+                    total_accounts_closed += new_ids.len() as u64;
+                }
+            }
         } else {
         } else {
             let _ = executor.drain_cleared();
             let _ = executor.drain_cleared();
         }
         }
@@ -398,8 +494,8 @@ fn run_accounts_bench(
         count += 1;
         count += 1;
         if last_log.elapsed().as_millis() > 3000 {
         if last_log.elapsed().as_millis() > 3000 {
             info!(
             info!(
-                "total_accounts: {} tx_sent_count: {} loop_count: {} balance: {}",
-                total_account_count, tx_sent_count, count, balance
+                "total_accounts_created: {} total_accounts_closed: {} tx_sent_count: {} loop_count: {} balance: {}",
+                total_accounts_created, total_accounts_closed, tx_sent_count, count, balance
             );
             );
             last_log = Instant::now();
             last_log = Instant::now();
         }
         }
@@ -455,14 +551,21 @@ fn main() {
         )
         )
         .arg(
         .arg(
             Arg::with_name("batch_size")
             Arg::with_name("batch_size")
-                .long("batch_size")
+                .long("batch-size")
                 .takes_value(true)
                 .takes_value(true)
                 .value_name("BYTES")
                 .value_name("BYTES")
-                .help("Size of accounts to create"),
+                .help("Number of transactions to send per batch"),
+        )
+        .arg(
+            Arg::with_name("close_nth")
+                .long("close-frequency")
+                .takes_value(true)
+                .value_name("BYTES")
+                .help("Send close transactions after this many accounts created"),
         )
         )
         .arg(
         .arg(
             Arg::with_name("num_instructions")
             Arg::with_name("num_instructions")
-                .long("num_instructions")
+                .long("num-instructions")
                 .takes_value(true)
                 .takes_value(true)
                 .value_name("NUM")
                 .value_name("NUM")
                 .help("Number of accounts to create on each transaction"),
                 .help("Number of accounts to create on each transaction"),
@@ -508,6 +611,7 @@ fn main() {
     let space = value_t!(matches, "space", u64).ok();
     let space = value_t!(matches, "space", u64).ok();
     let lamports = value_t!(matches, "lamports", u64).ok();
     let lamports = value_t!(matches, "lamports", u64).ok();
     let batch_size = value_t!(matches, "batch_size", usize).unwrap_or(4);
     let batch_size = value_t!(matches, "batch_size", usize).unwrap_or(4);
+    let close_nth = value_t!(matches, "close_nth", u64).unwrap_or(0);
     let iterations = value_t!(matches, "iterations", usize).unwrap_or(10);
     let iterations = value_t!(matches, "iterations", usize).unwrap_or(10);
     let num_instructions = value_t!(matches, "num_instructions", usize).unwrap_or(1);
     let num_instructions = value_t!(matches, "num_instructions", usize).unwrap_or(1);
     if num_instructions == 0 || num_instructions > 500 {
     if num_instructions == 0 || num_instructions > 500 {
@@ -551,6 +655,7 @@ fn main() {
         iterations,
         iterations,
         space,
         space,
         batch_size,
         batch_size,
+        close_nth,
         lamports,
         lamports,
         num_instructions,
         num_instructions,
         mint,
         mint,
@@ -585,6 +690,7 @@ pub mod test {
         let iterations = 10;
         let iterations = 10;
         let maybe_space = None;
         let maybe_space = None;
         let batch_size = 100;
         let batch_size = 100;
+        let close_nth = 100;
         let maybe_lamports = None;
         let maybe_lamports = None;
         let num_instructions = 2;
         let num_instructions = 2;
         let mut start = Measure::start("total accounts run");
         let mut start = Measure::start("total accounts run");
@@ -595,6 +701,7 @@ pub mod test {
             iterations,
             iterations,
             maybe_space,
             maybe_space,
             batch_size,
             batch_size,
+            close_nth,
             maybe_lamports,
             maybe_lamports,
             num_instructions,
             num_instructions,
             None,
             None,