From 47fbfc52dedb165342224b20d0d30062acf7fb2d Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Tue, 17 Nov 2020 14:53:49 -0700 Subject: [PATCH] Revert solana-tokens to RpcClient (#13623) * Revert solana-tokens to RpcClient * Fixup check_payer_balances tests * Use RpcClient::new_with_commitment in other tests Co-authored-by: Tyera Eulberg --- Cargo.lock | 5 +- tokens/Cargo.toml | 6 +- tokens/src/commands.rs | 923 ++++++++++++++++++++------------------- tokens/src/db.rs | 5 +- tokens/src/main.rs | 15 +- tokens/tests/commands.rs | 9 +- 6 files changed, 480 insertions(+), 483 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 104b8e8e92..b0683ccddd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4958,8 +4958,6 @@ dependencies = [ "indicatif", "pickledb", "serde", - "solana-banks-client", - "solana-banks-server", "solana-clap-utils", "solana-cli-config", "solana-client", @@ -4969,10 +4967,9 @@ dependencies = [ "solana-runtime", "solana-sdk", "solana-stake-program", + "solana-transaction-status", "tempfile", "thiserror", - "tokio 0.3.2", - "url 2.1.1", ] [[package]] diff --git a/tokens/Cargo.toml b/tokens/Cargo.toml index c189c836ed..ee1d861e80 100644 --- a/tokens/Cargo.toml +++ b/tokens/Cargo.toml @@ -18,7 +18,6 @@ indexmap = "1.5.1" indicatif = "0.15.0" pickledb = "0.4.1" serde = { version = "1.0", features = ["derive"] } -solana-banks-client = { path = "../banks-client", version = "1.5.0" } solana-clap-utils = { path = "../clap-utils", version = "1.5.0" } solana-cli-config = { path = "../cli-config", version = "1.5.0" } solana-client = { path = "../client", version = "1.5.0" } @@ -26,14 +25,11 @@ solana-remote-wallet = { path = "../remote-wallet", version = "1.5.0" } solana-runtime = { path = "../runtime", version = "1.5.0" } solana-sdk = { path = "../sdk", version = "1.5.0" } solana-stake-program = { path = "../programs/stake", version = "1.5.0" } +solana-transaction-status = { path = "../transaction-status", version = "1.5.0" } tempfile = "3.1.0" thiserror = "1.0" -tokio = { version = "0.3", features = ["full"] } -url = "2.1" [dev-dependencies] bincode = "1.3.1" -solana-banks-server = { path = "../banks-server", version = "1.5.0" } solana-core = { path = "../core", version = "1.5.0" } solana-logger = { path = "../logger", version = "1.5.0" } -solana-runtime = { path = "../runtime", version = "1.5.0" } diff --git a/tokens/src/commands.rs b/tokens/src/commands.rs index 0d4e7d10c1..d28a911f47 100644 --- a/tokens/src/commands.rs +++ b/tokens/src/commands.rs @@ -7,16 +7,19 @@ use indexmap::IndexMap; use indicatif::{ProgressBar, ProgressStyle}; use pickledb::PickleDb; use serde::{Deserialize, Serialize}; -use solana_banks_client::BanksClient; +use solana_client::{ + client_error::{ClientError, Result as ClientResult}, + rpc_client::RpcClient, + rpc_config::RpcSendTransactionConfig, +}; use solana_sdk::{ - commitment_config::CommitmentLevel, + commitment_config::CommitmentConfig, instruction::Instruction, message::Message, native_token::{lamports_to_sol, sol_to_lamports}, signature::{unique_signers, Signature, Signer}, system_instruction, transaction::Transaction, - transport::{self, TransportError}, }; use solana_stake_program::{ stake_instruction::{self, LockupArgs}, @@ -25,9 +28,9 @@ use solana_stake_program::{ use std::{ cmp::{self}, io, + thread::sleep, time::Duration, }; -use tokio::time::sleep; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] struct Allocation { @@ -78,7 +81,7 @@ pub enum Error { #[error("PickleDb error")] PickleDbError(#[from] pickledb::error::Error), #[error("Transport error")] - TransportError(#[from] TransportError), + ClientError(#[from] ClientError), #[error("Missing lockup authority")] MissingLockupAuthority, #[error("insufficient funds in {0:?}, requires {1} SOL")] @@ -128,16 +131,16 @@ fn apply_previous_transactions( allocations.retain(|x| x.amount > 0.5); } -async fn transfer( - client: &mut BanksClient, +fn transfer( + client: &RpcClient, lamports: u64, sender_keypair: &S, to_pubkey: &Pubkey, -) -> io::Result { +) -> ClientResult { let create_instruction = system_instruction::transfer(&sender_keypair.pubkey(), &to_pubkey, lamports); let message = Message::new(&[create_instruction], Some(&sender_keypair.pubkey())); - let recent_blockhash = client.get_recent_blockhash().await?; + let (recent_blockhash, _fees) = client.get_recent_blockhash()?; Ok(Transaction::new( &[sender_keypair], message, @@ -218,8 +221,8 @@ fn distribution_instructions( instructions } -async fn distribute_allocations( - client: &mut BanksClient, +fn distribute_allocations( + client: &RpcClient, db: &mut PickleDb, allocations: &[Allocation], args: &DistributeTokensArgs, @@ -252,7 +255,7 @@ async fn distribute_allocations( .iter() .map(|message| message.header.num_required_signatures as usize) .sum(); - check_payer_balances(num_signatures, allocations, client, args).await?; + check_payer_balances(num_signatures, allocations, client, args)?; for ((allocation, message), (new_stake_account_keypair, lockup_date)) in allocations.iter().zip(messages).zip(stake_extras) @@ -273,13 +276,19 @@ async fn distribute_allocations( } } let signers = unique_signers(signers); - let result: transport::Result<(Transaction, u64)> = { + let result: ClientResult<(Transaction, u64)> = { if args.dry_run { Ok((Transaction::new_unsigned(message), std::u64::MAX)) } else { - let (_fee_calculator, blockhash, last_valid_slot) = client.get_fees().await?; + let (blockhash, _fee_calculator, last_valid_slot) = client + .get_recent_blockhash_with_commitment(CommitmentConfig::default())? + .value; let transaction = Transaction::new(&signers, message, blockhash); - client.send_transaction(transaction.clone()).await?; + let config = RpcSendTransactionConfig { + skip_preflight: true, + ..RpcSendTransactionConfig::default() + }; + client.send_transaction_with_config(&transaction, config)?; Ok((transaction, last_valid_slot)) } }; @@ -333,8 +342,8 @@ fn new_spinner_progress_bar() -> ProgressBar { progress_bar } -pub async fn process_allocations( - client: &mut BanksClient, +pub fn process_allocations( + client: &RpcClient, args: &DistributeTokensArgs, ) -> Result, Error> { let mut allocations: Vec = read_allocations(&args.input_csv, args.transfer_amount)?; @@ -349,7 +358,7 @@ pub async fn process_allocations( let mut db = db::open_db(&args.transaction_db, args.dry_run)?; // Start by finalizing any transactions from the previous run. - let confirmations = finalize_transactions(client, &mut db, args.dry_run).await?; + let confirmations = finalize_transactions(client, &mut db, args.dry_run)?; let transaction_infos = db::read_transaction_infos(&db); apply_previous_transactions(&mut allocations, &transaction_infos); @@ -382,9 +391,9 @@ pub async fn process_allocations( .bold() ); - distribute_allocations(client, &mut db, &allocations, args).await?; + distribute_allocations(client, &mut db, &allocations, args)?; - let opt_confirmations = finalize_transactions(client, &mut db, args.dry_run).await?; + let opt_confirmations = finalize_transactions(client, &mut db, args.dry_run)?; if !args.dry_run { if let Some(output_path) = &args.output_path { @@ -395,8 +404,8 @@ pub async fn process_allocations( Ok(opt_confirmations) } -async fn finalize_transactions( - client: &mut BanksClient, +fn finalize_transactions( + client: &RpcClient, db: &mut PickleDb, dry_run: bool, ) -> Result, Error> { @@ -404,7 +413,7 @@ async fn finalize_transactions( return Ok(None); } - let mut opt_confirmations = update_finalized_transactions(client, db).await?; + let mut opt_confirmations = update_finalized_transactions(client, db)?; let progress_bar = new_spinner_progress_bar(); @@ -417,8 +426,8 @@ async fn finalize_transactions( } // Sleep for about 1 slot - sleep(Duration::from_millis(500)).await; - let opt_conf = update_finalized_transactions(client, db).await?; + sleep(Duration::from_millis(500)); + let opt_conf = update_finalized_transactions(client, db)?; opt_confirmations = opt_conf; } @@ -427,8 +436,8 @@ async fn finalize_transactions( // Update the finalized bit on any transactions that are now rooted // Return the lowest number of confirmations on the unfinalized transactions or None if all are finalized. -async fn update_finalized_transactions( - client: &mut BanksClient, +fn update_finalized_transactions( + client: &RpcClient, db: &mut PickleDb, ) -> Result, Error> { let transaction_infos = db::read_transaction_infos(db); @@ -448,9 +457,9 @@ async fn update_finalized_transactions( .filter(|sig| *sig != Signature::default()) // Filter out dry-run signatures .collect(); let transaction_statuses = client - .get_transaction_statuses(unconfirmed_signatures) - .await?; - let root_slot = client.get_root_slot().await?; + .get_signature_statuses(&unconfirmed_signatures)? + .value; + let root_slot = client.get_slot()?; let mut confirmations = None; for ((transaction, last_valid_slot), opt_transaction_status) in unconfirmed_transactions @@ -475,15 +484,15 @@ async fn update_finalized_transactions( Ok(confirmations) } -async fn check_payer_balances( +fn check_payer_balances( num_signatures: usize, allocations: &[Allocation], - client: &mut BanksClient, + client: &RpcClient, args: &DistributeTokensArgs, ) -> Result<(), Error> { let mut undistributed_tokens: f64 = allocations.iter().map(|x| x.amount).sum(); - let (fee_calculator, _blockhash, _last_valid_slot) = client.get_fees().await?; + let (_blockhash, fee_calculator) = client.get_recent_blockhash()?; let fees = fee_calculator .lamports_per_signature .checked_mul(num_signatures as u64) @@ -505,7 +514,7 @@ async fn check_payer_balances( let allocation_lamports = sol_to_lamports(undistributed_tokens); if let Some((unlocked_sol_source, total_unlocked_sol)) = unlocked_sol_source { - let staker_balance = client.get_balance(distribution_source).await?; + let staker_balance = client.get_balance(&distribution_source)?; if staker_balance < allocation_lamports { return Err(Error::InsufficientFunds( vec![FundingSource::StakeAccount].into(), @@ -513,7 +522,7 @@ async fn check_payer_balances( )); } if args.fee_payer.pubkey() == unlocked_sol_source { - let balance = client.get_balance(args.fee_payer.pubkey()).await?; + let balance = client.get_balance(&args.fee_payer.pubkey())?; if balance < fees + total_unlocked_sol { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount, FundingSource::FeePayer].into(), @@ -521,14 +530,14 @@ async fn check_payer_balances( )); } } else { - let fee_payer_balance = client.get_balance(args.fee_payer.pubkey()).await?; + let fee_payer_balance = client.get_balance(&args.fee_payer.pubkey())?; if fee_payer_balance < fees { return Err(Error::InsufficientFunds( vec![FundingSource::FeePayer].into(), lamports_to_sol(fees), )); } - let unlocked_sol_balance = client.get_balance(unlocked_sol_source).await?; + let unlocked_sol_balance = client.get_balance(&unlocked_sol_source)?; if unlocked_sol_balance < total_unlocked_sol { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount].into(), @@ -537,7 +546,7 @@ async fn check_payer_balances( } } } else if args.fee_payer.pubkey() == distribution_source { - let balance = client.get_balance(args.fee_payer.pubkey()).await?; + let balance = client.get_balance(&args.fee_payer.pubkey())?; if balance < fees + allocation_lamports { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount, FundingSource::FeePayer].into(), @@ -545,14 +554,14 @@ async fn check_payer_balances( )); } } else { - let fee_payer_balance = client.get_balance(args.fee_payer.pubkey()).await?; + let fee_payer_balance = client.get_balance(&args.fee_payer.pubkey())?; if fee_payer_balance < fees { return Err(Error::InsufficientFunds( vec![FundingSource::FeePayer].into(), lamports_to_sol(fees), )); } - let sender_balance = client.get_balance(distribution_source).await?; + let sender_balance = client.get_balance(&distribution_source)?; if sender_balance < allocation_lamports { return Err(Error::InsufficientFunds( vec![FundingSource::SystemAccount].into(), @@ -563,10 +572,7 @@ async fn check_payer_balances( Ok(()) } -pub async fn process_balances( - client: &mut BanksClient, - args: &BalancesArgs, -) -> Result<(), csv::Error> { +pub fn process_balances(client: &RpcClient, args: &BalancesArgs) -> Result<(), csv::Error> { let allocations: Vec = read_allocations(&args.input_csv, None)?; let allocations = merge_allocations(&allocations); @@ -582,7 +588,7 @@ pub async fn process_balances( for allocation in &allocations { let address = allocation.recipient.parse().unwrap(); let expected = lamports_to_sol(sol_to_lamports(allocation.amount)); - let actual = lamports_to_sol(client.get_balance(address).await.unwrap()); + let actual = lamports_to_sol(client.get_balance(&address).unwrap()); println!( "{:<44} {:>24.9} {:>24.9} {:>24.9}", allocation.recipient, @@ -604,8 +610,8 @@ pub fn process_transaction_log(args: &TransactionLogArgs) -> Result<(), Error> { use crate::db::check_output_file; use solana_sdk::{pubkey::Pubkey, signature::Keypair}; use tempfile::{tempdir, NamedTempFile}; -pub async fn test_process_distribute_tokens_with_client( - client: &mut BanksClient, +pub fn test_process_distribute_tokens_with_client( + client: &RpcClient, sender_keypair: Keypair, transfer_amount: Option, ) { @@ -616,17 +622,12 @@ pub async fn test_process_distribute_tokens_with_client( &sender_keypair, &fee_payer.pubkey(), ) - .await .unwrap(); client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); assert_eq!( - client - .get_balance_with_commitment(fee_payer.pubkey(), CommitmentLevel::Recent) - .await - .unwrap(), + client.get_balance(&fee_payer.pubkey()).unwrap(), sol_to_lamports(1.0), ); @@ -667,7 +668,7 @@ pub async fn test_process_distribute_tokens_with_client( stake_args: None, transfer_amount, }; - let confirmations = process_allocations(client, &args).await.unwrap(); + let confirmations = process_allocations(client, &args).unwrap(); assert_eq!(confirmations, None); let transaction_infos = @@ -680,15 +681,12 @@ pub async fn test_process_distribute_tokens_with_client( expected_amount ); - assert_eq!( - client.get_balance(alice_pubkey).await.unwrap(), - expected_amount, - ); + assert_eq!(client.get_balance(&alice_pubkey).unwrap(), expected_amount,); check_output_file(&output_path, &db::open_db(&transaction_db, true).unwrap()); // Now, run it again, and check there's no double-spend. - process_allocations(client, &args).await.unwrap(); + process_allocations(client, &args).unwrap(); let transaction_infos = db::read_transaction_infos(&db::open_db(&transaction_db, true).unwrap()); assert_eq!(transaction_infos.len(), 1); @@ -699,18 +697,12 @@ pub async fn test_process_distribute_tokens_with_client( expected_amount ); - assert_eq!( - client.get_balance(alice_pubkey).await.unwrap(), - expected_amount, - ); + assert_eq!(client.get_balance(&alice_pubkey).unwrap(), expected_amount,); check_output_file(&output_path, &db::open_db(&transaction_db, true).unwrap()); } -pub async fn test_process_distribute_stake_with_client( - client: &mut BanksClient, - sender_keypair: Keypair, -) { +pub fn test_process_distribute_stake_with_client(client: &RpcClient, sender_keypair: Keypair) { let fee_payer = Keypair::new(); let transaction = transfer( client, @@ -718,11 +710,9 @@ pub async fn test_process_distribute_stake_with_client( &sender_keypair, &fee_payer.pubkey(), ) - .await .unwrap(); client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); let stake_account_keypair = Keypair::new(); @@ -744,11 +734,10 @@ pub async fn test_process_distribute_stake_with_client( ); let message = Message::new(&instructions, Some(&sender_keypair.pubkey())); let signers = [&sender_keypair, &stake_account_keypair]; - let blockhash = client.get_recent_blockhash().await.unwrap(); + let (blockhash, _fees) = client.get_recent_blockhash().unwrap(); let transaction = Transaction::new(&signers, message, blockhash); client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); let alice_pubkey = solana_sdk::pubkey::new_rand(); @@ -791,7 +780,7 @@ pub async fn test_process_distribute_stake_with_client( sender_keypair: Box::new(sender_keypair), transfer_amount: None, }; - let confirmations = process_allocations(client, &args).await.unwrap(); + let confirmations = process_allocations(client, &args).unwrap(); assert_eq!(confirmations, None); let transaction_infos = @@ -805,19 +794,19 @@ pub async fn test_process_distribute_stake_with_client( ); assert_eq!( - client.get_balance(alice_pubkey).await.unwrap(), + client.get_balance(&alice_pubkey).unwrap(), sol_to_lamports(1.0), ); let new_stake_account_address = transaction_infos[0].new_stake_account_address.unwrap(); assert_eq!( - client.get_balance(new_stake_account_address).await.unwrap(), + client.get_balance(&new_stake_account_address).unwrap(), expected_amount - sol_to_lamports(1.0), ); check_output_file(&output_path, &db::open_db(&transaction_db, true).unwrap()); // Now, run it again, and check there's no double-spend. - process_allocations(client, &args).await.unwrap(); + process_allocations(client, &args).unwrap(); let transaction_infos = db::read_transaction_infos(&db::open_db(&transaction_db, true).unwrap()); assert_eq!(transaction_infos.len(), 1); @@ -829,11 +818,11 @@ pub async fn test_process_distribute_stake_with_client( ); assert_eq!( - client.get_balance(alice_pubkey).await.unwrap(), + client.get_balance(&alice_pubkey).unwrap(), sol_to_lamports(1.0), ); assert_eq!( - client.get_balance(new_stake_account_address).await.unwrap(), + client.get_balance(&new_stake_account_address).unwrap(), expected_amount - sol_to_lamports(1.0), ); @@ -843,55 +832,67 @@ pub async fn test_process_distribute_stake_with_client( #[cfg(test)] mod tests { use super::*; - use solana_banks_client::start_client; - use solana_banks_server::banks_server::start_local_server; - use solana_runtime::{bank::Bank, bank_forks::BankForks}; + use solana_client::rpc_client::get_rpc_request_str; + use solana_core::test_validator::TestValidator; use solana_sdk::{ - fee_calculator::FeeRateGovernor, - genesis_config::create_genesis_config, + clock::DEFAULT_MS_PER_SLOT, signature::{read_keypair_file, write_keypair_file}, }; use solana_stake_program::stake_instruction::StakeInstruction; - use std::sync::{Arc, RwLock}; - use tokio::runtime::Runtime; + use std::fs::remove_dir_all; #[test] fn test_process_token_allocations() { - let (genesis_config, sender_keypair) = create_genesis_config(sol_to_lamports(9_000_000.0)); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); - test_process_distribute_tokens_with_client(&mut banks_client, sender_keypair, None) - .await; - }); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run(); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); + test_process_distribute_tokens_with_client(&client, alice, None); + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } #[test] fn test_process_transfer_amount_allocations() { - let (genesis_config, sender_keypair) = create_genesis_config(sol_to_lamports(9_000_000.0)); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); - test_process_distribute_tokens_with_client( - &mut banks_client, - sender_keypair, - Some(1.5), - ) - .await; - }); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run(); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); + test_process_distribute_tokens_with_client(&client, alice, Some(1.5)); + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } #[test] fn test_process_stake_allocations() { - let (genesis_config, sender_keypair) = create_genesis_config(sol_to_lamports(9_000_000.0)); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); - test_process_distribute_stake_with_client(&mut banks_client, sender_keypair).await; - }); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run(); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); + test_process_distribute_stake_with_client(&client, alice); + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } #[test] @@ -1115,185 +1116,198 @@ mod tests { fn test_check_payer_balances_distribute_tokens_single_payer() { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); - let (mut genesis_config, sender_keypair) = - create_genesis_config(sol_to_lamports(9_000_000.0)); - genesis_config.fee_rate_governor = FeeRateGovernor::new(fees, 0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run_with_fees(fees); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); + let sender_keypair_file = tmp_file_path("keypair_file", &alice.pubkey()); + write_keypair_file(&alice, &sender_keypair_file).unwrap(); - let sender_keypair_file = tmp_file_path("keypair_file", &sender_keypair.pubkey()); - write_keypair_file(&sender_keypair, &sender_keypair_file).unwrap(); + // This is a quick hack until TestValidator can be initialized with fees from block 0 + while client + .get_recent_blockhash() + .unwrap() + .1 + .lamports_per_signature + == 0 + { + sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + } - let allocation_amount = 1000.0; + let allocation_amount = 1000.0; - // Fully funded payer - let (allocations, mut args) = initialize_check_payer_balances_inputs( - allocation_amount, - &sender_keypair_file, - &sender_keypair_file, - None, + // Fully funded payer + let (allocations, mut args) = initialize_check_payer_balances_inputs( + allocation_amount, + &sender_keypair_file, + &sender_keypair_file, + None, + ); + check_payer_balances(1, &allocations, &client, &args).unwrap(); + + // Unfunded payer + let unfunded_payer = Keypair::new(); + let unfunded_payer_keypair_file = tmp_file_path("keypair_file", &unfunded_payer.pubkey()); + write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); + args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!( + sources, + vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap(); + assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } - // Unfunded payer - let unfunded_payer = Keypair::new(); - let unfunded_payer_keypair_file = - tmp_file_path("keypair_file", &unfunded_payer.pubkey()); - write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); - args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!( - sources, - vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() - ); - assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - - // Payer funded enough for distribution only - let partially_funded_payer = Keypair::new(); - let partially_funded_payer_keypair_file = - tmp_file_path("keypair_file", &partially_funded_payer.pubkey()); - write_keypair_file( - &partially_funded_payer, - &partially_funded_payer_keypair_file, - ) + // Payer funded enough for distribution only + let partially_funded_payer = Keypair::new(); + let partially_funded_payer_keypair_file = + tmp_file_path("keypair_file", &partially_funded_payer.pubkey()); + write_keypair_file( + &partially_funded_payer, + &partially_funded_payer_keypair_file, + ) + .unwrap(); + let transaction = transfer( + &client, + sol_to_lamports(allocation_amount), + &alice, + &partially_funded_payer.pubkey(), + ) + .unwrap(); + client + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); - let transaction = transfer( - &mut banks_client, - sol_to_lamports(allocation_amount), - &sender_keypair, - &partially_funded_payer.pubkey(), - ) - .await - .unwrap(); - banks_client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await - .unwrap(); - args.sender_keypair = read_keypair_file(&partially_funded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&partially_funded_payer_keypair_file) - .unwrap() - .into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!( - sources, - vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() - ); - assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - }); + args.sender_keypair = read_keypair_file(&partially_funded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&partially_funded_payer_keypair_file) + .unwrap() + .into(); + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!( + sources, + vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() + ); + assert!((amount - (allocation_amount + fees_in_sol)).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } #[test] fn test_check_payer_balances_distribute_tokens_separate_payers() { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); - let (mut genesis_config, sender_keypair) = - create_genesis_config(sol_to_lamports(9_000_000.0)); - genesis_config.fee_rate_governor = FeeRateGovernor::new(fees, 0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run_with_fees(fees); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); - let sender_keypair_file = tmp_file_path("keypair_file", &sender_keypair.pubkey()); - write_keypair_file(&sender_keypair, &sender_keypair_file).unwrap(); + let sender_keypair_file = tmp_file_path("keypair_file", &alice.pubkey()); + write_keypair_file(&alice, &sender_keypair_file).unwrap(); - let allocation_amount = 1000.0; + // This is a quick hack until TestValidator can be initialized with fees from block 0 + while client + .get_recent_blockhash() + .unwrap() + .1 + .lamports_per_signature + == 0 + { + sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + } - let funded_payer = Keypair::new(); - let funded_payer_keypair_file = tmp_file_path("keypair_file", &funded_payer.pubkey()); - write_keypair_file(&funded_payer, &funded_payer_keypair_file).unwrap(); - let transaction = transfer( - &mut banks_client, - sol_to_lamports(allocation_amount), - &sender_keypair, - &funded_payer.pubkey(), - ) - .await + let allocation_amount = 1000.0; + + let funded_payer = Keypair::new(); + let funded_payer_keypair_file = tmp_file_path("keypair_file", &funded_payer.pubkey()); + write_keypair_file(&funded_payer, &funded_payer_keypair_file).unwrap(); + let transaction = transfer( + &client, + sol_to_lamports(allocation_amount), + &alice, + &funded_payer.pubkey(), + ) + .unwrap(); + client + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); - banks_client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await - .unwrap(); - // Fully funded payers - let (allocations, mut args) = initialize_check_payer_balances_inputs( - allocation_amount, - &funded_payer_keypair_file, - &sender_keypair_file, - None, - ); - check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap(); + // Fully funded payers + let (allocations, mut args) = initialize_check_payer_balances_inputs( + allocation_amount, + &funded_payer_keypair_file, + &sender_keypair_file, + None, + ); + check_payer_balances(1, &allocations, &client, &args).unwrap(); - // Unfunded sender - let unfunded_payer = Keypair::new(); - let unfunded_payer_keypair_file = - tmp_file_path("keypair_file", &unfunded_payer.pubkey()); - write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); - args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into(); + // Unfunded sender + let unfunded_payer = Keypair::new(); + let unfunded_payer_keypair_file = tmp_file_path("keypair_file", &unfunded_payer.pubkey()); + write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); + args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!(sources, vec![FundingSource::SystemAccount].into()); - assert!((amount - allocation_amount).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!(sources, vec![FundingSource::SystemAccount].into()); + assert!((amount - allocation_amount).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } - // Unfunded fee payer - args.sender_keypair = read_keypair_file(&sender_keypair_file).unwrap().into(); - args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); + // Unfunded fee payer + args.sender_keypair = read_keypair_file(&sender_keypair_file).unwrap().into(); + args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!(sources, vec![FundingSource::FeePayer].into()); - assert!((amount - fees_in_sol).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - }); + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!(sources, vec![FundingSource::FeePayer].into()); + assert!((amount - fees_in_sol).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } - async fn initialize_stake_account( + fn initialize_stake_account( stake_account_amount: f64, unlocked_sol: f64, sender_keypair: &Keypair, - banks_client: &mut BanksClient, + client: &RpcClient, ) -> StakeArgs { let stake_account_keypair = Keypair::new(); let stake_account_address = stake_account_keypair.pubkey(); @@ -1314,11 +1328,10 @@ mod tests { ); let message = Message::new(&instructions, Some(&sender_keypair.pubkey())); let signers = [sender_keypair, &stake_account_keypair]; - let blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let (blockhash, _fees) = client.get_recent_blockhash().unwrap(); let transaction = Transaction::new(&signers, message, blockhash); - banks_client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await + client + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); StakeArgs { @@ -1334,213 +1347,211 @@ mod tests { fn test_check_payer_balances_distribute_stakes_single_payer() { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); - let (mut genesis_config, sender_keypair) = - create_genesis_config(sol_to_lamports(9_000_000.0)); - genesis_config.fee_rate_governor = FeeRateGovernor::new(fees, 0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run_with_fees(fees); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); - let sender_keypair_file = tmp_file_path("keypair_file", &sender_keypair.pubkey()); - write_keypair_file(&sender_keypair, &sender_keypair_file).unwrap(); + let sender_keypair_file = tmp_file_path("keypair_file", &alice.pubkey()); + write_keypair_file(&alice, &sender_keypair_file).unwrap(); - let allocation_amount = 1000.0; - let unlocked_sol = 1.0; - let stake_args = initialize_stake_account( - allocation_amount, - unlocked_sol, - &sender_keypair, - &mut banks_client, - ) - .await; + // This is a quick hack until TestValidator can be initialized with fees from block 0 + while client + .get_recent_blockhash() + .unwrap() + .1 + .lamports_per_signature + == 0 + { + sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + } - // Fully funded payer & stake account - let (allocations, mut args) = initialize_check_payer_balances_inputs( - allocation_amount, - &sender_keypair_file, - &sender_keypair_file, - Some(stake_args), + let allocation_amount = 1000.0; + let unlocked_sol = 1.0; + let stake_args = initialize_stake_account(allocation_amount, unlocked_sol, &alice, &client); + + // Fully funded payer & stake account + let (allocations, mut args) = initialize_check_payer_balances_inputs( + allocation_amount, + &sender_keypair_file, + &sender_keypair_file, + Some(stake_args), + ); + check_payer_balances(1, &allocations, &client, &args).unwrap(); + + // Underfunded stake-account + let expensive_allocation_amount = 5000.0; + let expensive_allocations = vec![Allocation { + recipient: solana_sdk::pubkey::new_rand().to_string(), + amount: expensive_allocation_amount, + lockup_date: "".to_string(), + }]; + let err_result = + check_payer_balances(1, &expensive_allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!(sources, vec![FundingSource::StakeAccount].into()); + assert!((amount - (expensive_allocation_amount - unlocked_sol)).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } + + // Unfunded payer + let unfunded_payer = Keypair::new(); + let unfunded_payer_keypair_file = tmp_file_path("keypair_file", &unfunded_payer.pubkey()); + write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); + args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!( + sources, + vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() ); - check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap(); + assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } - // Underfunded stake-account - let expensive_allocation_amount = 5000.0; - let expensive_allocations = vec![Allocation { - recipient: solana_sdk::pubkey::new_rand().to_string(), - amount: expensive_allocation_amount, - lockup_date: "".to_string(), - }]; - let err_result = - check_payer_balances(1, &expensive_allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!(sources, vec![FundingSource::StakeAccount].into()); - assert!( - (amount - (expensive_allocation_amount - unlocked_sol)).abs() < f64::EPSILON - ); - } else { - panic!("check_payer_balances should have errored"); - } - - // Unfunded payer - let unfunded_payer = Keypair::new(); - let unfunded_payer_keypair_file = - tmp_file_path("keypair_file", &unfunded_payer.pubkey()); - write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); - args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!( - sources, - vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() - ); - assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - - // Payer funded enough for distribution only - let partially_funded_payer = Keypair::new(); - let partially_funded_payer_keypair_file = - tmp_file_path("keypair_file", &partially_funded_payer.pubkey()); - write_keypair_file( - &partially_funded_payer, - &partially_funded_payer_keypair_file, - ) + // Payer funded enough for distribution only + let partially_funded_payer = Keypair::new(); + let partially_funded_payer_keypair_file = + tmp_file_path("keypair_file", &partially_funded_payer.pubkey()); + write_keypair_file( + &partially_funded_payer, + &partially_funded_payer_keypair_file, + ) + .unwrap(); + let transaction = transfer( + &client, + sol_to_lamports(unlocked_sol), + &alice, + &partially_funded_payer.pubkey(), + ) + .unwrap(); + client + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); - let transaction = transfer( - &mut banks_client, - sol_to_lamports(unlocked_sol), - &sender_keypair, - &partially_funded_payer.pubkey(), - ) - .await - .unwrap(); - banks_client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await - .unwrap(); - args.sender_keypair = read_keypair_file(&partially_funded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&partially_funded_payer_keypair_file) - .unwrap() - .into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!( - sources, - vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() - ); - assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - }); + args.sender_keypair = read_keypair_file(&partially_funded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&partially_funded_payer_keypair_file) + .unwrap() + .into(); + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!( + sources, + vec![FundingSource::SystemAccount, FundingSource::FeePayer].into() + ); + assert!((amount - (unlocked_sol + fees_in_sol)).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } #[test] fn test_check_payer_balances_distribute_stakes_separate_payers() { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); - let (mut genesis_config, sender_keypair) = - create_genesis_config(sol_to_lamports(9_000_000.0)); - genesis_config.fee_rate_governor = FeeRateGovernor::new(fees, 0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new(&genesis_config)))); - Runtime::new().unwrap().block_on(async { - let transport = start_local_server(&bank_forks).await; - let mut banks_client = start_client(transport).await.unwrap(); + let TestValidator { + server, + leader_data, + alice, + ledger_path, + .. + } = TestValidator::run_with_fees(fees); + let url = get_rpc_request_str(leader_data.rpc, false); + let client = RpcClient::new_with_commitment(url, CommitmentConfig::recent()); - let sender_keypair_file = tmp_file_path("keypair_file", &sender_keypair.pubkey()); - write_keypair_file(&sender_keypair, &sender_keypair_file).unwrap(); + let sender_keypair_file = tmp_file_path("keypair_file", &alice.pubkey()); + write_keypair_file(&alice, &sender_keypair_file).unwrap(); - let allocation_amount = 1000.0; - let unlocked_sol = 1.0; - let stake_args = initialize_stake_account( - allocation_amount, - unlocked_sol, - &sender_keypair, - &mut banks_client, - ) - .await; + // This is a quick hack until TestValidator can be initialized with fees from block 0 + while client + .get_recent_blockhash() + .unwrap() + .1 + .lamports_per_signature + == 0 + { + sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + } - let funded_payer = Keypair::new(); - let funded_payer_keypair_file = tmp_file_path("keypair_file", &funded_payer.pubkey()); - write_keypair_file(&funded_payer, &funded_payer_keypair_file).unwrap(); - let transaction = transfer( - &mut banks_client, - sol_to_lamports(unlocked_sol), - &sender_keypair, - &funded_payer.pubkey(), - ) - .await + let allocation_amount = 1000.0; + let unlocked_sol = 1.0; + let stake_args = initialize_stake_account(allocation_amount, unlocked_sol, &alice, &client); + + let funded_payer = Keypair::new(); + let funded_payer_keypair_file = tmp_file_path("keypair_file", &funded_payer.pubkey()); + write_keypair_file(&funded_payer, &funded_payer_keypair_file).unwrap(); + let transaction = transfer( + &client, + sol_to_lamports(unlocked_sol), + &alice, + &funded_payer.pubkey(), + ) + .unwrap(); + client + .send_and_confirm_transaction_with_spinner(&transaction) .unwrap(); - banks_client - .process_transaction_with_commitment(transaction, CommitmentLevel::Recent) - .await - .unwrap(); - // Fully funded payers - let (allocations, mut args) = initialize_check_payer_balances_inputs( - allocation_amount, - &funded_payer_keypair_file, - &sender_keypair_file, - Some(stake_args), - ); - check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap(); + // Fully funded payers + let (allocations, mut args) = initialize_check_payer_balances_inputs( + allocation_amount, + &funded_payer_keypair_file, + &sender_keypair_file, + Some(stake_args), + ); + check_payer_balances(1, &allocations, &client, &args).unwrap(); - // Unfunded sender - let unfunded_payer = Keypair::new(); - let unfunded_payer_keypair_file = - tmp_file_path("keypair_file", &unfunded_payer.pubkey()); - write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); - args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); - args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into(); + // Unfunded sender + let unfunded_payer = Keypair::new(); + let unfunded_payer_keypair_file = tmp_file_path("keypair_file", &unfunded_payer.pubkey()); + write_keypair_file(&unfunded_payer, &unfunded_payer_keypair_file).unwrap(); + args.sender_keypair = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); + args.fee_payer = read_keypair_file(&sender_keypair_file).unwrap().into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!(sources, vec![FundingSource::SystemAccount].into()); - assert!((amount - unlocked_sol).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!(sources, vec![FundingSource::SystemAccount].into()); + assert!((amount - unlocked_sol).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } - // Unfunded fee payer - args.sender_keypair = read_keypair_file(&sender_keypair_file).unwrap().into(); - args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) - .unwrap() - .into(); + // Unfunded fee payer + args.sender_keypair = read_keypair_file(&sender_keypair_file).unwrap().into(); + args.fee_payer = read_keypair_file(&unfunded_payer_keypair_file) + .unwrap() + .into(); - let err_result = check_payer_balances(1, &allocations, &mut banks_client, &args) - .await - .unwrap_err(); - if let Error::InsufficientFunds(sources, amount) = err_result { - assert_eq!(sources, vec![FundingSource::FeePayer].into()); - assert!((amount - fees_in_sol).abs() < f64::EPSILON); - } else { - panic!("check_payer_balances should have errored"); - } - }); + let err_result = check_payer_balances(1, &allocations, &client, &args).unwrap_err(); + if let Error::InsufficientFunds(sources, amount) = err_result { + assert_eq!(sources, vec![FundingSource::FeePayer].into()); + assert!((amount - fees_in_sol).abs() < f64::EPSILON); + } else { + panic!("check_payer_balances should have errored"); + } + + // Explicit cleanup, otherwise "pure virtual method called" crash in Docker + server.close().unwrap(); + remove_dir_all(ledger_path).unwrap(); } } diff --git a/tokens/src/db.rs b/tokens/src/db.rs index 78210c757b..aab8799cf8 100644 --- a/tokens/src/db.rs +++ b/tokens/src/db.rs @@ -1,8 +1,8 @@ use chrono::prelude::*; use pickledb::{error::Error, PickleDb, PickleDbDumpPolicy}; use serde::{Deserialize, Serialize}; -use solana_banks_client::TransactionStatus; use solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature, transaction::Transaction}; +use solana_transaction_status::TransactionStatus; use std::{cmp::Ordering, fs, io, path::Path}; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -306,6 +306,7 @@ mod tests { slot: 0, confirmations: Some(1), err: None, + status: Ok(()), }; assert_eq!( update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0) @@ -332,6 +333,7 @@ mod tests { slot: 0, confirmations: None, err: Some(TransactionError::AccountNotFound), + status: Ok(()), }; assert_eq!( update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0) @@ -355,6 +357,7 @@ mod tests { slot: 0, confirmations: None, err: None, + status: Ok(()), }; assert_eq!( update_finalized_transaction(&mut db, &signature, Some(transaction_status), 0, 0) diff --git a/tokens/src/main.rs b/tokens/src/main.rs index f677772bf8..4a4874be01 100644 --- a/tokens/src/main.rs +++ b/tokens/src/main.rs @@ -1,9 +1,7 @@ -use solana_banks_client::start_tcp_client; use solana_cli_config::{Config, CONFIG_FILE}; +use solana_client::rpc_client::RpcClient; use solana_tokens::{arg_parser::parse_args, args::Command, commands}; use std::{env, error::Error, path::Path, process}; -use tokio::runtime::Runtime; -use url::Url; fn main() -> Result<(), Box> { let command_args = parse_args(env::args_os())?; @@ -18,19 +16,14 @@ fn main() -> Result<(), Box> { Config::default() }; let json_rpc_url = command_args.url.unwrap_or(config.json_rpc_url); - let rpc_banks_url = Config::compute_rpc_banks_url(&json_rpc_url); - let url = Url::parse(&rpc_banks_url)?; - let host_port = (url.host_str().unwrap(), url.port().unwrap()); - - let runtime = Runtime::new().unwrap(); - let mut banks_client = runtime.block_on(start_tcp_client(&host_port))?; + let client = RpcClient::new(json_rpc_url); match command_args.command { Command::DistributeTokens(args) => { - runtime.block_on(commands::process_allocations(&mut banks_client, &args))?; + commands::process_allocations(&client, &args)?; } Command::Balances(args) => { - runtime.block_on(commands::process_balances(&mut banks_client, &args))?; + commands::process_balances(&client, &args)?; } Command::TransactionLog(args) => { commands::process_transaction_log(&args)?; diff --git a/tokens/tests/commands.rs b/tokens/tests/commands.rs index 52de12e810..0d3d288bc9 100644 --- a/tokens/tests/commands.rs +++ b/tokens/tests/commands.rs @@ -1,8 +1,7 @@ -use solana_banks_client::start_tcp_client; +use solana_client::rpc_client::RpcClient; use solana_core::test_validator::TestValidator; use solana_tokens::commands::test_process_distribute_tokens_with_client; use std::fs::remove_dir_all; -use tokio::runtime::Runtime; #[test] fn test_process_distribute_with_rpc_client() { @@ -15,10 +14,8 @@ fn test_process_distribute_with_rpc_client() { .. } = TestValidator::run(); - Runtime::new().unwrap().block_on(async { - let mut banks_client = start_tcp_client(leader_data.rpc_banks).await.unwrap(); - test_process_distribute_tokens_with_client(&mut banks_client, alice, None).await - }); + let client = RpcClient::new_socket(leader_data.rpc); + test_process_distribute_tokens_with_client(&client, alice, None); // Explicit cleanup, otherwise "pure virtual method called" crash in Docker server.close().unwrap();