Add staking commands to wallet
This commit is contained in:
parent
01fb76f4bd
commit
a4a3995a84
|
@ -2407,6 +2407,7 @@ dependencies = [
|
|||
"solana-drone 0.12.0",
|
||||
"solana-logger 0.12.0",
|
||||
"solana-sdk 0.12.0",
|
||||
"solana-vote-api 0.12.0",
|
||||
"solana-vote-signer 0.12.0",
|
||||
]
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ solana-budget-api = { path = "../programs/budget_api", version = "0.12.0" }
|
|||
solana-drone = { path = "../drone", version = "0.12.0" }
|
||||
solana-logger = { path = "../logger", version = "0.12.0" }
|
||||
solana-sdk = { path = "../sdk", version = "0.12.0" }
|
||||
solana-vote-api = { path = "../programs/vote_api", version = "0.12.0" }
|
||||
solana-vote-signer = { path = "../vote-signer", version = "0.12.0" }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use clap::{crate_version, App, Arg, ArgMatches, SubCommand};
|
||||
use clap::{crate_version, App, Arg, ArgGroup, ArgMatches, SubCommand};
|
||||
use solana_sdk::signature::{gen_keypair_file, read_keypair, KeypairUtil};
|
||||
use solana_wallet::wallet::{parse_command, process_command, WalletConfig, WalletError};
|
||||
use std::error;
|
||||
|
@ -180,6 +180,50 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
|||
.help("The transaction signature to confirm"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("configure-staking-account")
|
||||
.about("Configure staking account for node")
|
||||
.group(
|
||||
ArgGroup::with_name("options")
|
||||
.args(&["delegate", "authorized_voter"])
|
||||
.multiple(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("delegate")
|
||||
.long("delegate-account")
|
||||
.value_name("PUBKEY")
|
||||
.takes_value(true)
|
||||
.help("Address to delegate this vote account to"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("authorized_voter")
|
||||
.long("authorize-voter")
|
||||
.value_name("PUBKEY")
|
||||
.takes_value(true)
|
||||
.help("Vote signer to authorize"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("create-staking-account")
|
||||
.about("Create staking account for node")
|
||||
.arg(
|
||||
Arg::with_name("voting_account_id")
|
||||
.index(1)
|
||||
.value_name("PUBKEY")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("Staking account address to fund"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("lamports")
|
||||
.index(2)
|
||||
.value_name("NUM")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.help("The number of lamports to send to staking account"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("deploy")
|
||||
.about("Deploy a program")
|
||||
|
|
|
@ -25,6 +25,9 @@ use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
|
|||
use solana_sdk::system_transaction::SystemTransaction;
|
||||
use solana_sdk::timing::{DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND};
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use solana_sdk::transaction_builder::TransactionBuilder;
|
||||
use solana_vote_api::vote_instruction::VoteInstruction;
|
||||
use solana_vote_api::vote_transaction::VoteTransaction;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
|
@ -42,6 +45,9 @@ pub enum WalletCommand {
|
|||
Balance,
|
||||
Cancel(Pubkey),
|
||||
Confirm(Signature),
|
||||
// ConfigureStakingAccount(delegate_id, authorized_voter_id)
|
||||
ConfigureStakingAccount(Option<Pubkey>, Option<Pubkey>),
|
||||
CreateStakingAccount(Pubkey, u64),
|
||||
Deploy(String),
|
||||
GetTransactionCount,
|
||||
// Pay(lamports, to, timestamp, timestamp_pubkey, witness(es), cancelable)
|
||||
|
@ -161,6 +167,48 @@ pub fn parse_command(
|
|||
Err(WalletError::BadParameter("Invalid signature".to_string()))
|
||||
}
|
||||
}
|
||||
("configure-staking-account", Some(staking_config_matches)) => {
|
||||
let delegate_id = staking_config_matches
|
||||
.value_of("delegate")
|
||||
.map(|pubkey_string| {
|
||||
let pubkey_vec = bs58::decode(pubkey_string)
|
||||
.into_vec()
|
||||
.expect("base58-encoded public key");
|
||||
// TODO: Add valid pubkey check
|
||||
Pubkey::new(&pubkey_vec)
|
||||
});
|
||||
let authorized_voter_id =
|
||||
staking_config_matches
|
||||
.value_of("authorize-voter")
|
||||
.map(|pubkey_string| {
|
||||
let pubkey_vec = bs58::decode(pubkey_string)
|
||||
.into_vec()
|
||||
.expect("base58-encoded public key");
|
||||
// TODO: Add valid pubkey check
|
||||
Pubkey::new(&pubkey_vec)
|
||||
});
|
||||
Ok(WalletCommand::ConfigureStakingAccount(
|
||||
delegate_id,
|
||||
authorized_voter_id,
|
||||
))
|
||||
}
|
||||
("create-staking-account", Some(staking_matches)) => {
|
||||
let voting_account_string = staking_matches.value_of("voting_account_id").unwrap();
|
||||
let voting_account_vec = bs58::decode(voting_account_string)
|
||||
.into_vec()
|
||||
.expect("base58-encoded public key");
|
||||
|
||||
if voting_account_vec.len() != mem::size_of::<Pubkey>() {
|
||||
eprintln!("{}", staking_matches.usage());
|
||||
Err(WalletError::BadParameter("Invalid public key".to_string()))?;
|
||||
}
|
||||
let voting_account_id = Pubkey::new(&voting_account_vec);
|
||||
let lamports = staking_matches.value_of("lamports").unwrap().parse()?;
|
||||
Ok(WalletCommand::CreateStakingAccount(
|
||||
voting_account_id,
|
||||
lamports,
|
||||
))
|
||||
}
|
||||
("deploy", Some(deploy_matches)) => Ok(WalletCommand::Deploy(
|
||||
deploy_matches
|
||||
.value_of("program-location")
|
||||
|
@ -387,6 +435,44 @@ fn process_confirm(rpc_client: &RpcClient, signature: Signature) -> ProcessResul
|
|||
}
|
||||
}
|
||||
|
||||
fn process_configure_staking(
|
||||
rpc_client: &RpcClient,
|
||||
config: &WalletConfig,
|
||||
delegate_option: Option<Pubkey>,
|
||||
authorized_voter_option: Option<Pubkey>,
|
||||
) -> ProcessResult {
|
||||
let recent_blockhash = get_recent_blockhash(&rpc_client)?;
|
||||
let mut tx = TransactionBuilder::new(0);
|
||||
if let Some(delegate_id) = delegate_option {
|
||||
tx.push(VoteInstruction::new_delegate_stake(
|
||||
config.id.pubkey(),
|
||||
delegate_id,
|
||||
));
|
||||
}
|
||||
if let Some(authorized_voter_id) = authorized_voter_option {
|
||||
tx.push(VoteInstruction::new_authorize_voter(
|
||||
config.id.pubkey(),
|
||||
authorized_voter_id,
|
||||
));
|
||||
}
|
||||
let mut tx = tx.sign(&[&config.id], recent_blockhash);
|
||||
let signature_str = send_and_confirm_transaction(&rpc_client, &mut tx, &config.id)?;
|
||||
Ok(signature_str.to_string())
|
||||
}
|
||||
|
||||
fn process_create_staking(
|
||||
rpc_client: &RpcClient,
|
||||
config: &WalletConfig,
|
||||
voting_account_id: Pubkey,
|
||||
lamports: u64,
|
||||
) -> ProcessResult {
|
||||
let recent_blockhash = get_recent_blockhash(&rpc_client)?;
|
||||
let mut tx =
|
||||
VoteTransaction::new_account(&config.id, voting_account_id, recent_blockhash, lamports, 0);
|
||||
let signature_str = send_and_confirm_transaction(&rpc_client, &mut tx, &config.id)?;
|
||||
Ok(signature_str.to_string())
|
||||
}
|
||||
|
||||
fn process_deploy(
|
||||
rpc_client: &RpcClient,
|
||||
config: &WalletConfig,
|
||||
|
@ -683,6 +769,21 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
|||
// Confirm the last client transaction by signature
|
||||
WalletCommand::Confirm(signature) => process_confirm(&rpc_client, signature),
|
||||
|
||||
// Configure staking account already created
|
||||
WalletCommand::ConfigureStakingAccount(delegate_option, authorized_voter_option) => {
|
||||
process_configure_staking(
|
||||
&rpc_client,
|
||||
config,
|
||||
delegate_option,
|
||||
authorized_voter_option,
|
||||
)
|
||||
}
|
||||
|
||||
// Create staking account
|
||||
WalletCommand::CreateStakingAccount(voting_account_id, lamports) => {
|
||||
process_create_staking(&rpc_client, config, voting_account_id, lamports)
|
||||
}
|
||||
|
||||
// Deploy a custom program to the chain
|
||||
WalletCommand::Deploy(ref program_location) => {
|
||||
process_deploy(&rpc_client, config, program_location)
|
||||
|
|
Loading…
Reference in New Issue