stake: Disallow stakes merging with themselves
This commit is contained in:
committed by
Trent Nelson
parent
6b9a019c0a
commit
488ce982f0
@ -1053,9 +1053,14 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||||||
stake_history: &StakeHistory,
|
stake_history: &StakeHistory,
|
||||||
signers: &HashSet<Pubkey>,
|
signers: &HashSet<Pubkey>,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
|
// Ensure source isn't spoofed
|
||||||
if source_account.owner()? != id() {
|
if source_account.owner()? != id() {
|
||||||
return Err(InstructionError::IncorrectProgramId);
|
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 stake_merge_kind = MergeKind::get_if_mergeable(self, clock, stake_history)?;
|
||||||
let meta = stake_merge_kind.meta();
|
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]
|
#[test]
|
||||||
fn test_merge_incorrect_authorized_staker() {
|
fn test_merge_incorrect_authorized_staker() {
|
||||||
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
let stake_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
Reference in New Issue
Block a user