Add support for split of 100% of stake (#7510)
This commit is contained in:
parent
7a7992ab0b
commit
b22dc38ba1
|
@ -667,12 +667,11 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
||||||
|
|
||||||
// verify enough lamports for rent in new stake with the split
|
// verify enough lamports for rent in new stake with the split
|
||||||
if split.account.lamports + lamports < meta.rent_exempt_reserve
|
if split.account.lamports + lamports < meta.rent_exempt_reserve
|
||||||
// verify enough lamports left in previous stake
|
// verify enough lamports left in previous stake and not full withdrawal
|
||||||
|| lamports + meta.rent_exempt_reserve > self.account.lamports
|
|| (lamports + meta.rent_exempt_reserve > self.account.lamports && lamports != self.account.lamports)
|
||||||
{
|
{
|
||||||
return Err(InstructionError::InsufficientFunds);
|
return Err(InstructionError::InsufficientFunds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// split the stake, subtract rent_exempt_balance unless
|
// split the stake, subtract rent_exempt_balance unless
|
||||||
// the destination account already has those lamports
|
// the destination account already has those lamports
|
||||||
// in place.
|
// in place.
|
||||||
|
@ -694,7 +693,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
||||||
// enough lamports for rent in new stake
|
// enough lamports for rent in new stake
|
||||||
if lamports < meta.rent_exempt_reserve
|
if lamports < meta.rent_exempt_reserve
|
||||||
// verify enough lamports left in previous stake
|
// verify enough lamports left in previous stake
|
||||||
|| lamports + meta.rent_exempt_reserve > self.account.lamports
|
|| (lamports + meta.rent_exempt_reserve > self.account.lamports && lamports != self.account.lamports)
|
||||||
{
|
{
|
||||||
return Err(InstructionError::InsufficientFunds);
|
return Err(InstructionError::InsufficientFunds);
|
||||||
}
|
}
|
||||||
|
@ -2313,7 +2312,10 @@ mod tests {
|
||||||
// test splitting both an Initialized stake and a Staked stake
|
// test splitting both an Initialized stake and a Staked stake
|
||||||
for state in &[
|
for state in &[
|
||||||
StakeState::Initialized(meta),
|
StakeState::Initialized(meta),
|
||||||
StakeState::Stake(meta, Stake::just_stake(stake_lamports)),
|
StakeState::Stake(
|
||||||
|
meta,
|
||||||
|
Stake::just_stake(stake_lamports - rent_exempt_reserve),
|
||||||
|
),
|
||||||
] {
|
] {
|
||||||
let mut stake_account = Account::new_data_with_space(
|
let mut stake_account = Account::new_data_with_space(
|
||||||
stake_lamports,
|
stake_lamports,
|
||||||
|
@ -2383,10 +2385,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
// assert_eq!(
|
|
||||||
// stake_keyed_account.state(),
|
|
||||||
// Ok(StakeState::Stake(*meta, Stake { stake: 0, ..*stake }))
|
|
||||||
// );
|
|
||||||
assert_eq!(stake_keyed_account.account.lamports, rent_exempt_reserve);
|
assert_eq!(stake_keyed_account.account.lamports, rent_exempt_reserve);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
split_stake_keyed_account.account.lamports,
|
split_stake_keyed_account.account.lamports,
|
||||||
|
@ -2496,6 +2494,103 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_split_100_percent_of_source() {
|
||||||
|
let stake_pubkey = Pubkey::new_rand();
|
||||||
|
let stake_lamports = 42;
|
||||||
|
let rent_exempt_reserve = 10;
|
||||||
|
|
||||||
|
let split_stake_pubkey = Pubkey::new_rand();
|
||||||
|
let signers = vec![stake_pubkey].into_iter().collect();
|
||||||
|
|
||||||
|
let meta = Meta {
|
||||||
|
authorized: Authorized::auto(&stake_pubkey),
|
||||||
|
rent_exempt_reserve,
|
||||||
|
..Meta::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// test splitting both an Initialized stake and a Staked stake
|
||||||
|
for state in &[
|
||||||
|
StakeState::Initialized(meta),
|
||||||
|
StakeState::Stake(
|
||||||
|
meta,
|
||||||
|
Stake::just_stake(stake_lamports - rent_exempt_reserve),
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let mut split_stake_account = Account::new_data_with_space(
|
||||||
|
0,
|
||||||
|
&StakeState::Uninitialized,
|
||||||
|
std::mem::size_of::<StakeState>(),
|
||||||
|
&id(),
|
||||||
|
)
|
||||||
|
.expect("stake_account");
|
||||||
|
|
||||||
|
let mut split_stake_keyed_account =
|
||||||
|
KeyedAccount::new(&split_stake_pubkey, true, &mut split_stake_account);
|
||||||
|
|
||||||
|
let mut stake_account = Account::new_data_with_space(
|
||||||
|
stake_lamports,
|
||||||
|
state,
|
||||||
|
std::mem::size_of::<StakeState>(),
|
||||||
|
&id(),
|
||||||
|
)
|
||||||
|
.expect("stake_account");
|
||||||
|
let mut stake_keyed_account =
|
||||||
|
KeyedAccount::new(&stake_pubkey, true, &mut stake_account);
|
||||||
|
|
||||||
|
// split 100% over to dest
|
||||||
|
assert_eq!(
|
||||||
|
stake_keyed_account.split(stake_lamports, &mut split_stake_keyed_account, &signers),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
|
||||||
|
// no lamport leakage
|
||||||
|
assert_eq!(
|
||||||
|
stake_keyed_account.account.lamports + split_stake_keyed_account.account.lamports,
|
||||||
|
stake_lamports
|
||||||
|
);
|
||||||
|
|
||||||
|
match state {
|
||||||
|
StakeState::Initialized(_) => {
|
||||||
|
assert_eq!(Ok(*state), split_stake_keyed_account.state());
|
||||||
|
assert_eq!(Ok(*state), stake_keyed_account.state());
|
||||||
|
}
|
||||||
|
StakeState::Stake(meta, stake) => {
|
||||||
|
assert_eq!(
|
||||||
|
Ok(StakeState::Stake(
|
||||||
|
*meta,
|
||||||
|
Stake {
|
||||||
|
delegation: Delegation {
|
||||||
|
stake: stake_lamports - rent_exempt_reserve,
|
||||||
|
..stake.delegation
|
||||||
|
},
|
||||||
|
..*stake
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
split_stake_keyed_account.state()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok(StakeState::Stake(
|
||||||
|
*meta,
|
||||||
|
Stake {
|
||||||
|
delegation: Delegation {
|
||||||
|
stake: 0,
|
||||||
|
..stake.delegation
|
||||||
|
},
|
||||||
|
..*stake
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
stake_keyed_account.state()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset
|
||||||
|
stake_keyed_account.account.lamports = stake_lamports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_authorize_delegated_stake() {
|
fn test_authorize_delegated_stake() {
|
||||||
let stake_pubkey = Pubkey::new_rand();
|
let stake_pubkey = Pubkey::new_rand();
|
||||||
|
|
Loading…
Reference in New Issue