Add set-lockup to solana-stake-accounts (#9827)
* Add a command to set lockups or authorize a new custodian on derived stake accounts * Thanks clippy
This commit is contained in:
parent
7678af6300
commit
450f1d2867
|
@ -77,6 +77,18 @@ impl StakeState {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lockup_from(account: &Account) -> Option<Lockup> {
|
||||||
|
Self::from(account).and_then(|state: Self| state.lockup())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lockup(&self) -> Option<Lockup> {
|
||||||
|
match self {
|
||||||
|
StakeState::Stake(meta, _stake) => Some(meta.lockup),
|
||||||
|
StakeState::Initialized(meta) => Some(meta.lockup),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
use crate::args::{
|
use crate::args::{
|
||||||
Args, AuthorizeArgs, Command, CountArgs, MoveArgs, NewArgs, QueryArgs, RebaseArgs,
|
Args, AuthorizeArgs, Command, CountArgs, MoveArgs, NewArgs, QueryArgs, RebaseArgs,
|
||||||
|
SetLockupArgs,
|
||||||
|
};
|
||||||
|
use clap::{value_t, value_t_or_exit, App, Arg, ArgMatches, SubCommand};
|
||||||
|
use solana_clap_utils::{
|
||||||
|
input_parsers::unix_timestamp_from_rfc3339_datetime,
|
||||||
|
input_validators::{is_amount, is_rfc3339_datetime, is_valid_pubkey, is_valid_signer},
|
||||||
};
|
};
|
||||||
use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand};
|
|
||||||
use solana_clap_utils::input_validators::{is_amount, is_valid_pubkey, is_valid_signer};
|
|
||||||
use solana_cli_config::CONFIG_FILE;
|
use solana_cli_config::CONFIG_FILE;
|
||||||
use solana_sdk::native_token::sol_to_lamports;
|
use solana_sdk::native_token::sol_to_lamports;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
@ -36,6 +40,23 @@ fn base_pubkey_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
.help("Public key which stake account addresses are derived from")
|
.help("Public key which stake account addresses are derived from")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn custodian_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name("custodian")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("KEYPAIR")
|
||||||
|
.validator(is_valid_signer)
|
||||||
|
.help("Authority to modify lockups")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_custodian_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name("new_custodian")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("PUBKEY")
|
||||||
|
.validator(is_valid_pubkey)
|
||||||
|
.help("New authority to modify lockups")
|
||||||
|
}
|
||||||
|
|
||||||
fn new_base_keypair_arg<'a, 'b>() -> Arg<'a, 'b> {
|
fn new_base_keypair_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
Arg::with_name("new_base_keypair")
|
Arg::with_name("new_base_keypair")
|
||||||
.required(true)
|
.required(true)
|
||||||
|
@ -85,6 +106,23 @@ fn new_withdraw_authority_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
.help("New withdraw authority")
|
.help("New withdraw authority")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lockup_epoch_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name("lockup_epoch")
|
||||||
|
.long("lockup-epoch")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("NUMBER")
|
||||||
|
.help("The epoch height at which each account will be available for withdrawl")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lockup_date_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
|
Arg::with_name("lockup_date")
|
||||||
|
.long("lockup-date")
|
||||||
|
.value_name("RFC3339 DATETIME")
|
||||||
|
.validator(is_rfc3339_datetime)
|
||||||
|
.takes_value(true)
|
||||||
|
.help("The date and time at which each account will be available for withdrawl")
|
||||||
|
}
|
||||||
|
|
||||||
fn num_accounts_arg<'a, 'b>() -> Arg<'a, 'b> {
|
fn num_accounts_arg<'a, 'b>() -> Arg<'a, 'b> {
|
||||||
Arg::with_name("num_accounts")
|
Arg::with_name("num_accounts")
|
||||||
.long("num-accounts")
|
.long("num-accounts")
|
||||||
|
@ -197,6 +235,17 @@ where
|
||||||
.arg(new_withdraw_authority_arg())
|
.arg(new_withdraw_authority_arg())
|
||||||
.arg(num_accounts_arg()),
|
.arg(num_accounts_arg()),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("set-lockup")
|
||||||
|
.about("Set new lockups in all derived stake accounts")
|
||||||
|
.arg(fee_payer_arg())
|
||||||
|
.arg(base_pubkey_arg().index(1))
|
||||||
|
.arg(custodian_arg())
|
||||||
|
.arg(lockup_epoch_arg())
|
||||||
|
.arg(lockup_date_arg())
|
||||||
|
.arg(new_custodian_arg())
|
||||||
|
.arg(num_accounts_arg()),
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("rebase")
|
SubCommand::with_name("rebase")
|
||||||
.about("Relocate derived stake accounts")
|
.about("Relocate derived stake accounts")
|
||||||
|
@ -258,6 +307,18 @@ fn parse_authorize_args(matches: &ArgMatches<'_>) -> AuthorizeArgs<String, Strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_set_lockup_args(matches: &ArgMatches<'_>) -> SetLockupArgs<String, String> {
|
||||||
|
SetLockupArgs {
|
||||||
|
fee_payer: value_t_or_exit!(matches, "fee_payer", String),
|
||||||
|
base_pubkey: value_t_or_exit!(matches, "base_pubkey", String),
|
||||||
|
custodian: value_t_or_exit!(matches, "custodian", String),
|
||||||
|
lockup_epoch: value_t!(matches, "lockup_epoch", u64).ok(),
|
||||||
|
lockup_date: unix_timestamp_from_rfc3339_datetime(matches, "lockup_date"),
|
||||||
|
new_custodian: value_t!(matches, "new_custodian", String).ok(),
|
||||||
|
num_accounts: value_t_or_exit!(matches, "num_accounts", usize),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_rebase_args(matches: &ArgMatches<'_>) -> RebaseArgs<String, String> {
|
fn parse_rebase_args(matches: &ArgMatches<'_>) -> RebaseArgs<String, String> {
|
||||||
RebaseArgs {
|
RebaseArgs {
|
||||||
fee_payer: value_t_or_exit!(matches, "fee_payer", String),
|
fee_payer: value_t_or_exit!(matches, "fee_payer", String),
|
||||||
|
@ -290,6 +351,7 @@ where
|
||||||
("addresses", Some(matches)) => Command::Addresses(parse_query_args(matches)),
|
("addresses", Some(matches)) => Command::Addresses(parse_query_args(matches)),
|
||||||
("balance", Some(matches)) => Command::Balance(parse_query_args(matches)),
|
("balance", Some(matches)) => Command::Balance(parse_query_args(matches)),
|
||||||
("authorize", Some(matches)) => Command::Authorize(parse_authorize_args(matches)),
|
("authorize", Some(matches)) => Command::Authorize(parse_authorize_args(matches)),
|
||||||
|
("set-lockup", Some(matches)) => Command::SetLockup(parse_set_lockup_args(matches)),
|
||||||
("rebase", Some(matches)) => Command::Rebase(parse_rebase_args(matches)),
|
("rebase", Some(matches)) => Command::Rebase(parse_rebase_args(matches)),
|
||||||
("move", Some(matches)) => Command::Move(Box::new(parse_move_args(matches))),
|
("move", Some(matches)) => Command::Move(Box::new(parse_move_args(matches))),
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use solana_clap_utils::keypair::{pubkey_from_path, signer_from_path};
|
use solana_clap_utils::keypair::{pubkey_from_path, signer_from_path};
|
||||||
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
|
||||||
use solana_sdk::{pubkey::Pubkey, signature::Signer};
|
use solana_sdk::{
|
||||||
|
clock::{Epoch, UnixTimestamp},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
signature::Signer,
|
||||||
|
};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -34,6 +38,16 @@ pub(crate) struct AuthorizeArgs<P, K> {
|
||||||
pub num_accounts: usize,
|
pub num_accounts: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct SetLockupArgs<P, K> {
|
||||||
|
pub fee_payer: K,
|
||||||
|
pub base_pubkey: P,
|
||||||
|
pub custodian: K,
|
||||||
|
pub lockup_epoch: Option<Epoch>,
|
||||||
|
pub lockup_date: Option<UnixTimestamp>,
|
||||||
|
pub new_custodian: Option<P>,
|
||||||
|
pub num_accounts: usize,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct RebaseArgs<P, K> {
|
pub(crate) struct RebaseArgs<P, K> {
|
||||||
pub fee_payer: K,
|
pub fee_payer: K,
|
||||||
pub base_pubkey: P,
|
pub base_pubkey: P,
|
||||||
|
@ -53,6 +67,7 @@ pub(crate) enum Command<P, K> {
|
||||||
Addresses(QueryArgs<P>),
|
Addresses(QueryArgs<P>),
|
||||||
Balance(QueryArgs<P>),
|
Balance(QueryArgs<P>),
|
||||||
Authorize(AuthorizeArgs<P, K>),
|
Authorize(AuthorizeArgs<P, K>),
|
||||||
|
SetLockup(SetLockupArgs<P, K>),
|
||||||
Rebase(RebaseArgs<P, K>),
|
Rebase(RebaseArgs<P, K>),
|
||||||
Move(Box<MoveArgs<P, K>>),
|
Move(Box<MoveArgs<P, K>>),
|
||||||
}
|
}
|
||||||
|
@ -103,6 +118,29 @@ fn resolve_fee_payer(
|
||||||
signer_from_path(&matches, key_url, "fee-payer", wallet_manager)
|
signer_from_path(&matches, key_url, "fee-payer", wallet_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_custodian(
|
||||||
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||||
|
key_url: &str,
|
||||||
|
) -> Result<Box<dyn Signer>, Box<dyn Error>> {
|
||||||
|
let matches = ArgMatches::default();
|
||||||
|
signer_from_path(&matches, key_url, "custodian", wallet_manager)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_new_custodian(
|
||||||
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||||
|
key_url: &Option<String>,
|
||||||
|
) -> Result<Option<Pubkey>, Box<dyn Error>> {
|
||||||
|
let matches = ArgMatches::default();
|
||||||
|
let pubkey = match key_url {
|
||||||
|
None => None,
|
||||||
|
Some(key_url) => {
|
||||||
|
let pubkey = pubkey_from_path(&matches, key_url, "new custodian", wallet_manager)?;
|
||||||
|
Some(pubkey)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_base_pubkey(
|
fn resolve_base_pubkey(
|
||||||
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||||
key_url: &str,
|
key_url: &str,
|
||||||
|
@ -141,6 +179,22 @@ fn resolve_authorize_args(
|
||||||
Ok(resolved_args)
|
Ok(resolved_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_set_lockup_args(
|
||||||
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||||
|
args: &SetLockupArgs<String, String>,
|
||||||
|
) -> Result<SetLockupArgs<Pubkey, Box<dyn Signer>>, Box<dyn Error>> {
|
||||||
|
let resolved_args = SetLockupArgs {
|
||||||
|
fee_payer: resolve_fee_payer(wallet_manager, &args.fee_payer)?,
|
||||||
|
base_pubkey: resolve_base_pubkey(wallet_manager, &args.base_pubkey)?,
|
||||||
|
custodian: resolve_custodian(wallet_manager, &args.custodian)?,
|
||||||
|
lockup_epoch: args.lockup_epoch,
|
||||||
|
lockup_date: args.lockup_date,
|
||||||
|
new_custodian: resolve_new_custodian(wallet_manager, &args.new_custodian)?,
|
||||||
|
num_accounts: args.num_accounts,
|
||||||
|
};
|
||||||
|
Ok(resolved_args)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_rebase_args(
|
fn resolve_rebase_args(
|
||||||
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
|
||||||
args: &RebaseArgs<String, String>,
|
args: &RebaseArgs<String, String>,
|
||||||
|
@ -217,6 +271,10 @@ pub(crate) fn resolve_command(
|
||||||
let resolved_args = resolve_authorize_args(&mut wallet_manager, &args)?;
|
let resolved_args = resolve_authorize_args(&mut wallet_manager, &args)?;
|
||||||
Ok(Command::Authorize(resolved_args))
|
Ok(Command::Authorize(resolved_args))
|
||||||
}
|
}
|
||||||
|
Command::SetLockup(args) => {
|
||||||
|
let resolved_args = resolve_set_lockup_args(&mut wallet_manager, &args)?;
|
||||||
|
Ok(Command::SetLockup(resolved_args))
|
||||||
|
}
|
||||||
Command::Rebase(args) => {
|
Command::Rebase(args) => {
|
||||||
let resolved_args = resolve_rebase_args(&mut wallet_manager, &args)?;
|
let resolved_args = resolve_rebase_args(&mut wallet_manager, &args)?;
|
||||||
Ok(Command::Rebase(resolved_args))
|
Ok(Command::Rebase(resolved_args))
|
||||||
|
|
|
@ -3,7 +3,9 @@ mod args;
|
||||||
mod stake_accounts;
|
mod stake_accounts;
|
||||||
|
|
||||||
use crate::arg_parser::parse_args;
|
use crate::arg_parser::parse_args;
|
||||||
use crate::args::{resolve_command, AuthorizeArgs, Command, MoveArgs, NewArgs, RebaseArgs};
|
use crate::args::{
|
||||||
|
resolve_command, AuthorizeArgs, Command, MoveArgs, NewArgs, RebaseArgs, SetLockupArgs,
|
||||||
|
};
|
||||||
use solana_cli_config::Config;
|
use solana_cli_config::Config;
|
||||||
use solana_client::client_error::ClientError;
|
use solana_client::client_error::ClientError;
|
||||||
use solana_client::rpc_client::RpcClient;
|
use solana_client::rpc_client::RpcClient;
|
||||||
|
@ -15,6 +17,7 @@ use solana_sdk::{
|
||||||
signers::Signers,
|
signers::Signers,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
|
use solana_stake_program::stake_instruction::LockupArgs;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
@ -53,6 +56,7 @@ fn process_new_stake_account(
|
||||||
args.lamports,
|
args.lamports,
|
||||||
&args.stake_authority,
|
&args.stake_authority,
|
||||||
&args.withdraw_authority,
|
&args.withdraw_authority,
|
||||||
|
&Pubkey::default(),
|
||||||
args.index,
|
args.index,
|
||||||
);
|
);
|
||||||
let signers = vec![
|
let signers = vec![
|
||||||
|
@ -89,6 +93,30 @@ fn process_authorize_stake_accounts(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_lockup_stake_accounts(
|
||||||
|
client: &RpcClient,
|
||||||
|
args: &SetLockupArgs<Pubkey, Box<dyn Signer>>,
|
||||||
|
) -> Result<(), ClientError> {
|
||||||
|
let lockup = LockupArgs {
|
||||||
|
epoch: args.lockup_epoch,
|
||||||
|
unix_timestamp: args.lockup_date,
|
||||||
|
custodian: args.new_custodian,
|
||||||
|
};
|
||||||
|
let messages = stake_accounts::lockup_stake_accounts(
|
||||||
|
&args.fee_payer.pubkey(),
|
||||||
|
&args.base_pubkey,
|
||||||
|
&args.custodian.pubkey(),
|
||||||
|
&lockup,
|
||||||
|
args.num_accounts,
|
||||||
|
);
|
||||||
|
let signers = vec![&*args.fee_payer, &*args.custodian];
|
||||||
|
for message in messages {
|
||||||
|
let signature = send_message(client, message, &signers)?;
|
||||||
|
println!("{}", signature);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn process_rebase_stake_accounts(
|
fn process_rebase_stake_accounts(
|
||||||
client: &RpcClient,
|
client: &RpcClient,
|
||||||
args: &RebaseArgs<Pubkey, Box<dyn Signer>>,
|
args: &RebaseArgs<Pubkey, Box<dyn Signer>>,
|
||||||
|
@ -201,6 +229,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
Command::Authorize(args) => {
|
Command::Authorize(args) => {
|
||||||
process_authorize_stake_accounts(&client, &args)?;
|
process_authorize_stake_accounts(&client, &args)?;
|
||||||
}
|
}
|
||||||
|
Command::SetLockup(args) => {
|
||||||
|
process_lockup_stake_accounts(&client, &args)?;
|
||||||
|
}
|
||||||
Command::Rebase(args) => {
|
Command::Rebase(args) => {
|
||||||
process_rebase_stake_accounts(&client, &args)?;
|
process_rebase_stake_accounts(&client, &args)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use solana_sdk::{instruction::Instruction, message::Message, pubkey::Pubkey};
|
use solana_sdk::{instruction::Instruction, message::Message, pubkey::Pubkey};
|
||||||
use solana_stake_program::{
|
use solana_stake_program::{
|
||||||
stake_instruction,
|
stake_instruction::{self, LockupArgs},
|
||||||
stake_state::{Authorized, Lockup, StakeAuthorize},
|
stake_state::{Authorized, Lockup, StakeAuthorize},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ pub(crate) fn new_stake_account(
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
stake_authority_pubkey: &Pubkey,
|
stake_authority_pubkey: &Pubkey,
|
||||||
withdraw_authority_pubkey: &Pubkey,
|
withdraw_authority_pubkey: &Pubkey,
|
||||||
|
custodian_pubkey: &Pubkey,
|
||||||
index: usize,
|
index: usize,
|
||||||
) -> Message {
|
) -> Message {
|
||||||
let stake_account_address = derive_stake_account_address(base_pubkey, index);
|
let stake_account_address = derive_stake_account_address(base_pubkey, index);
|
||||||
|
@ -32,13 +33,17 @@ pub(crate) fn new_stake_account(
|
||||||
staker: *stake_authority_pubkey,
|
staker: *stake_authority_pubkey,
|
||||||
withdrawer: *withdraw_authority_pubkey,
|
withdrawer: *withdraw_authority_pubkey,
|
||||||
};
|
};
|
||||||
|
let lockup = Lockup {
|
||||||
|
custodian: *custodian_pubkey,
|
||||||
|
..Lockup::default()
|
||||||
|
};
|
||||||
let instructions = stake_instruction::create_account_with_seed(
|
let instructions = stake_instruction::create_account_with_seed(
|
||||||
funding_pubkey,
|
funding_pubkey,
|
||||||
&stake_account_address,
|
&stake_account_address,
|
||||||
&base_pubkey,
|
&base_pubkey,
|
||||||
&index.to_string(),
|
&index.to_string(),
|
||||||
&authorized,
|
&authorized,
|
||||||
&Lockup::default(),
|
&lockup,
|
||||||
lamports,
|
lamports,
|
||||||
);
|
);
|
||||||
Message::new_with_payer(&instructions, Some(fee_payer_pubkey))
|
Message::new_with_payer(&instructions, Some(fee_payer_pubkey))
|
||||||
|
@ -152,6 +157,23 @@ pub(crate) fn authorize_stake_accounts(
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn lockup_stake_accounts(
|
||||||
|
fee_payer_pubkey: &Pubkey,
|
||||||
|
base_pubkey: &Pubkey,
|
||||||
|
custodian_pubkey: &Pubkey,
|
||||||
|
lockup: &LockupArgs,
|
||||||
|
num_accounts: usize,
|
||||||
|
) -> Vec<Message> {
|
||||||
|
let stake_account_addresses = derive_stake_account_addresses(base_pubkey, num_accounts);
|
||||||
|
stake_account_addresses
|
||||||
|
.iter()
|
||||||
|
.map(|address| {
|
||||||
|
let instruction = stake_instruction::set_lockup(address, &lockup, custodian_pubkey);
|
||||||
|
Message::new_with_payer(&[instruction], Some(&fee_payer_pubkey))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn rebase_stake_accounts(
|
pub(crate) fn rebase_stake_accounts(
|
||||||
fee_payer_pubkey: &Pubkey,
|
fee_payer_pubkey: &Pubkey,
|
||||||
new_base_pubkey: &Pubkey,
|
new_base_pubkey: &Pubkey,
|
||||||
|
@ -273,6 +295,7 @@ mod tests {
|
||||||
lamports,
|
lamports,
|
||||||
&stake_authority_pubkey,
|
&stake_authority_pubkey,
|
||||||
&withdraw_authority_pubkey,
|
&withdraw_authority_pubkey,
|
||||||
|
&Pubkey::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -310,6 +333,7 @@ mod tests {
|
||||||
lamports,
|
lamports,
|
||||||
&stake_authority_pubkey,
|
&stake_authority_pubkey,
|
||||||
&withdraw_authority_pubkey,
|
&withdraw_authority_pubkey,
|
||||||
|
&Pubkey::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -343,6 +367,57 @@ mod tests {
|
||||||
assert_eq!(authorized.withdrawer, new_withdraw_authority_pubkey);
|
assert_eq!(authorized.withdrawer, new_withdraw_authority_pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lockup_stake_accounts() {
|
||||||
|
let (bank, funding_keypair, rent) = create_bank(10_000_000);
|
||||||
|
let funding_pubkey = funding_keypair.pubkey();
|
||||||
|
let bank_client = BankClient::new(bank);
|
||||||
|
let fee_payer_keypair = create_account(&bank_client, &funding_keypair, 1);
|
||||||
|
let fee_payer_pubkey = fee_payer_keypair.pubkey();
|
||||||
|
|
||||||
|
let base_keypair = Keypair::new();
|
||||||
|
let base_pubkey = base_keypair.pubkey();
|
||||||
|
let lamports = rent + 1;
|
||||||
|
|
||||||
|
let custodian_keypair = Keypair::new();
|
||||||
|
let custodian_pubkey = custodian_keypair.pubkey();
|
||||||
|
|
||||||
|
let message = new_stake_account(
|
||||||
|
&fee_payer_pubkey,
|
||||||
|
&funding_pubkey,
|
||||||
|
&base_pubkey,
|
||||||
|
lamports,
|
||||||
|
&Pubkey::default(),
|
||||||
|
&Pubkey::default(),
|
||||||
|
&custodian_pubkey,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let signers = [&funding_keypair, &fee_payer_keypair, &base_keypair];
|
||||||
|
bank_client.send_message(&signers, message).unwrap();
|
||||||
|
|
||||||
|
let messages = lockup_stake_accounts(
|
||||||
|
&fee_payer_pubkey,
|
||||||
|
&base_pubkey,
|
||||||
|
&custodian_pubkey,
|
||||||
|
&LockupArgs {
|
||||||
|
unix_timestamp: Some(1),
|
||||||
|
..LockupArgs::default()
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
let signers = [&fee_payer_keypair, &custodian_keypair];
|
||||||
|
for message in messages {
|
||||||
|
bank_client.send_message(&signers, message).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = get_account_at(&bank_client, &base_pubkey, 0);
|
||||||
|
let lockup = StakeState::lockup_from(&account).unwrap();
|
||||||
|
assert_eq!(lockup.unix_timestamp, 1);
|
||||||
|
assert_eq!(lockup.epoch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rebase_empty_account() {
|
fn test_rebase_empty_account() {
|
||||||
let pubkey = Pubkey::default();
|
let pubkey = Pubkey::default();
|
||||||
|
@ -384,6 +459,7 @@ mod tests {
|
||||||
lamports,
|
lamports,
|
||||||
&stake_authority_pubkey,
|
&stake_authority_pubkey,
|
||||||
&withdraw_authority_pubkey,
|
&withdraw_authority_pubkey,
|
||||||
|
&Pubkey::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -442,6 +518,7 @@ mod tests {
|
||||||
lamports,
|
lamports,
|
||||||
&stake_authority_pubkey,
|
&stake_authority_pubkey,
|
||||||
&withdraw_authority_pubkey,
|
&withdraw_authority_pubkey,
|
||||||
|
&Pubkey::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue