Cli: move airdrop to rpc requests (#16557)
* 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 <mvines@gmail.com> Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
parent
76ce28c723
commit
7dfb51c0b4
142
cli/src/cli.rs
142
cli/src/cli.rs
|
@ -33,11 +33,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},
|
||||
|
@ -59,19 +54,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";
|
||||
|
||||
|
@ -361,8 +347,6 @@ pub enum CliCommand {
|
|||
// Wallet Commands
|
||||
Address,
|
||||
Airdrop {
|
||||
faucet_host: Option<IpAddr>,
|
||||
faucet_port: u16,
|
||||
pubkey: Option<Pubkey>,
|
||||
lamports: u64,
|
||||
},
|
||||
|
@ -784,20 +768,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![]
|
||||
|
@ -806,12 +776,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,
|
||||
})
|
||||
}
|
||||
|
@ -1008,7 +973,6 @@ fn process_create_address_with_seed(
|
|||
fn process_airdrop(
|
||||
rpc_client: &RpcClient,
|
||||
config: &CliConfig,
|
||||
faucet_addr: &SocketAddr,
|
||||
pubkey: &Option<Pubkey>,
|
||||
lamports: u64,
|
||||
) -> ProcessResult {
|
||||
|
@ -1018,14 +982,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::<SystemError>(result, &config)?;
|
||||
println!("{}", signature_cli_message);
|
||||
|
@ -1877,27 +1840,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 {
|
||||
|
@ -1963,67 +1907,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<Self, FaucetError> {
|
||||
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<Pubkey, SignerError> {
|
||||
Ok(self.pubkey())
|
||||
}
|
||||
|
||||
fn sign_message(&self, _msg: &[u8]) -> Signature {
|
||||
self.transaction.signatures[0]
|
||||
}
|
||||
|
||||
fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
|
||||
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<Signature> {
|
||||
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<E>(
|
||||
|
@ -2493,8 +2391,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,
|
||||
},
|
||||
|
@ -2880,8 +2776,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,
|
||||
};
|
||||
|
@ -2906,8 +2800,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,
|
||||
};
|
||||
|
|
|
@ -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<String>,
|
||||
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,
|
||||
)
|
||||
|
@ -220,9 +214,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();
|
||||
|
@ -233,14 +227,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,
|
||||
)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
@ -104,8 +103,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
|
||||
};
|
||||
|
@ -147,8 +144,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());
|
||||
|
@ -171,8 +169,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,
|
||||
};
|
||||
|
@ -231,8 +227,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());
|
||||
|
@ -256,8 +253,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,
|
||||
};
|
||||
|
@ -560,8 +555,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());
|
||||
|
@ -586,8 +582,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,
|
||||
};
|
||||
|
@ -843,8 +837,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());
|
||||
|
@ -864,8 +859,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,
|
||||
};
|
||||
|
@ -957,8 +950,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());
|
||||
|
@ -978,8 +972,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,
|
||||
};
|
||||
|
@ -1047,8 +1039,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());
|
||||
|
@ -1071,8 +1064,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,
|
||||
};
|
||||
|
@ -1228,8 +1219,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());
|
||||
|
@ -1252,8 +1244,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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
@ -119,8 +115,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());
|
||||
|
@ -132,7 +129,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,
|
||||
)
|
||||
|
@ -202,8 +199,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());
|
||||
|
@ -217,7 +215,7 @@ fn test_stake_delegation_and_deactivation() {
|
|||
|
||||
request_and_confirm_airdrop(
|
||||
&rpc_client,
|
||||
&faucet_addr,
|
||||
&config_validator,
|
||||
&config_validator.signers[0].pubkey(),
|
||||
100_000,
|
||||
)
|
||||
|
@ -281,8 +279,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());
|
||||
|
@ -307,7 +306,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,
|
||||
)
|
||||
|
@ -316,7 +315,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,
|
||||
)
|
||||
|
@ -420,8 +419,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());
|
||||
|
@ -435,13 +435,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();
|
||||
|
@ -539,8 +534,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());
|
||||
|
@ -550,13 +546,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();
|
||||
|
@ -569,7 +560,7 @@ fn test_stake_authorize() {
|
|||
|
||||
request_and_confirm_airdrop(
|
||||
&rpc_client,
|
||||
&faucet_addr,
|
||||
&config_offline,
|
||||
&config_offline.signers[0].pubkey(),
|
||||
100_000,
|
||||
)
|
||||
|
@ -809,8 +800,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());
|
||||
|
@ -836,13 +828,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);
|
||||
|
@ -937,8 +929,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());
|
||||
|
@ -957,16 +950,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
|
||||
|
@ -1084,8 +1072,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());
|
||||
|
@ -1104,16 +1093,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
|
||||
|
@ -1347,8 +1331,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());
|
||||
|
@ -1366,16 +1351,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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -94,7 +95,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
|
||||
|
@ -273,8 +274,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();
|
||||
|
@ -284,11 +286,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,
|
||||
)
|
||||
|
@ -394,8 +401,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());
|
||||
|
@ -409,7 +417,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);
|
||||
|
||||
|
@ -441,8 +449,9 @@ fn test_transfer_all() {
|
|||
fn test_transfer_unfunded_recipient() {
|
||||
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());
|
||||
|
@ -456,7 +465,7 @@ fn test_transfer_unfunded_recipient() {
|
|||
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);
|
||||
|
||||
|
@ -488,8 +497,9 @@ fn test_transfer_unfunded_recipient() {
|
|||
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());
|
||||
|
@ -511,8 +521,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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -124,6 +124,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()
|
||||
|
|
|
@ -7,8 +7,8 @@ use {
|
|||
rpc_config::{
|
||||
RpcConfirmedBlockConfig, RpcConfirmedTransactionConfig, RpcEpochConfig,
|
||||
RpcGetConfirmedSignaturesForAddress2Config, RpcLargestAccountsConfig,
|
||||
RpcProgramAccountsConfig, RpcSendTransactionConfig, RpcSimulateTransactionConfig,
|
||||
RpcTokenAccountsFilter,
|
||||
RpcProgramAccountsConfig, RpcRequestAirdropConfig, RpcSendTransactionConfig,
|
||||
RpcSimulateTransactionConfig, RpcTokenAccountsFilter,
|
||||
},
|
||||
rpc_request::{RpcError, RpcRequest, RpcResponseErrorData, TokenAccountsFilter},
|
||||
rpc_response::*,
|
||||
|
@ -1356,6 +1356,64 @@ impl RpcClient {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn request_airdrop(&self, pubkey: &Pubkey, lamports: u64) -> ClientResult<Signature> {
|
||||
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<Signature> {
|
||||
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<Signature> {
|
||||
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,
|
||||
|
@ -1557,6 +1615,24 @@ impl RpcClient {
|
|||
commitment: CommitmentConfig,
|
||||
config: RpcSendTransactionConfig,
|
||||
) -> ClientResult<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)?;
|
||||
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 {
|
||||
|
@ -1568,16 +1644,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
|
||||
|
@ -1624,7 +1692,7 @@ impl RpcClient {
|
|||
{
|
||||
progress_bar.set_message("Transaction confirmed");
|
||||
progress_bar.finish_and_clear();
|
||||
return Ok(signature);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
progress_bar.set_message(&format!(
|
||||
|
|
|
@ -33,6 +33,14 @@ pub struct RpcSimulateTransactionConfig {
|
|||
pub encoding: Option<UiTransactionEncoding>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RpcRequestAirdropConfig {
|
||||
pub recent_blockhash: Option<String>, // base-58 encoded blockhash
|
||||
#[serde(flatten)]
|
||||
pub commitment: Option<CommitmentConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum RpcLargestAccountsFilter {
|
||||
|
|
|
@ -1754,6 +1754,12 @@ fn verify_pubkey(input: String) -> Result<Pubkey> {
|
|||
.map_err(|e| Error::invalid_params(format!("Invalid param: {:?}", e)))
|
||||
}
|
||||
|
||||
fn verify_hash(input: String) -> Result<Hash> {
|
||||
input
|
||||
.parse()
|
||||
.map_err(|e| Error::invalid_params(format!("Invalid param: {:?}", e)))
|
||||
}
|
||||
|
||||
fn verify_signature(input: &str) -> Result<Signature> {
|
||||
input
|
||||
.parse()
|
||||
|
@ -2355,7 +2361,7 @@ pub mod rpc_full {
|
|||
meta: Self::Metadata,
|
||||
pubkey_str: String,
|
||||
lamports: u64,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcRequestAirdropConfig>,
|
||||
) -> Result<String>;
|
||||
|
||||
#[rpc(meta, name = "sendTransaction")]
|
||||
|
@ -2786,28 +2792,28 @@ pub mod rpc_full {
|
|||
meta: Self::Metadata,
|
||||
pubkey_str: String,
|
||||
lamports: u64,
|
||||
commitment: Option<CommitmentConfig>,
|
||||
config: Option<RpcRequestAirdropConfig>,
|
||||
) -> Result<String> {
|
||||
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(
|
||||
|
|
|
@ -95,6 +95,11 @@ impl TestValidatorGenesis {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn faucet_addr(&mut self, faucet_addr: Option<SocketAddr>) -> &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
|
||||
|
@ -244,9 +249,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<SocketAddr>) -> Self {
|
||||
TestValidatorGenesis::default()
|
||||
.fee_rate_governor(FeeRateGovernor::new(0, 0))
|
||||
.rent(Rent {
|
||||
|
@ -254,14 +260,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<SocketAddr>,
|
||||
) -> Self {
|
||||
TestValidatorGenesis::default()
|
||||
.fee_rate_governor(FeeRateGovernor::new(target_lamports_per_signature, 0))
|
||||
.rent(Rent {
|
||||
|
@ -269,6 +281,7 @@ impl TestValidator {
|
|||
exemption_threshold: 1.0,
|
||||
..Rent::default()
|
||||
})
|
||||
.faucet_addr(faucet_addr)
|
||||
.start_with_mint_address(mint_address)
|
||||
.expect("validator start failed")
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -55,7 +55,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();
|
||||
|
@ -119,7 +119,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();
|
||||
|
@ -150,7 +150,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 rt = Runtime::new().unwrap();
|
||||
|
@ -215,7 +215,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();
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue