Cli: transfer ALL; check spend+fee in client (#10012)
* lamports->SOL in user-facing error msg * Check for sufficient balance for spend and fee * Add ALL option to solana transfer * Rework TransferAmount to check for sign_only in parse * Refactor TransferAmount & fee-check handling to be more general * Add addl checks mechanism * Move checks out of cli.rs * Rename to SpendAmount to be more general & move * Impl ALL/spend helpers for create-nonce-account * Impl spend helpers for create-vote-account * Impl ALL/spend helpers for create-stake-account * Impl spend helpers for ping * Impl ALL/spend helpers for pay * Impl spend helpers for validator-info * Remove unused fns * Remove retry_get_balance * Add a couple unit tests * Rework send_util fn signatures
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
cli::{check_account_for_fee, CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult},
|
||||
cli::{CliCommand, CliCommandInfo, CliConfig, CliError, ProcessResult},
|
||||
cli_output::{CliValidatorInfo, CliValidatorInfoVec},
|
||||
spend_utils::{resolve_spend_tx_and_check_account_balance, SpendAmount},
|
||||
};
|
||||
use bincode::deserialize;
|
||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||
@@ -310,8 +311,10 @@ pub fn process_set_validator_info(
|
||||
.poll_get_balance_with_commitment(&info_pubkey, CommitmentConfig::default())
|
||||
.unwrap_or(0);
|
||||
|
||||
let keys = vec![(id(), false), (config.signers[0].pubkey(), true)];
|
||||
let (message, signers): (Message, Vec<&dyn Signer>) = if balance == 0 {
|
||||
let lamports =
|
||||
rpc_client.get_minimum_balance_for_rent_exemption(ValidatorInfo::max_space() as usize)?;
|
||||
|
||||
let signers = if balance == 0 {
|
||||
if info_pubkey != info_keypair.pubkey() {
|
||||
println!(
|
||||
"Account {:?} does not exist. Generating new keypair...",
|
||||
@@ -319,54 +322,59 @@ pub fn process_set_validator_info(
|
||||
);
|
||||
info_pubkey = info_keypair.pubkey();
|
||||
}
|
||||
println!(
|
||||
"Publishing info for Validator {:?}",
|
||||
config.signers[0].pubkey()
|
||||
);
|
||||
let lamports = rpc_client
|
||||
.get_minimum_balance_for_rent_exemption(ValidatorInfo::max_space() as usize)?;
|
||||
let mut instructions = config_instruction::create_account::<ValidatorInfo>(
|
||||
&config.signers[0].pubkey(),
|
||||
&info_keypair.pubkey(),
|
||||
lamports,
|
||||
keys.clone(),
|
||||
);
|
||||
instructions.extend_from_slice(&[config_instruction::store(
|
||||
&info_keypair.pubkey(),
|
||||
true,
|
||||
keys,
|
||||
&validator_info,
|
||||
)]);
|
||||
let signers = vec![config.signers[0], &info_keypair];
|
||||
let message = Message::new(&instructions);
|
||||
(message, signers)
|
||||
vec![config.signers[0], &info_keypair]
|
||||
} else {
|
||||
println!(
|
||||
"Updating Validator {:?} info at: {:?}",
|
||||
config.signers[0].pubkey(),
|
||||
info_pubkey
|
||||
);
|
||||
let instructions = vec![config_instruction::store(
|
||||
&info_pubkey,
|
||||
false,
|
||||
keys,
|
||||
&validator_info,
|
||||
)];
|
||||
let message = Message::new_with_payer(&instructions, Some(&config.signers[0].pubkey()));
|
||||
let signers = vec![config.signers[0]];
|
||||
(message, signers)
|
||||
vec![config.signers[0]]
|
||||
};
|
||||
|
||||
let build_message = |lamports| {
|
||||
let keys = vec![(id(), false), (config.signers[0].pubkey(), true)];
|
||||
if balance == 0 {
|
||||
println!(
|
||||
"Publishing info for Validator {:?}",
|
||||
config.signers[0].pubkey()
|
||||
);
|
||||
let mut instructions = config_instruction::create_account::<ValidatorInfo>(
|
||||
&config.signers[0].pubkey(),
|
||||
&info_pubkey,
|
||||
lamports,
|
||||
keys.clone(),
|
||||
);
|
||||
instructions.extend_from_slice(&[config_instruction::store(
|
||||
&info_pubkey,
|
||||
true,
|
||||
keys,
|
||||
&validator_info,
|
||||
)]);
|
||||
Message::new(&instructions)
|
||||
} else {
|
||||
println!(
|
||||
"Updating Validator {:?} info at: {:?}",
|
||||
config.signers[0].pubkey(),
|
||||
info_pubkey
|
||||
);
|
||||
let instructions = vec![config_instruction::store(
|
||||
&info_pubkey,
|
||||
false,
|
||||
keys,
|
||||
&validator_info,
|
||||
)];
|
||||
Message::new_with_payer(&instructions, Some(&config.signers[0].pubkey()))
|
||||
}
|
||||
};
|
||||
|
||||
// Submit transaction
|
||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||
let (message, _) = resolve_spend_tx_and_check_account_balance(
|
||||
rpc_client,
|
||||
false,
|
||||
SpendAmount::Some(lamports),
|
||||
&fee_calculator,
|
||||
&config.signers[0].pubkey(),
|
||||
build_message,
|
||||
)?;
|
||||
let mut tx = Transaction::new_unsigned(message);
|
||||
tx.try_sign(&signers, recent_blockhash)?;
|
||||
check_account_for_fee(
|
||||
rpc_client,
|
||||
&config.signers[0].pubkey(),
|
||||
&fee_calculator,
|
||||
&tx.message,
|
||||
)?;
|
||||
let signature_str = rpc_client.send_and_confirm_transaction_with_spinner(&tx)?;
|
||||
|
||||
println!("Success! Validator info published at: {:?}", info_pubkey);
|
||||
|
Reference in New Issue
Block a user