Stake tests respect MINIMUM_STAKE_DELEGATION (#23426)

This commit is contained in:
Brooks Prumo 2022-03-16 16:36:23 -05:00 committed by GitHub
parent 86c695268e
commit 18bddbc730
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 36 deletions

View File

@ -634,7 +634,8 @@ mod tests {
let stake_address = Pubkey::new_unique(); let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account(); let stake_account = create_default_stake_account();
let rent_address = sysvar::rent::id(); let rent_address = sysvar::rent::id();
let rent_account = account::create_account_shared_data_for_test(&Rent::default()); let rent = Rent::default();
let rent_account = account::create_account_shared_data_for_test(&rent);
let rewards_address = sysvar::rewards::id(); let rewards_address = sysvar::rewards::id();
let rewards_account = let rewards_account =
account::create_account_shared_data_for_test(&sysvar::rewards::Rewards::new(0.0)); account::create_account_shared_data_for_test(&sysvar::rewards::Rewards::new(0.0));
@ -648,6 +649,8 @@ mod tests {
account::create_account_shared_data_for_test(&sysvar::clock::Clock::default()); account::create_account_shared_data_for_test(&sysvar::clock::Clock::default());
let config_address = stake_config::id(); let config_address = stake_config::id();
let config_account = config::create_account(0, &stake_config::Config::default()); let config_account = config::create_account(0, &stake_config::Config::default());
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let withdrawal_amount = rent_exempt_reserve + MINIMUM_STAKE_DELEGATION;
// gets the "is_empty()" check // gets the "is_empty()" check
process_instruction( process_instruction(
@ -769,7 +772,7 @@ mod tests {
// Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw // Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw
process_instruction( process_instruction(
&serialize(&StakeInstruction::Withdraw(42)).unwrap(), &serialize(&StakeInstruction::Withdraw(withdrawal_amount)).unwrap(),
vec![ vec![
(stake_address, stake_account.clone()), (stake_address, stake_account.clone()),
(vote_address, vote_account), (vote_address, vote_account),
@ -803,7 +806,7 @@ mod tests {
// Tests correct number of accounts are provided in withdraw // Tests correct number of accounts are provided in withdraw
process_instruction( process_instruction(
&serialize(&StakeInstruction::Withdraw(42)).unwrap(), &serialize(&StakeInstruction::Withdraw(withdrawal_amount)).unwrap(),
vec![(stake_address, stake_account.clone())], vec![(stake_address, stake_account.clone())],
vec![AccountMeta { vec![AccountMeta {
pubkey: stake_address, pubkey: stake_address,
@ -858,6 +861,10 @@ mod tests {
let clock_account = account::create_account_shared_data_for_test(&Clock::default()); let clock_account = account::create_account_shared_data_for_test(&Clock::default());
let custodian = Pubkey::new_unique(); let custodian = Pubkey::new_unique();
let custodian_account = create_default_account(); let custodian_account = create_default_account();
let rent = Rent::default();
let rent_address = sysvar::rent::id();
let rent_account = account::create_account_shared_data_for_test(&rent);
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
// Test InitializeChecked with non-signing withdrawer // Test InitializeChecked with non-signing withdrawer
let mut instruction = let mut instruction =
@ -870,12 +877,10 @@ mod tests {
// Test InitializeChecked with withdrawer signer // Test InitializeChecked with withdrawer signer
let stake_account = AccountSharedData::new( let stake_account = AccountSharedData::new(
1_000_000_000, rent_exempt_reserve + MINIMUM_STAKE_DELEGATION,
std::mem::size_of::<crate::stake_state::StakeState>(), std::mem::size_of::<crate::stake_state::StakeState>(),
&id(), &id(),
); );
let rent_address = sysvar::rent::id();
let rent_account = account::create_account_shared_data_for_test(&Rent::default());
process_instruction( process_instruction(
&serialize(&StakeInstruction::InitializeChecked).unwrap(), &serialize(&StakeInstruction::InitializeChecked).unwrap(),
vec![ vec![
@ -1192,7 +1197,9 @@ mod tests {
#[test] #[test]
fn test_stake_initialize() { fn test_stake_initialize() {
let stake_lamports = 42; let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_lamports = rent_exempt_reserve + MINIMUM_STAKE_DELEGATION;
let stake_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand();
let stake_account = let stake_account =
AccountSharedData::new(stake_lamports, std::mem::size_of::<StakeState>(), &id()); AccountSharedData::new(stake_lamports, std::mem::size_of::<StakeState>(), &id());
@ -1211,7 +1218,7 @@ mod tests {
(stake_address, stake_account.clone()), (stake_address, stake_account.clone()),
( (
sysvar::rent::id(), sysvar::rent::id(),
account::create_account_shared_data_for_test(&Rent::free()), account::create_account_shared_data_for_test(&rent),
), ),
]; ];
let instruction_accounts = vec![ let instruction_accounts = vec![
@ -1238,11 +1245,9 @@ mod tests {
assert_eq!( assert_eq!(
from(&accounts[0]).unwrap(), from(&accounts[0]).unwrap(),
StakeState::Initialized(Meta { StakeState::Initialized(Meta {
authorized: Authorized::auto(&stake_address),
rent_exempt_reserve,
lockup, lockup,
..Meta {
authorized: Authorized::auto(&stake_address),
..Meta::default()
}
}), }),
); );
@ -1256,12 +1261,12 @@ mod tests {
); );
transaction_accounts[0] = (stake_address, stake_account); transaction_accounts[0] = (stake_address, stake_account);
// not enough balance for rent... // not enough balance for rent and minimum delegation...
transaction_accounts[1] = ( transaction_accounts[1] = (
sysvar::rent::id(), sysvar::rent::id(),
account::create_account_shared_data_for_test(&Rent { account::create_account_shared_data_for_test(&Rent {
lamports_per_byte_year: 42, lamports_per_byte_year: rent.lamports_per_byte_year + 1,
..Rent::free() ..rent
}), }),
); );
process_instruction( process_instruction(
@ -2325,7 +2330,7 @@ mod tests {
#[test] #[test]
fn test_split() { fn test_split() {
let stake_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand();
let stake_lamports = 42; let stake_lamports = MINIMUM_STAKE_DELEGATION * 2;
let split_to_address = solana_sdk::pubkey::new_rand(); let split_to_address = solana_sdk::pubkey::new_rand();
let split_to_account = AccountSharedData::new_data_with_space( let split_to_account = AccountSharedData::new_data_with_space(
0, 0,
@ -2421,7 +2426,7 @@ mod tests {
let authority_address = solana_sdk::pubkey::new_rand(); let authority_address = solana_sdk::pubkey::new_rand();
let custodian_address = solana_sdk::pubkey::new_rand(); let custodian_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand();
let stake_lamports = 42; let stake_lamports = MINIMUM_STAKE_DELEGATION;
let stake_account = AccountSharedData::new_data_with_space( let stake_account = AccountSharedData::new_data_with_space(
stake_lamports, stake_lamports,
&StakeState::Uninitialized, &StakeState::Uninitialized,
@ -3165,7 +3170,7 @@ mod tests {
let custodian_address = solana_sdk::pubkey::new_rand(); let custodian_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand(); let authorized_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand();
let stake_lamports = 42; let stake_lamports = MINIMUM_STAKE_DELEGATION;
let stake_account = AccountSharedData::new_data_with_space( let stake_account = AccountSharedData::new_data_with_space(
stake_lamports, stake_lamports,
&StakeState::Uninitialized, &StakeState::Uninitialized,

View File

@ -2494,8 +2494,10 @@ mod tests {
#[test] #[test]
fn test_split_source_uninitialized() { fn test_split_source_uninitialized() {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let stake_lamports = 42; let stake_lamports = (rent_exempt_reserve + MINIMUM_STAKE_DELEGATION) * 2;
let stake_account = AccountSharedData::new_ref_data_with_space( let stake_account = AccountSharedData::new_ref_data_with_space(
stake_lamports, stake_lamports,
&StakeState::Uninitialized, &StakeState::Uninitialized,
@ -2614,12 +2616,17 @@ mod tests {
#[test] #[test]
fn test_split_more_than_staked() { fn test_split_more_than_staked() {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let stake_lamports = 42; let stake_lamports = (rent_exempt_reserve + MINIMUM_STAKE_DELEGATION) * 2;
let stake_account = AccountSharedData::new_ref_data_with_space( let stake_account = AccountSharedData::new_ref_data_with_space(
stake_lamports, stake_lamports,
&StakeState::Stake( &StakeState::Stake(
Meta::auto(&stake_pubkey), Meta {
rent_exempt_reserve,
..Meta::auto(&stake_pubkey)
},
just_stake(stake_lamports / 2 - 1), just_stake(stake_lamports / 2 - 1),
), ),
std::mem::size_of::<StakeState>(), std::mem::size_of::<StakeState>(),
@ -2648,10 +2655,12 @@ mod tests {
#[test] #[test]
fn test_split_with_rent() { fn test_split_with_rent() {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let minimum_balance = rent_exempt_reserve + MINIMUM_STAKE_DELEGATION;
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let split_stake_pubkey = solana_sdk::pubkey::new_rand(); let split_stake_pubkey = solana_sdk::pubkey::new_rand();
let stake_lamports = 10_000_000; let stake_lamports = minimum_balance * 2;
let rent_exempt_reserve = 2_282_880;
let signers = vec![stake_pubkey].into_iter().collect(); let signers = vec![stake_pubkey].into_iter().collect();
let meta = Meta { let meta = Meta {
@ -2710,10 +2719,10 @@ mod tests {
split_stake_keyed_account split_stake_keyed_account
.account .account
.borrow_mut() .borrow_mut()
.set_lamports(10_000_000); .set_lamports(minimum_balance);
assert_eq!( assert_eq!(
stake_keyed_account.split( stake_keyed_account.split(
stake_lamports - (rent_exempt_reserve + 1), // leave rent_exempt_reserve + 1 in original account stake_lamports - minimum_balance,
&split_stake_keyed_account, &split_stake_keyed_account,
&signers &signers
), ),
@ -2728,7 +2737,7 @@ mod tests {
*meta, *meta,
Stake { Stake {
delegation: Delegation { delegation: Delegation {
stake: stake_lamports - rent_exempt_reserve - 1, stake: stake_lamports - minimum_balance,
..stake.delegation ..stake.delegation
}, },
..*stake ..*stake
@ -2737,11 +2746,11 @@ mod tests {
); );
assert_eq!( assert_eq!(
stake_keyed_account.account.borrow().lamports(), stake_keyed_account.account.borrow().lamports(),
rent_exempt_reserve + 1 minimum_balance,
); );
assert_eq!( assert_eq!(
split_stake_keyed_account.account.borrow().lamports(), split_stake_keyed_account.account.borrow().lamports(),
10_000_000 + stake_lamports - rent_exempt_reserve - 1 stake_lamports,
); );
} }
} }
@ -2752,7 +2761,7 @@ mod tests {
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let rent = Rent::default(); let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>()); let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_lamports = rent_exempt_reserve * 3; // Enough to allow half to be split and remain rent-exempt let stake_lamports = (rent_exempt_reserve + MINIMUM_STAKE_DELEGATION) * 2;
let split_stake_pubkey = solana_sdk::pubkey::new_rand(); let split_stake_pubkey = solana_sdk::pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect(); let signers = vec![stake_pubkey].into_iter().collect();
@ -2767,7 +2776,13 @@ mod tests {
// Test various account prefunding, including empty, less than rent_exempt_reserve, exactly // Test various account prefunding, including empty, less than rent_exempt_reserve, exactly
// rent_exempt_reserve, and more than rent_exempt_reserve. The empty case is not covered in // rent_exempt_reserve, and more than rent_exempt_reserve. The empty case is not covered in
// test_split, since that test uses a Meta with rent_exempt_reserve = 0 // test_split, since that test uses a Meta with rent_exempt_reserve = 0
let split_lamport_balances = vec![0, 1, rent_exempt_reserve, rent_exempt_reserve + 1]; let split_lamport_balances = vec![
0,
rent_exempt_reserve - 1,
rent_exempt_reserve,
rent_exempt_reserve + MINIMUM_STAKE_DELEGATION - 1,
rent_exempt_reserve + MINIMUM_STAKE_DELEGATION,
];
for initial_balance in split_lamport_balances { for initial_balance in split_lamport_balances {
let split_stake_account = AccountSharedData::new_ref_data_with_space( let split_stake_account = AccountSharedData::new_ref_data_with_space(
initial_balance, initial_balance,
@ -2852,7 +2867,7 @@ mod tests {
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let rent = Rent::default(); let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>()); let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_lamports = rent_exempt_reserve * 3; // Enough to allow half to be split and remain rent-exempt let stake_lamports = (rent_exempt_reserve + MINIMUM_STAKE_DELEGATION) * 2;
let split_stake_pubkey = solana_sdk::pubkey::new_rand(); let split_stake_pubkey = solana_sdk::pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect(); let signers = vec![stake_pubkey].into_iter().collect();
@ -2876,9 +2891,10 @@ mod tests {
// test_split, since that test uses a Meta with rent_exempt_reserve = 0 // test_split, since that test uses a Meta with rent_exempt_reserve = 0
let split_lamport_balances = vec![ let split_lamport_balances = vec![
0, 0,
1, expected_rent_exempt_reserve - 1,
expected_rent_exempt_reserve, expected_rent_exempt_reserve,
expected_rent_exempt_reserve + 1, expected_rent_exempt_reserve + MINIMUM_STAKE_DELEGATION - 1,
expected_rent_exempt_reserve + MINIMUM_STAKE_DELEGATION,
]; ];
for initial_balance in split_lamport_balances { for initial_balance in split_lamport_balances {
let split_stake_account = AccountSharedData::new_ref_data_with_space( let split_stake_account = AccountSharedData::new_ref_data_with_space(
@ -3033,7 +3049,7 @@ mod tests {
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let rent = Rent::default(); let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>()); let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_lamports = rent_exempt_reserve * 3; // Arbitrary amount over rent_exempt_reserve let stake_lamports = rent_exempt_reserve + MINIMUM_STAKE_DELEGATION;
let split_stake_pubkey = solana_sdk::pubkey::new_rand(); let split_stake_pubkey = solana_sdk::pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect(); let signers = vec![stake_pubkey].into_iter().collect();
@ -3119,7 +3135,7 @@ mod tests {
let stake_pubkey = solana_sdk::pubkey::new_rand(); let stake_pubkey = solana_sdk::pubkey::new_rand();
let rent = Rent::default(); let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>()); let rent_exempt_reserve = rent.minimum_balance(std::mem::size_of::<StakeState>());
let stake_lamports = rent_exempt_reserve * 3; // Arbitrary amount over rent_exempt_reserve let stake_lamports = rent_exempt_reserve + MINIMUM_STAKE_DELEGATION;
let split_stake_pubkey = solana_sdk::pubkey::new_rand(); let split_stake_pubkey = solana_sdk::pubkey::new_rand();
let signers = vec![stake_pubkey].into_iter().collect(); let signers = vec![stake_pubkey].into_iter().collect();
@ -3134,7 +3150,13 @@ mod tests {
// Test various account prefunding, including empty, less than rent_exempt_reserve, exactly // Test various account prefunding, including empty, less than rent_exempt_reserve, exactly
// rent_exempt_reserve, and more than rent_exempt_reserve. Technically, the empty case is // rent_exempt_reserve, and more than rent_exempt_reserve. Technically, the empty case is
// covered in test_split_100_percent_of_source, but included here as well for readability // covered in test_split_100_percent_of_source, but included here as well for readability
let split_lamport_balances = vec![0, 1, rent_exempt_reserve, rent_exempt_reserve + 1]; let split_lamport_balances = vec![
0,
rent_exempt_reserve - 1,
rent_exempt_reserve,
rent_exempt_reserve + MINIMUM_STAKE_DELEGATION - 1,
rent_exempt_reserve + MINIMUM_STAKE_DELEGATION,
];
for initial_balance in split_lamport_balances { for initial_balance in split_lamport_balances {
let split_stake_account = AccountSharedData::new_ref_data_with_space( let split_stake_account = AccountSharedData::new_ref_data_with_space(
initial_balance, initial_balance,