Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.16: Make active stake consistent in split (backport of #33295) #33319

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/downstream-project-spl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
- [governance/addin-mock/program, governance/program]
- [memo/program]
- [name-service/program]
- [stake-pool/program]
# - [stake-pool/program]
- [single-pool/program]

steps:
Expand Down
4 changes: 4 additions & 0 deletions cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ pub enum CliCommand {
lamports: u64,
fee_payer: SignerIndex,
compute_unit_price: Option<u64>,
rent_exempt_reserve: Option<u64>,
},
MergeStake {
stake_account_pubkey: Pubkey,
Expand Down Expand Up @@ -1215,6 +1216,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
lamports,
fee_payer,
compute_unit_price,
rent_exempt_reserve,
} => process_split_stake(
&rpc_client,
config,
Expand All @@ -1231,6 +1233,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
*lamports,
*fee_payer,
compute_unit_price.as_ref(),
rent_exempt_reserve.as_ref(),
),
CliCommand::MergeStake {
stake_account_pubkey,
Expand Down Expand Up @@ -2232,6 +2235,7 @@ mod tests {
lamports: 30,
fee_payer: 0,
compute_unit_price: None,
rent_exempt_reserve: None,
};
config.signers = vec![&keypair, &split_stake_account];
let result = process_command(&config);
Expand Down
78 changes: 57 additions & 21 deletions cli/src/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use {
tools::{acceptable_reference_epoch_credits, eligible_for_deactivate_delinquent},
},
stake_history::{Epoch, StakeHistory},
system_instruction::SystemError,
system_instruction::{self, SystemError},
sysvar::{clock, stake_history},
transaction::Transaction,
},
Expand Down Expand Up @@ -119,6 +119,13 @@ pub struct StakeAuthorizationIndexed {
pub new_authority_signer: Option<SignerIndex>,
}

struct SignOnlySplitNeedsRent {}
impl ArgsConfig for SignOnlySplitNeedsRent {
fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> {
arg.requires("rent_exempt_reserve_sol")
}
}

pub trait StakeSubCommands {
fn stake_subcommands(self) -> Self;
}
Expand Down Expand Up @@ -491,11 +498,21 @@ impl StakeSubCommands for App<'_, '_> {
will be at a derived address of SPLIT_STAKE_ACCOUNT")
)
.arg(stake_authority_arg())
.offline_args()
.offline_args_config(&SignOnlySplitNeedsRent{})
.nonce_args(false)
.arg(fee_payer_arg())
.arg(memo_arg())
.arg(compute_unit_price_arg())
.arg(
Arg::with_name("rent_exempt_reserve_sol")
.long("rent-exempt-reserve-sol")
.value_name("AMOUNT")
.takes_value(true)
.validator(is_amount)
.requires("sign_only")
.help("Offline signing only: the rent-exempt amount to move into the new \
stake account, in SOL")
)
)
.subcommand(
SubCommand::with_name("merge-stake")
Expand Down Expand Up @@ -1025,6 +1042,7 @@ pub fn parse_split_stake(
let signer_info =
default_signer.generate_unique_signers(bulk_signers, matches, wallet_manager)?;
let compute_unit_price = value_of(matches, COMPUTE_UNIT_PRICE_ARG.name);
let rent_exempt_reserve = lamports_of_sol(matches, "rent_exempt_reserve_sol");

Ok(CliCommandInfo {
command: CliCommand::SplitStake {
Expand All @@ -1041,6 +1059,7 @@ pub fn parse_split_stake(
lamports,
fee_payer: signer_info.index_of(fee_payer_pubkey).unwrap(),
compute_unit_price,
rent_exempt_reserve,
},
signers: signer_info.signers,
})
Expand Down Expand Up @@ -1850,6 +1869,7 @@ pub fn process_split_stake(
lamports: u64,
fee_payer: SignerIndex,
compute_unit_price: Option<&u64>,
rent_exempt_reserve: Option<&u64>,
) -> ProcessResult {
let split_stake_account = config.signers[split_stake_account];
let fee_payer = config.signers[fee_payer];
Expand Down Expand Up @@ -1883,7 +1903,7 @@ pub fn process_split_stake(
split_stake_account.pubkey()
};

if !sign_only {
let rent_exempt_reserve = if !sign_only {
if let Ok(stake_account) = rpc_client.get_account(&split_stake_account_address) {
let err_msg = if stake_account.owner == stake::program::id() {
format!("Stake account {split_stake_account_address} already exists")
Expand All @@ -1904,30 +1924,44 @@ pub fn process_split_stake(
))
.into());
}
}
minimum_balance
} else {
rent_exempt_reserve
.cloned()
.expect("rent_exempt_reserve_sol is required with sign_only")
};

let recent_blockhash = blockhash_query.get_blockhash(rpc_client, config.commitment)?;

let ixs = if let Some(seed) = split_stake_account_seed {
stake_instruction::split_with_seed(
stake_account_pubkey,
&stake_authority.pubkey(),
lamports,
&split_stake_account_address,
&split_stake_account.pubkey(),
seed,
let mut ixs = vec![system_instruction::transfer(
&fee_payer.pubkey(),
&split_stake_account_address,
rent_exempt_reserve,
)];
if let Some(seed) = split_stake_account_seed {
ixs.append(
&mut stake_instruction::split_with_seed(
stake_account_pubkey,
&stake_authority.pubkey(),
lamports,
&split_stake_account_address,
&split_stake_account.pubkey(),
seed,
)
.with_memo(memo)
.with_compute_unit_price(compute_unit_price),
)
.with_memo(memo)
.with_compute_unit_price(compute_unit_price)
} else {
stake_instruction::split(
stake_account_pubkey,
&stake_authority.pubkey(),
lamports,
&split_stake_account_address,
ixs.append(
&mut stake_instruction::split(
stake_account_pubkey,
&stake_authority.pubkey(),
lamports,
&split_stake_account_address,
)
.with_memo(memo)
.with_compute_unit_price(compute_unit_price),
)
.with_memo(memo)
.with_compute_unit_price(compute_unit_price)
};

let nonce_authority = config.signers[nonce_authority];
Expand Down Expand Up @@ -4845,6 +4879,7 @@ mod tests {
lamports: 50_000_000_000,
fee_payer: 0,
compute_unit_price: None,
rent_exempt_reserve: None,
},
signers: vec![
read_keypair_file(&default_keypair_file).unwrap().into(),
Expand Down Expand Up @@ -4912,6 +4947,7 @@ mod tests {
lamports: 50_000_000_000,
fee_payer: 1,
compute_unit_price: None,
rent_exempt_reserve: None,
},
signers: vec![
Presigner::new(&stake_auth_pubkey, &stake_sig).into(),
Expand Down
19 changes: 13 additions & 6 deletions cli/tests/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,10 @@ fn test_stake_split() {
config.json_rpc_url = test_validator.rpc_url();
config.signers = vec![&default_signer];

let minimum_balance = rpc_client
.get_minimum_balance_for_rent_exemption(StakeState::size_of())
.unwrap();

let mut config_offline = CliConfig::recent_for_tests();
config_offline.json_rpc_url = String::default();
config_offline.signers = vec![&offline_signer];
Expand Down Expand Up @@ -1494,10 +1498,7 @@ fn test_stake_split() {
check_balance!(1_000_000_000_000, &rpc_client, &offline_pubkey);

// Create stake account, identity is authority
let stake_balance = rpc_client
.get_minimum_balance_for_rent_exemption(StakeState::size_of())
.unwrap()
+ 10_000_000_000;
let stake_balance = minimum_balance + 10_000_000_000;
let stake_keypair = keypair_from_seed(&[0u8; 32]).unwrap();
let stake_account_pubkey = stake_keypair.pubkey();
config.signers.push(&stake_keypair);
Expand Down Expand Up @@ -1567,6 +1568,7 @@ fn test_stake_split() {
lamports: 2 * stake_balance,
fee_payer: 0,
compute_unit_price: None,
rent_exempt_reserve: Some(minimum_balance),
};
config_offline.output_format = OutputFormat::JsonCompact;
let sig_response = process_command(&config_offline).unwrap();
Expand All @@ -1591,10 +1593,15 @@ fn test_stake_split() {
lamports: 2 * stake_balance,
fee_payer: 0,
compute_unit_price: None,
rent_exempt_reserve: None,
};
process_command(&config).unwrap();
check_balance!(8 * stake_balance, &rpc_client, &stake_account_pubkey,);
check_balance!(2 * stake_balance, &rpc_client, &split_account.pubkey(),);
check_balance!(8 * stake_balance, &rpc_client, &stake_account_pubkey);
check_balance!(
2 * stake_balance + minimum_balance,
&rpc_client,
&split_account.pubkey()
);
}

#[test]
Expand Down
Loading