diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index 05f704d701..6e6dc08b0e 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -3959,8 +3959,35 @@ mod tests { Err(InstructionError::MissingRequiredSignature) ); + let signers = HashSet::from([stake_pubkey]); + + // splitting an uninitialized account where the destination is the same as the source + { + // splitting should work when... + // - when split amount is the full balance + // - when split amount is zero + // - when split amount is non-zero and less than the full balance + // + // and splitting should fail when the split amount is greater than the balance + assert_eq!( + stake_keyed_account.split(stake_lamports, &stake_keyed_account, &signers), + Ok(()), + ); + assert_eq!( + stake_keyed_account.split(0, &stake_keyed_account, &signers), + Ok(()), + ); + assert_eq!( + stake_keyed_account.split(stake_lamports / 2, &stake_keyed_account, &signers), + Ok(()), + ); + assert_eq!( + stake_keyed_account.split(stake_lamports + 1, &stake_keyed_account, &signers), + Err(InstructionError::InsufficientFunds), + ); + } + // this should work - let signers = vec![stake_pubkey].into_iter().collect(); assert_eq!( stake_keyed_account.split(stake_lamports / 2, &split_stake_keyed_account, &signers), Ok(()) @@ -3982,24 +4009,30 @@ mod tests { &id(), ) .expect("stake_account"); - - let split_stake_pubkey = solana_sdk::pubkey::new_rand(); - let split_stake_account = AccountSharedData::new_ref_data_with_space( - 0, - &StakeState::Initialized(Meta::auto(&stake_pubkey)), - std::mem::size_of::(), - &id(), - ) - .expect("stake_account"); - - let signers = vec![stake_pubkey].into_iter().collect(); let stake_keyed_account = KeyedAccount::new(&stake_pubkey, true, &stake_account); - let split_stake_keyed_account = - KeyedAccount::new(&split_stake_pubkey, true, &split_stake_account); - assert_eq!( - stake_keyed_account.split(stake_lamports / 2, &split_stake_keyed_account, &signers), - Err(InstructionError::InvalidAccountData) - ); + let signers = vec![stake_pubkey].into_iter().collect(); + + for split_stake_state in &[ + StakeState::Initialized(Meta::default()), + StakeState::Stake(Meta::default(), Stake::default()), + StakeState::RewardsPool, + ] { + let split_stake_pubkey = solana_sdk::pubkey::new_rand(); + let split_stake_account = AccountSharedData::new_ref_data_with_space( + 0, + split_stake_state, + std::mem::size_of::(), + &id(), + ) + .expect("split_stake_account"); + + let split_stake_keyed_account = + KeyedAccount::new(&split_stake_pubkey, true, &split_stake_account); + assert_eq!( + stake_keyed_account.split(stake_lamports / 2, &split_stake_keyed_account, &signers), + Err(InstructionError::InvalidAccountData) + ); + } } fn just_stake(stake: u64) -> Stake { Stake {