Cap split stake at source stake when splitting entire balance (#13754) (#13765)

(cherry picked from commit f0f99ffc7e)

Co-authored-by: Tyera Eulberg <teulberg@gmail.com>
This commit is contained in:
mergify[bot]
2020-11-23 18:23:58 +00:00
committed by GitHub
parent de03a5092d
commit 0c2433d796

View File

@ -938,13 +938,20 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
// split account. Since split accounts retain the state of their source
// account, this prevents any magic activation of stake by prefunding the
// split account.
(
lamports.saturating_sub(meta.rent_exempt_reserve),
// The new split stake also needs to ignore any positive delta between the
// original rent_exempt_reserve and the split_rent_exempt_reserve, in order
// to prevent magic activation of stake by splitting between accounts of
// different sizes.
let remaining_stake_delta =
lamports.saturating_sub(meta.rent_exempt_reserve);
let split_stake_amount = std::cmp::min(
lamports - split_rent_exempt_reserve,
)
remaining_stake_delta,
);
(remaining_stake_delta, split_stake_amount)
} else {
// Otherwise, the new split stake should reflect the entire split
// requested, less any lamports needed to cover the rent-exempt reserve
// requested, less any lamports needed to cover the split_rent_exempt_reserve
(
lamports,
lamports - split_rent_exempt_reserve.saturating_sub(split.lamports()?),
@ -4287,7 +4294,9 @@ mod tests {
assert_eq!(Ok(*state), stake_keyed_account.state());
}
StakeState::Stake(meta, stake) => {
let expected_stake = stake_lamports - expected_rent_exempt_reserve;
// Expected stake should reflect original stake amount so that extra lamports
// from the rent_exempt_reserve inequality do not magically activate
let expected_stake = stake_lamports - rent_exempt_reserve;
assert_eq!(
Ok(StakeState::Stake(
@ -4304,7 +4313,9 @@ mod tests {
);
assert_eq!(
split_stake_keyed_account.account.borrow().lamports,
expected_stake + expected_rent_exempt_reserve
expected_stake
+ expected_rent_exempt_reserve
+ (rent_exempt_reserve - expected_rent_exempt_reserve)
);
assert_eq!(
Ok(StakeState::Stake(