stake: Disallow stakes merging with themselves

This commit is contained in:
Trent Nelson 2020-11-22 20:11:00 -07:00 committed by Trent Nelson
parent 6b9a019c0a
commit 488ce982f0
1 changed files with 47 additions and 0 deletions

View File

@ -1053,9 +1053,14 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
stake_history: &StakeHistory,
signers: &HashSet<Pubkey>,
) -> Result<(), InstructionError> {
// Ensure source isn't spoofed
if source_account.owner()? != id() {
return Err(InstructionError::IncorrectProgramId);
}
// Close the self-reference loophole
if source_account.unsigned_key() == self.unsigned_key() {
return Err(InstructionError::InvalidArgument);
}
let stake_merge_kind = MergeKind::get_if_mergeable(self, clock, stake_history)?;
let meta = stake_merge_kind.meta();
@ -4631,6 +4636,48 @@ mod tests {
}
}
#[test]
fn test_merge_self_fails() {
let stake_address = Pubkey::new_unique();
let authority_pubkey = Pubkey::new_unique();
let signers = HashSet::from_iter(vec![authority_pubkey]);
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_amount = 4242424242;
let stake_lamports = rent_exempt_reserve + stake_amount;
let meta = Meta {
rent_exempt_reserve,
..Meta::auto(&authority_pubkey)
};
let stake = Stake {
delegation: Delegation {
stake: stake_amount,
activation_epoch: 0,
..Delegation::default()
},
..Stake::default()
};
let stake_account = Account::new_ref_data_with_space(
stake_lamports,
&StakeState::Stake(meta, stake),
std::mem::size_of::<StakeState>(),
&id(),
)
.expect("stake_account");
let stake_keyed_account = KeyedAccount::new(&stake_address, true, &stake_account);
assert_eq!(
stake_keyed_account.merge(
&stake_keyed_account,
&Clock::default(),
&StakeHistory::default(),
&signers,
),
Err(InstructionError::InvalidArgument),
);
}
#[test]
fn test_merge_incorrect_authorized_staker() {
let stake_pubkey = solana_sdk::pubkey::new_rand();