From 0c2faa316812715e536605d24599816adf4b6d17 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 15 Apr 2021 18:12:07 +0000 Subject: [PATCH] Cli: move airdrop to rpc requests (#16557) (#16563) * Add recent_blockhash to requestAirdrop * Move tx confirmation to separate method * Add RpcClient airdrop methods * Request cli airdrop via RpcClient * Pass optional faucet_addr into TestValidator and fix tests * Update client/src/rpc_client.rs Co-authored-by: Michael Vines Co-authored-by: Michael Vines Co-authored-by: Tyera Eulberg Co-authored-by: Michael Vines --- cli/src/cli.rs | 142 +++++------------------------------ cli/tests/nonce.rs | 46 +++++------- cli/tests/program.rs | 42 ++++------- cli/tests/request_airdrop.rs | 6 +- cli/tests/stake.rs | 106 +++++++++++--------------- cli/tests/transfer.rs | 33 +++++--- cli/tests/vote.rs | 12 +-- client/src/mock_sender.rs | 1 + client/src/rpc_client.rs | 92 ++++++++++++++++++++--- client/src/rpc_config.rs | 8 ++ core/src/rpc.rs | 28 ++++--- core/src/test_validator.rs | 17 ++++- core/tests/client.rs | 2 +- core/tests/rpc.rs | 8 +- tokens/src/commands.rs | 16 ++-- tokens/tests/commands.rs | 2 +- 16 files changed, 258 insertions(+), 303 deletions(-) diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 6b2bb38e80..9a7ef0bb9a 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -32,11 +32,6 @@ use solana_client::{ }, rpc_response::RpcKeyedAccount, }; -#[cfg(not(test))] -use solana_faucet::faucet::request_airdrop_transaction; -use solana_faucet::faucet::FaucetError; -#[cfg(test)] -use solana_faucet::faucet_mock::request_airdrop_transaction; use solana_remote_wallet::remote_wallet::RemoteWalletManager; use solana_sdk::{ clock::{Epoch, Slot}, @@ -58,19 +53,10 @@ use solana_stake_program::{ use solana_transaction_status::{EncodedTransaction, UiTransactionEncoding}; use solana_vote_program::vote_state::VoteAuthorize; use std::{ - collections::HashMap, - error, - fmt::Write as FmtWrite, - fs::File, - io::Write, - net::{IpAddr, SocketAddr}, - str::FromStr, - sync::Arc, - thread::sleep, - time::Duration, + collections::HashMap, error, fmt::Write as FmtWrite, fs::File, io::Write, str::FromStr, + sync::Arc, time::Duration, }; use thiserror::Error; -use url::Url; pub const DEFAULT_RPC_TIMEOUT_SECONDS: &str = "30"; @@ -343,8 +329,6 @@ pub enum CliCommand { // Wallet Commands Address, Airdrop { - faucet_host: Option, - faucet_port: u16, pubkey: Option, lamports: u64, }, @@ -764,20 +748,6 @@ pub fn parse_command( signers: vec![default_signer.signer_from_path(matches, wallet_manager)?], }), ("airdrop", Some(matches)) => { - let faucet_port = matches - .value_of("faucet_port") - .ok_or_else(|| CliError::BadParameter("Missing faucet port".to_string()))? - .parse() - .map_err(|err| CliError::BadParameter(format!("Invalid faucet port: {}", err)))?; - - let faucet_host = matches - .value_of("faucet_host") - .map(|faucet_host| { - solana_net_utils::parse_host(faucet_host).map_err(|err| { - CliError::BadParameter(format!("Invalid faucet host: {}", err)) - }) - }) - .transpose()?; let pubkey = pubkey_of_signer(matches, "to", wallet_manager)?; let signers = if pubkey.is_some() { vec![] @@ -786,12 +756,7 @@ pub fn parse_command( }; let lamports = lamports_of_sol(matches, "amount").unwrap(); Ok(CliCommandInfo { - command: CliCommand::Airdrop { - faucet_host, - faucet_port, - pubkey, - lamports, - }, + command: CliCommand::Airdrop { pubkey, lamports }, signers, }) } @@ -984,7 +949,6 @@ fn process_create_address_with_seed( fn process_airdrop( rpc_client: &RpcClient, config: &CliConfig, - faucet_addr: &SocketAddr, pubkey: &Option, lamports: u64, ) -> ProcessResult { @@ -994,14 +958,13 @@ fn process_airdrop( config.pubkey()? }; println!( - "Requesting airdrop of {} from {}", + "Requesting airdrop of {}", build_balance_message(lamports, false, true), - faucet_addr ); let pre_balance = rpc_client.get_balance(&pubkey)?; - let result = request_and_confirm_airdrop(&rpc_client, faucet_addr, &pubkey, lamports); + let result = request_and_confirm_airdrop(rpc_client, config, &pubkey, lamports); if let Ok(signature) = result { let signature_cli_message = log_instruction_custom_error::(result, &config)?; println!("{}", signature_cli_message); @@ -1796,27 +1759,8 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { // Wallet Commands // Request an airdrop from Solana Faucet; - CliCommand::Airdrop { - faucet_host, - faucet_port, - pubkey, - lamports, - } => { - let faucet_addr = SocketAddr::new( - faucet_host.unwrap_or_else(|| { - let faucet_host = Url::parse(&config.json_rpc_url) - .unwrap() - .host() - .unwrap() - .to_string(); - solana_net_utils::parse_host(&faucet_host).unwrap_or_else(|err| { - panic!("Unable to resolve {}: {}", faucet_host, err); - }) - }), - *faucet_port, - ); - - process_airdrop(&rpc_client, config, &faucet_addr, pubkey, *lamports) + CliCommand::Airdrop { pubkey, lamports } => { + process_airdrop(&rpc_client, config, pubkey, *lamports) } // Check client balance CliCommand::Balance { @@ -1878,67 +1822,21 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { } } -// Quick and dirty Keypair that assumes the client will do retries but not update the -// blockhash. If the client updates the blockhash, the signature will be invalid. -struct FaucetKeypair { - transaction: Transaction, -} - -impl FaucetKeypair { - fn new_keypair( - faucet_addr: &SocketAddr, - to_pubkey: &Pubkey, - lamports: u64, - blockhash: Hash, - ) -> Result { - let transaction = request_airdrop_transaction(faucet_addr, to_pubkey, lamports, blockhash)?; - Ok(Self { transaction }) - } - - fn airdrop_transaction(&self) -> Transaction { - self.transaction.clone() - } -} - -impl Signer for FaucetKeypair { - /// Return the public key of the keypair used to sign votes - fn pubkey(&self) -> Pubkey { - self.transaction.message().account_keys[0] - } - - fn try_pubkey(&self) -> Result { - Ok(self.pubkey()) - } - - fn sign_message(&self, _msg: &[u8]) -> Signature { - self.transaction.signatures[0] - } - - fn try_sign_message(&self, message: &[u8]) -> Result { - Ok(self.sign_message(message)) - } -} - pub fn request_and_confirm_airdrop( rpc_client: &RpcClient, - faucet_addr: &SocketAddr, + config: &CliConfig, to_pubkey: &Pubkey, lamports: u64, ) -> ClientResult { - let (blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?; - let keypair = { - let mut retries = 5; - loop { - let result = FaucetKeypair::new_keypair(faucet_addr, to_pubkey, lamports, blockhash); - if result.is_ok() || retries == 0 { - break result; - } - retries -= 1; - sleep(Duration::from_secs(1)); - } - }?; - let tx = keypair.airdrop_transaction(); - rpc_client.send_and_confirm_transaction_with_spinner(&tx) + let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?; + let signature = + rpc_client.request_airdrop_with_blockhash(to_pubkey, lamports, &recent_blockhash)?; + rpc_client.confirm_transaction_with_spinner( + &signature, + &recent_blockhash, + config.commitment, + )?; + Ok(signature) } pub fn log_instruction_custom_error( @@ -2396,8 +2294,6 @@ mod tests { parse_command(&test_airdrop, &default_signer, &mut None).unwrap(), CliCommandInfo { command: CliCommand::Airdrop { - faucet_host: None, - faucet_port: solana_faucet::faucet::FAUCET_PORT, pubkey: Some(pubkey), lamports: 50_000_000_000, }, @@ -2775,8 +2671,6 @@ mod tests { let to = solana_sdk::pubkey::new_rand(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: 1234, pubkey: Some(to), lamports: 50, }; @@ -2801,8 +2695,6 @@ mod tests { config.rpc_client = Some(RpcClient::new_mock("fails".to_string())); config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: 1234, pubkey: None, lamports: 50, }; diff --git a/cli/tests/nonce.rs b/cli/tests/nonce.rs index 6c8acc3557..b73215ccb6 100644 --- a/cli/tests/nonce.rs +++ b/cli/tests/nonce.rs @@ -22,44 +22,38 @@ use solana_sdk::{ #[test] fn test_nonce() { let mint_keypair = Keypair::new(); - full_battery_tests( - TestValidator::with_no_fees(mint_keypair.pubkey()), - mint_keypair, - None, - false, - ); + let mint_pubkey = mint_keypair.pubkey(); + let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); + + full_battery_tests(test_validator, None, false); } #[test] fn test_nonce_with_seed() { let mint_keypair = Keypair::new(); - full_battery_tests( - TestValidator::with_no_fees(mint_keypair.pubkey()), - mint_keypair, - Some(String::from("seed")), - false, - ); + let mint_pubkey = mint_keypair.pubkey(); + let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); + + full_battery_tests(test_validator, Some(String::from("seed")), false); } #[test] fn test_nonce_with_authority() { let mint_keypair = Keypair::new(); - full_battery_tests( - TestValidator::with_no_fees(mint_keypair.pubkey()), - mint_keypair, - None, - true, - ); + let mint_pubkey = mint_keypair.pubkey(); + let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); + + full_battery_tests(test_validator, None, true); } fn full_battery_tests( test_validator: TestValidator, - mint_keypair: Keypair, seed: Option, use_nonce_authority: bool, ) { - let faucet_addr = run_local_faucet(mint_keypair, None); - let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); let json_rpc_url = test_validator.rpc_url(); @@ -71,7 +65,7 @@ fn full_battery_tests( request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_payer, &config_payer.signers[0].pubkey(), 2000, ) @@ -213,9 +207,9 @@ fn full_battery_tests( fn test_create_account_with_seed() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); - + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let offline_nonce_authority_signer = keypair_from_seed(&[1u8; 32]).unwrap(); let online_nonce_creator_signer = keypair_from_seed(&[2u8; 32]).unwrap(); @@ -226,14 +220,14 @@ fn test_create_account_with_seed() { RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &CliConfig::recent_for_tests(), &offline_nonce_authority_signer.pubkey(), 42, ) .unwrap(); request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &CliConfig::recent_for_tests(), &online_nonce_creator_signer.pubkey(), 4242, ) diff --git a/cli/tests/program.rs b/cli/tests/program.rs index fb089c4ab7..5cc6bce0dd 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -28,8 +28,9 @@ fn test_cli_program_deploy_non_upgradeable() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -46,8 +47,6 @@ fn test_cli_program_deploy_non_upgradeable() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 4 * minimum_balance_for_rent_exemption, // min balance for rent exemption for three programs + leftover for tx processing }; @@ -103,8 +102,6 @@ fn test_cli_program_deploy_non_upgradeable() { let custom_address_keypair = Keypair::new(); config.signers = vec![&custom_address_keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 2 * minimum_balance_for_rent_exemption, // Anything over minimum_balance_for_rent_exemption should trigger err }; @@ -146,8 +143,9 @@ fn test_cli_program_deploy_no_authority() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -170,8 +168,6 @@ fn test_cli_program_deploy_no_authority() { let keypair = Keypair::new(); config.json_rpc_url = test_validator.rpc_url(); config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program, }; @@ -229,8 +225,9 @@ fn test_cli_program_deploy_with_authority() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -254,8 +251,6 @@ fn test_cli_program_deploy_with_authority() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program, }; @@ -558,8 +553,9 @@ fn test_cli_program_write_buffer() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -584,8 +580,6 @@ fn test_cli_program_write_buffer() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_buffer, }; @@ -841,8 +835,9 @@ fn test_cli_program_set_buffer_authority() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -862,8 +857,6 @@ fn test_cli_program_set_buffer_authority() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_buffer, }; @@ -954,8 +947,9 @@ fn test_cli_program_mismatch_buffer_authority() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -975,8 +969,6 @@ fn test_cli_program_mismatch_buffer_authority() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_buffer, }; @@ -1044,8 +1036,9 @@ fn test_cli_program_show() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1068,8 +1061,6 @@ fn test_cli_program_show() { // Airdrop config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_buffer, }; @@ -1225,8 +1216,9 @@ fn test_cli_program_dump() { pathbuf.set_extension("so"); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1249,8 +1241,6 @@ fn test_cli_program_dump() { // Airdrop config.signers = vec![&keypair]; config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 100 * minimum_balance_for_buffer, }; diff --git a/cli/tests/request_airdrop.rs b/cli/tests/request_airdrop.rs index 38d9570653..0787d7725d 100644 --- a/cli/tests/request_airdrop.rs +++ b/cli/tests/request_airdrop.rs @@ -10,15 +10,13 @@ use solana_sdk::{ #[test] fn test_cli_request_airdrop() { let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); - + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let mut bob_config = CliConfig::recent_for_tests(); bob_config.json_rpc_url = test_validator.rpc_url(); bob_config.command = CliCommand::Airdrop { - faucet_host: None, - faucet_port: faucet_addr.port(), pubkey: None, lamports: 50, }; diff --git a/cli/tests/stake.rs b/cli/tests/stake.rs index 2b58596333..42b6e65208 100644 --- a/cli/tests/stake.rs +++ b/cli/tests/stake.rs @@ -26,8 +26,9 @@ use solana_stake_program::{ #[test] fn test_stake_delegation_force() { let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -37,13 +38,8 @@ fn test_stake_delegation_force() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 100_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 100_000) + .unwrap(); // Create vote account let vote_keypair = Keypair::new(); @@ -115,8 +111,9 @@ fn test_seed_stake_delegation_and_deactivation() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -128,7 +125,7 @@ fn test_seed_stake_delegation_and_deactivation() { request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_validator, &config_validator.signers[0].pubkey(), 100_000, ) @@ -195,8 +192,9 @@ fn test_stake_delegation_and_deactivation() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -210,7 +208,7 @@ fn test_stake_delegation_and_deactivation() { request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_validator, &config_validator.signers[0].pubkey(), 100_000, ) @@ -271,8 +269,9 @@ fn test_offline_stake_delegation_and_deactivation() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -297,7 +296,7 @@ fn test_offline_stake_delegation_and_deactivation() { request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_validator, &config_validator.signers[0].pubkey(), 100_000, ) @@ -306,7 +305,7 @@ fn test_offline_stake_delegation_and_deactivation() { request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_offline, &config_offline.signers[0].pubkey(), 100_000, ) @@ -405,8 +404,9 @@ fn test_nonced_stake_delegation_and_deactivation() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -420,13 +420,8 @@ fn test_nonced_stake_delegation_and_deactivation() { .get_minimum_balance_for_rent_exemption(NonceState::size()) .unwrap(); - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 100_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 100_000) + .unwrap(); // Create stake account let stake_keypair = Keypair::new(); @@ -520,8 +515,9 @@ fn test_stake_authorize() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -531,13 +527,8 @@ fn test_stake_authorize() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 100_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 100_000) + .unwrap(); let offline_keypair = keypair_from_seed(&[0u8; 32]).unwrap(); let mut config_offline = CliConfig::recent_for_tests(); @@ -550,7 +541,7 @@ fn test_stake_authorize() { request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &config_offline, &config_offline.signers[0].pubkey(), 100_000, ) @@ -781,8 +772,9 @@ fn test_stake_authorize_with_fee_payer() { const SIG_FEE: u64 = 42; let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), SIG_FEE); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, SIG_FEE, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -808,13 +800,13 @@ fn test_stake_authorize_with_fee_payer() { config_offline.command = CliCommand::ClusterVersion; process_command(&config_offline).unwrap_err(); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &default_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &default_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &config.signers[0].pubkey()); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &payer_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config_payer, &payer_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &payer_pubkey); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &offline_pubkey); check_ready(&rpc_client); @@ -905,8 +897,9 @@ fn test_stake_split() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -925,16 +918,11 @@ fn test_stake_split() { config_offline.command = CliCommand::ClusterVersion; process_command(&config_offline).unwrap_err(); - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 500_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 500_000) + .unwrap(); check_recent_balance(500_000, &rpc_client, &config.signers[0].pubkey()); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &offline_pubkey); // Create stake account, identity is authority @@ -1048,8 +1036,9 @@ fn test_stake_set_lockup() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1068,16 +1057,11 @@ fn test_stake_set_lockup() { config_offline.command = CliCommand::ClusterVersion; process_command(&config_offline).unwrap_err(); - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 500_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 500_000) + .unwrap(); check_recent_balance(500_000, &rpc_client, &config.signers[0].pubkey()); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &offline_pubkey); // Create stake account, identity is authority @@ -1303,8 +1287,9 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1322,16 +1307,11 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { // Verify that we cannot reach the cluster process_command(&config_offline).unwrap_err(); - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 200_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 200_000) + .unwrap(); check_recent_balance(200_000, &rpc_client, &config.signers[0].pubkey()); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_pubkey, 100_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config_offline, &offline_pubkey, 100_000).unwrap(); check_recent_balance(100_000, &rpc_client, &offline_pubkey); // Create nonce account diff --git a/cli/tests/transfer.rs b/cli/tests/transfer.rs index c8341c0e90..1fdd341234 100644 --- a/cli/tests/transfer.rs +++ b/cli/tests/transfer.rs @@ -22,8 +22,9 @@ use solana_sdk::{ fn test_transfer() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -38,7 +39,7 @@ fn test_transfer() { let sender_pubkey = config.signers[0].pubkey(); let recipient_pubkey = Pubkey::new(&[1u8; 32]); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &sender_pubkey, 50_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &sender_pubkey, 50_000).unwrap(); check_recent_balance(50_000, &rpc_client, &sender_pubkey); check_recent_balance(0, &rpc_client, &recipient_pubkey); @@ -90,7 +91,7 @@ fn test_transfer() { process_command(&offline).unwrap_err(); let offline_pubkey = offline.signers[0].pubkey(); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_pubkey, 50).unwrap(); + request_and_confirm_airdrop(&rpc_client, &offline, &offline_pubkey, 50).unwrap(); check_recent_balance(50, &rpc_client, &offline_pubkey); // Offline transfer @@ -257,8 +258,9 @@ fn test_transfer() { fn test_transfer_multisession_signing() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let to_pubkey = Pubkey::new(&[1u8; 32]); let offline_from_signer = keypair_from_seed(&[2u8; 32]).unwrap(); @@ -268,11 +270,16 @@ fn test_transfer_multisession_signing() { // Setup accounts let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &offline_from_signer.pubkey(), 43) - .unwrap(); request_and_confirm_airdrop( &rpc_client, - &faucet_addr, + &CliConfig::recent_for_tests(), + &offline_from_signer.pubkey(), + 43, + ) + .unwrap(); + request_and_confirm_airdrop( + &rpc_client, + &CliConfig::recent_for_tests(), &offline_fee_payer_signer.pubkey(), 3, ) @@ -372,8 +379,9 @@ fn test_transfer_multisession_signing() { fn test_transfer_all() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -387,7 +395,7 @@ fn test_transfer_all() { let sender_pubkey = config.signers[0].pubkey(); let recipient_pubkey = Pubkey::new(&[1u8; 32]); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &sender_pubkey, 50_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &sender_pubkey, 50_000).unwrap(); check_recent_balance(50_000, &rpc_client, &sender_pubkey); check_recent_balance(0, &rpc_client, &recipient_pubkey); @@ -417,8 +425,9 @@ fn test_transfer_all() { fn test_transfer_with_seed() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(mint_keypair.pubkey(), 1); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_custom_fees(mint_pubkey, 1, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -440,8 +449,8 @@ fn test_transfer_with_seed() { ) .unwrap(); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &sender_pubkey, 1).unwrap(); - request_and_confirm_airdrop(&rpc_client, &faucet_addr, &derived_address, 50_000).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &sender_pubkey, 1).unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &derived_address, 50_000).unwrap(); check_recent_balance(1, &rpc_client, &sender_pubkey); check_recent_balance(50_000, &rpc_client, &derived_address); check_recent_balance(0, &rpc_client, &recipient_pubkey); diff --git a/cli/tests/vote.rs b/cli/tests/vote.rs index f6f6fa4643..887c5801df 100644 --- a/cli/tests/vote.rs +++ b/cli/tests/vote.rs @@ -19,8 +19,9 @@ use solana_vote_program::vote_state::{VoteAuthorize, VoteState, VoteStateVersion #[test] fn test_vote_authorize_and_withdraw() { let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); + let test_validator = TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr)); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -30,13 +31,8 @@ fn test_vote_authorize_and_withdraw() { config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; - request_and_confirm_airdrop( - &rpc_client, - &faucet_addr, - &config.signers[0].pubkey(), - 100_000, - ) - .unwrap(); + request_and_confirm_airdrop(&rpc_client, &config, &config.signers[0].pubkey(), 100_000) + .unwrap(); // Create vote account let vote_account_keypair = Keypair::new(); diff --git a/client/src/mock_sender.rs b/client/src/mock_sender.rs index da84ec88c3..359c0b59ed 100644 --- a/client/src/mock_sender.rs +++ b/client/src/mock_sender.rs @@ -122,6 +122,7 @@ impl RpcSender for MockSender { } RpcRequest::GetTransactionCount => Value::Number(Number::from(1234)), RpcRequest::GetSlot => Value::Number(Number::from(0)), + RpcRequest::RequestAirdrop => Value::String(Signature::new(&[8; 64]).to_string()), RpcRequest::SendTransaction => { let signature = if self.url == "malicious" { Signature::new(&[8; 64]).to_string() diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index cdbb344cd2..a2e95ea499 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -6,8 +6,8 @@ use crate::{ rpc_config::{ RpcConfirmedBlockConfig, RpcConfirmedTransactionConfig, RpcEpochConfig, RpcGetConfirmedSignaturesForAddress2Config, RpcLargestAccountsConfig, - RpcProgramAccountsConfig, RpcSendTransactionConfig, RpcSimulateTransactionConfig, - RpcTokenAccountsFilter, + RpcProgramAccountsConfig, RpcRequestAirdropConfig, RpcSendTransactionConfig, + RpcSimulateTransactionConfig, RpcTokenAccountsFilter, }, rpc_request::{RpcError, RpcRequest, RpcResponseErrorData, TokenAccountsFilter}, rpc_response::*, @@ -1344,6 +1344,64 @@ impl RpcClient { ) } + pub fn request_airdrop(&self, pubkey: &Pubkey, lamports: u64) -> ClientResult { + self.request_airdrop_with_config( + pubkey, + lamports, + RpcRequestAirdropConfig { + commitment: Some(self.commitment_config), + ..RpcRequestAirdropConfig::default() + }, + ) + } + + pub fn request_airdrop_with_blockhash( + &self, + pubkey: &Pubkey, + lamports: u64, + recent_blockhash: &Hash, + ) -> ClientResult { + self.request_airdrop_with_config( + pubkey, + lamports, + RpcRequestAirdropConfig { + commitment: Some(self.commitment_config), + recent_blockhash: Some(recent_blockhash.to_string()), + }, + ) + } + + pub fn request_airdrop_with_config( + &self, + pubkey: &Pubkey, + lamports: u64, + config: RpcRequestAirdropConfig, + ) -> ClientResult { + let commitment = config.commitment.unwrap_or_default(); + let commitment = self.maybe_map_commitment(commitment)?; + let config = RpcRequestAirdropConfig { + commitment: Some(commitment), + ..config + }; + self.send( + RpcRequest::RequestAirdrop, + json!([pubkey.to_string(), lamports, config]), + ) + .and_then(|signature: String| { + Signature::from_str(&signature).map_err(|err| { + ClientErrorKind::Custom(format!("signature deserialization failed: {}", err)).into() + }) + }) + .map_err(|_| { + RpcError::ForUser( + "airdrop request failed. \ + This can happen when the rate limit is reached." + .to_string(), + ) + .into() + }) + } + fn poll_balance_with_timeout_and_commitment( &self, pubkey: &Pubkey, @@ -1545,6 +1603,24 @@ impl RpcClient { commitment: CommitmentConfig, config: RpcSendTransactionConfig, ) -> ClientResult { + let recent_blockhash = if uses_durable_nonce(transaction).is_some() { + self.get_recent_blockhash_with_commitment(CommitmentConfig::processed())? + .value + .0 + } else { + transaction.message.recent_blockhash + }; + let signature = self.send_transaction_with_config(transaction, config)?; + self.confirm_transaction_with_spinner(&signature, &recent_blockhash, commitment)?; + Ok(signature) + } + + pub fn confirm_transaction_with_spinner( + &self, + signature: &Signature, + recent_blockhash: &Hash, + commitment: CommitmentConfig, + ) -> ClientResult<()> { let desired_confirmations = if commitment.is_finalized() { MAX_LOCKOUT_HISTORY + 1 } else { @@ -1556,16 +1632,8 @@ impl RpcClient { progress_bar.set_message(&format!( "[{}/{}] Finalizing transaction {}", - confirmations, desired_confirmations, transaction.signatures[0], + confirmations, desired_confirmations, signature, )); - let recent_blockhash = if uses_durable_nonce(transaction).is_some() { - self.get_recent_blockhash_with_commitment(CommitmentConfig::processed())? - .value - .0 - } else { - transaction.message.recent_blockhash - }; - let signature = self.send_transaction_with_config(transaction, config)?; let (signature, status) = loop { // Get recent commitment in order to count confirmations for successful transactions let status = self @@ -1612,7 +1680,7 @@ impl RpcClient { { progress_bar.set_message("Transaction confirmed"); progress_bar.finish_and_clear(); - return Ok(signature); + return Ok(()); } progress_bar.set_message(&format!( diff --git a/client/src/rpc_config.rs b/client/src/rpc_config.rs index e2e1d145a3..3a6b058eef 100644 --- a/client/src/rpc_config.rs +++ b/client/src/rpc_config.rs @@ -31,6 +31,14 @@ pub struct RpcSimulateTransactionConfig { pub encoding: Option, } +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcRequestAirdropConfig { + pub recent_blockhash: Option, // base-58 encoded blockhash + #[serde(flatten)] + pub commitment: Option, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum RpcLargestAccountsFilter { diff --git a/core/src/rpc.rs b/core/src/rpc.rs index ebfe759840..b85d696de4 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -1778,6 +1778,12 @@ fn verify_pubkey(input: String) -> Result { .map_err(|e| Error::invalid_params(format!("Invalid param: {:?}", e))) } +fn verify_hash(input: String) -> Result { + input + .parse() + .map_err(|e| Error::invalid_params(format!("Invalid param: {:?}", e))) +} + fn verify_signature(input: &str) -> Result { input .parse() @@ -2226,7 +2232,7 @@ pub trait RpcSol { meta: Self::Metadata, pubkey_str: String, lamports: u64, - commitment: Option, + config: Option, ) -> Result; #[rpc(meta, name = "sendTransaction")] @@ -2859,28 +2865,28 @@ impl RpcSol for RpcSolImpl { meta: Self::Metadata, pubkey_str: String, lamports: u64, - commitment: Option, + config: Option, ) -> Result { debug!("request_airdrop rpc request received"); trace!( - "request_airdrop id={} lamports={} commitment: {:?}", + "request_airdrop id={} lamports={} config: {:?}", pubkey_str, lamports, - &commitment + &config ); let faucet_addr = meta.config.faucet_addr.ok_or_else(Error::invalid_request)?; let pubkey = verify_pubkey(pubkey_str)?; - let (blockhash, last_valid_slot) = { - let bank = meta.bank(commitment); + let config = config.unwrap_or_default(); + let bank = meta.bank(config.commitment); - let blockhash = bank.confirmed_last_blockhash().0; - ( - blockhash, - bank.get_blockhash_last_valid_slot(&blockhash).unwrap_or(0), - ) + let blockhash = if let Some(blockhash) = config.recent_blockhash { + verify_hash(blockhash)? + } else { + bank.confirmed_last_blockhash().0 }; + let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap_or(0); let transaction = request_airdrop_transaction(&faucet_addr, &pubkey, lamports, blockhash) .map_err(|err| { diff --git a/core/src/test_validator.rs b/core/src/test_validator.rs index f75b4eabfe..4bbc97b9ea 100644 --- a/core/src/test_validator.rs +++ b/core/src/test_validator.rs @@ -80,6 +80,11 @@ impl TestValidatorGenesis { self } + pub fn faucet_addr(&mut self, faucet_addr: Option) -> &mut Self { + self.rpc_config.faucet_addr = faucet_addr; + self + } + pub fn warp_slot(&mut self, warp_slot: Slot) -> &mut Self { self.warp_slot = Some(warp_slot); self @@ -229,9 +234,10 @@ pub struct TestValidator { impl TestValidator { /// Create and start a `TestValidator` with no transaction fees and minimal rent. + /// Faucet optional. /// /// This function panics on initialization failure. - pub fn with_no_fees(mint_address: Pubkey) -> Self { + pub fn with_no_fees(mint_address: Pubkey, faucet_addr: Option) -> Self { TestValidatorGenesis::default() .fee_rate_governor(FeeRateGovernor::new(0, 0)) .rent(Rent { @@ -239,14 +245,20 @@ impl TestValidator { exemption_threshold: 1.0, ..Rent::default() }) + .faucet_addr(faucet_addr) .start_with_mint_address(mint_address) .expect("validator start failed") } /// Create and start a `TestValidator` with custom transaction fees and minimal rent. + /// Faucet optional. /// /// This function panics on initialization failure. - pub fn with_custom_fees(mint_address: Pubkey, target_lamports_per_signature: u64) -> Self { + pub fn with_custom_fees( + mint_address: Pubkey, + target_lamports_per_signature: u64, + faucet_addr: Option, + ) -> Self { TestValidatorGenesis::default() .fee_rate_governor(FeeRateGovernor::new(target_lamports_per_signature, 0)) .rent(Rent { @@ -254,6 +266,7 @@ impl TestValidator { exemption_threshold: 1.0, ..Rent::default() }) + .faucet_addr(faucet_addr) .start_with_mint_address(mint_address) .expect("validator start failed") } diff --git a/core/tests/client.rs b/core/tests/client.rs index 33c7b88097..7350647513 100644 --- a/core/tests/client.rs +++ b/core/tests/client.rs @@ -34,7 +34,7 @@ fn test_rpc_client() { solana_logger::setup(); let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let bob_pubkey = solana_sdk::pubkey::new_rand(); diff --git a/core/tests/rpc.rs b/core/tests/rpc.rs index 8feae26981..5c8eaa849f 100644 --- a/core/tests/rpc.rs +++ b/core/tests/rpc.rs @@ -57,7 +57,7 @@ fn test_rpc_send_tx() { solana_logger::setup(); let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let rpc_url = test_validator.rpc_url(); let bob_pubkey = solana_sdk::pubkey::new_rand(); @@ -117,7 +117,7 @@ fn test_rpc_invalid_requests() { solana_logger::setup(); let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let rpc_url = test_validator.rpc_url(); let bob_pubkey = solana_sdk::pubkey::new_rand(); @@ -148,7 +148,7 @@ fn test_rpc_invalid_requests() { fn test_rpc_slot_updates() { solana_logger::setup(); - let test_validator = TestValidator::with_no_fees(Pubkey::new_unique()); + let test_validator = TestValidator::with_no_fees(Pubkey::new_unique(), None); // Create the pub sub runtime let mut rt = Runtime::new().unwrap(); @@ -224,7 +224,7 @@ fn test_rpc_subscriptions() { solana_logger::setup(); let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); transactions_socket.connect(test_validator.tpu()).unwrap(); diff --git a/tokens/src/commands.rs b/tokens/src/commands.rs index 2abc8a8ce8..40443297ad 100644 --- a/tokens/src/commands.rs +++ b/tokens/src/commands.rs @@ -1046,7 +1046,7 @@ mod tests { #[test] fn test_process_token_allocations() { let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1056,7 +1056,7 @@ mod tests { #[test] fn test_process_transfer_amount_allocations() { let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1066,7 +1066,7 @@ mod tests { #[test] fn test_process_stake_allocations() { let alice = Keypair::new(); - let test_validator = TestValidator::with_no_fees(alice.pubkey()); + let test_validator = TestValidator::with_no_fees(alice.pubkey(), None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1381,7 +1381,7 @@ mod tests { let fees_in_sol = lamports_to_sol(fees); let alice = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees); + let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees, None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1464,7 +1464,7 @@ mod tests { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); let alice = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees); + let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees, None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1574,7 +1574,7 @@ mod tests { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); let alice = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees); + let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees, None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1683,7 +1683,7 @@ mod tests { let fees = 10_000; let fees_in_sol = lamports_to_sol(fees); let alice = Keypair::new(); - let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees); + let test_validator = TestValidator::with_custom_fees(alice.pubkey(), fees, None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); @@ -1998,7 +1998,7 @@ mod tests { #[test] fn test_distribute_allocations_dump_db() { let sender_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(sender_keypair.pubkey()); + let test_validator = TestValidator::with_no_fees(sender_keypair.pubkey(), None); let url = test_validator.rpc_url(); let client = RpcClient::new_with_commitment(url, CommitmentConfig::processed()); diff --git a/tokens/tests/commands.rs b/tokens/tests/commands.rs index f0425497e9..67666f84ad 100644 --- a/tokens/tests/commands.rs +++ b/tokens/tests/commands.rs @@ -8,7 +8,7 @@ fn test_process_distribute_with_rpc_client() { solana_logger::setup(); let mint_keypair = Keypair::new(); - let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey()); + let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey(), None); let client = RpcClient::new(test_validator.rpc_url()); test_process_distribute_tokens_with_client(&client, mint_keypair, None);