Make stake integration tests aware of stake minimum delegation (#24809)

This commit is contained in:
Brooks Prumo 2022-04-28 18:11:39 -05:00 committed by GitHub
parent 8f6e469d92
commit b4ade0d48a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 24 deletions

View File

@ -11,6 +11,7 @@ use {
client::SyncClient, client::SyncClient,
message::Message, message::Message,
pubkey::Pubkey, pubkey::Pubkey,
rent::Rent,
signature::{Keypair, Signer}, signature::{Keypair, Signer},
stake::{ stake::{
self, instruction as stake_instruction, self, instruction as stake_instruction,
@ -116,14 +117,20 @@ fn test_stake_create_and_split_single_signature() {
let staker_pubkey = staker_keypair.pubkey(); let staker_pubkey = staker_keypair.pubkey();
let bank_client = BankClient::new_shared(&Arc::new(Bank::new_for_tests(&genesis_config))); let bank = Arc::new(Bank::new_for_tests(&genesis_config));
let bank_client = BankClient::new_shared(&bank);
let stake_address = let stake_address =
Pubkey::create_with_seed(&staker_pubkey, "stake", &stake::program::id()).unwrap(); Pubkey::create_with_seed(&staker_pubkey, "stake", &stake::program::id()).unwrap();
let authorized = Authorized::auto(&staker_pubkey); let authorized = Authorized::auto(&staker_pubkey);
let lamports = 1_000_000; let lamports = {
let rent = &bank.rent_collector().rent;
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
2 * (rent_exempt_reserve + minimum_delegation)
};
// Create stake account with seed // Create stake account with seed
let message = Message::new( let message = Message::new(
@ -186,14 +193,20 @@ fn test_stake_create_and_split_to_existing_system_account() {
let staker_pubkey = staker_keypair.pubkey(); let staker_pubkey = staker_keypair.pubkey();
let bank_client = BankClient::new_shared(&Arc::new(Bank::new_for_tests(&genesis_config))); let bank = Arc::new(Bank::new_for_tests(&genesis_config));
let bank_client = BankClient::new_shared(&bank);
let stake_address = let stake_address =
Pubkey::create_with_seed(&staker_pubkey, "stake", &stake::program::id()).unwrap(); Pubkey::create_with_seed(&staker_pubkey, "stake", &stake::program::id()).unwrap();
let authorized = Authorized::auto(&staker_pubkey); let authorized = Authorized::auto(&staker_pubkey);
let lamports = 1_000_000; let lamports = {
let rent = &bank.rent_collector().rent;
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
2 * (rent_exempt_reserve + minimum_delegation)
};
// Create stake account with seed // Create stake account with seed
let message = Message::new( let message = Message::new(
@ -257,19 +270,29 @@ fn test_stake_account_lifetime() {
let identity_pubkey = identity_keypair.pubkey(); let identity_pubkey = identity_keypair.pubkey();
let GenesisConfigInfo { let GenesisConfigInfo {
genesis_config, mut genesis_config,
mint_keypair, mint_keypair,
.. ..
} = create_genesis_config_with_leader( } = create_genesis_config_with_leader(
100_000_000_000, 100_000_000_000,
&solana_sdk::pubkey::new_rand(), &solana_sdk::pubkey::new_rand(),
1_000_000, 2_000_000_000,
); );
genesis_config.rent = Rent::default();
let bank = Bank::new_for_tests(&genesis_config); let bank = Bank::new_for_tests(&genesis_config);
let mint_pubkey = mint_keypair.pubkey(); let mint_pubkey = mint_keypair.pubkey();
let mut bank = Arc::new(bank); let mut bank = Arc::new(bank);
let bank_client = BankClient::new_shared(&bank); let bank_client = BankClient::new_shared(&bank);
let (vote_balance, stake_rent_exempt_reserve, stake_minimum_delegation) = {
let rent = &bank.rent_collector().rent;
(
rent.minimum_balance(VoteState::size_of()),
rent.minimum_balance(StakeState::size_of()),
solana_stake_program::get_minimum_delegation(&bank.feature_set),
)
};
// Create Vote Account // Create Vote Account
let message = Message::new( let message = Message::new(
&vote_instruction::create_account( &vote_instruction::create_account(
@ -281,7 +304,7 @@ fn test_stake_account_lifetime() {
authorized_withdrawer: vote_pubkey, authorized_withdrawer: vote_pubkey,
commission: 50, commission: 50,
}, },
10, vote_balance,
), ),
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -290,6 +313,11 @@ fn test_stake_account_lifetime() {
.expect("failed to create vote account"); .expect("failed to create vote account");
let authorized = Authorized::auto(&stake_pubkey); let authorized = Authorized::auto(&stake_pubkey);
let bonus_delegation = 1_000_000_000;
let stake_starting_delegation =
2 * stake_minimum_delegation + bonus_delegation + stake_rent_exempt_reserve;
let stake_starting_balance = stake_starting_delegation + stake_rent_exempt_reserve;
// Create stake account and delegate to vote account // Create stake account and delegate to vote account
let message = Message::new( let message = Message::new(
&stake_instruction::create_account_and_delegate_stake( &stake_instruction::create_account_and_delegate_stake(
@ -298,7 +326,7 @@ fn test_stake_account_lifetime() {
&vote_pubkey, &vote_pubkey,
&authorized, &authorized,
&Lockup::default(), &Lockup::default(),
1_000_000, stake_starting_balance,
), ),
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -310,7 +338,7 @@ fn test_stake_account_lifetime() {
let account = bank.get_account(&stake_pubkey).expect("account not found"); let account = bank.get_account(&stake_pubkey).expect("account not found");
let stake_state = account.state().expect("couldn't unpack account data"); let stake_state = account.state().expect("couldn't unpack account data");
if let StakeState::Stake(_meta, stake) = stake_state { if let StakeState::Stake(_meta, stake) = stake_state {
assert_eq!(stake.delegation.stake, 1_000_000); assert_eq!(stake.delegation.stake, stake_starting_delegation,);
} else { } else {
panic!("wrong account type found") panic!("wrong account type found")
} }
@ -334,7 +362,7 @@ fn test_stake_account_lifetime() {
let account = bank.get_account(&stake_pubkey).expect("account not found"); let account = bank.get_account(&stake_pubkey).expect("account not found");
let stake_state = account.state().expect("couldn't unpack account data"); let stake_state = account.state().expect("couldn't unpack account data");
if let StakeState::Stake(_meta, stake) = stake_state { if let StakeState::Stake(_meta, stake) = stake_state {
assert_eq!(stake.delegation.stake, 1_000_000); assert_eq!(stake.delegation.stake, stake_starting_delegation,);
} else { } else {
panic!("wrong account type found") panic!("wrong account type found")
} }
@ -361,18 +389,20 @@ fn test_stake_account_lifetime() {
assert_eq!(vote_state.votes.len(), 31); assert_eq!(vote_state.votes.len(), 31);
// one vote per slot, might be more slots than 32 in the epoch // one vote per slot, might be more slots than 32 in the epoch
assert!(vote_state.credits() >= 1); assert!(vote_state.credits() >= 1);
bank = fill_epoch_with_votes(&bank, &vote_keypair, &mint_keypair); bank = fill_epoch_with_votes(&bank, &vote_keypair, &mint_keypair);
let pre_staked = get_staked(&bank, &stake_pubkey); let pre_staked = get_staked(&bank, &stake_pubkey);
let pre_balance = bank.get_balance(&stake_pubkey);
// next epoch bank should pay rewards // next epoch bank should pay rewards
bank = next_epoch(&bank); bank = next_epoch(&bank);
// Test that balance increased, and that the balance got staked // Test that balance increased, and that the balance got staked
let staked = get_staked(&bank, &stake_pubkey); let staked = get_staked(&bank, &stake_pubkey);
let lamports = bank.get_balance(&stake_pubkey); let balance = bank.get_balance(&stake_pubkey);
assert!(staked > pre_staked); assert!(staked > pre_staked);
assert!(lamports > 1_000_000); assert!(balance > pre_balance);
// split the stake // split the stake
let split_stake_keypair = Keypair::new(); let split_stake_keypair = Keypair::new();
@ -380,11 +410,13 @@ fn test_stake_account_lifetime() {
let bank_client = BankClient::new_shared(&bank); let bank_client = BankClient::new_shared(&bank);
// Test split // Test split
let split_starting_delegation = stake_minimum_delegation + bonus_delegation;
let split_starting_balance = split_starting_delegation + stake_rent_exempt_reserve;
let message = Message::new( let message = Message::new(
&stake_instruction::split( &stake_instruction::split(
&stake_pubkey, &stake_pubkey,
&stake_pubkey, &stake_pubkey,
lamports / 2, split_starting_balance,
&split_stake_pubkey, &split_stake_pubkey,
), ),
Some(&mint_pubkey), Some(&mint_pubkey),
@ -395,6 +427,11 @@ fn test_stake_account_lifetime() {
message message
) )
.is_ok()); .is_ok());
assert_eq!(
get_staked(&bank, &split_stake_pubkey),
split_starting_delegation,
);
let stake_remaining_balance = balance - split_starting_balance;
// Deactivate the split // Deactivate the split
let message = Message::new( let message = Message::new(
@ -407,8 +444,10 @@ fn test_stake_account_lifetime() {
assert!(bank_client assert!(bank_client
.send_and_confirm_message(&[&mint_keypair, &stake_keypair], message) .send_and_confirm_message(&[&mint_keypair, &stake_keypair], message)
.is_ok()); .is_ok());
assert_eq!(
let split_staked = get_staked(&bank, &split_stake_pubkey); get_staked(&bank, &split_stake_pubkey),
split_starting_delegation,
);
// Test that we cannot withdraw above what's staked // Test that we cannot withdraw above what's staked
let message = Message::new( let message = Message::new(
@ -416,7 +455,7 @@ fn test_stake_account_lifetime() {
&split_stake_pubkey, &split_stake_pubkey,
&stake_pubkey, &stake_pubkey,
&solana_sdk::pubkey::new_rand(), &solana_sdk::pubkey::new_rand(),
lamports / 2 - split_staked + 1, split_starting_delegation + 1,
None, None,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
@ -433,33 +472,34 @@ fn test_stake_account_lifetime() {
assert!(split_staked > 0); assert!(split_staked > 0);
// withdrawal in cooldown // withdrawal in cooldown
let split_balance = bank.get_balance(&split_stake_pubkey);
let message = Message::new( let message = Message::new(
&[stake_instruction::withdraw( &[stake_instruction::withdraw(
&split_stake_pubkey, &split_stake_pubkey,
&stake_pubkey, &stake_pubkey,
&solana_sdk::pubkey::new_rand(), &solana_sdk::pubkey::new_rand(),
lamports / 2, split_balance,
None, None,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
); );
assert!(bank_client assert!(bank_client
.send_and_confirm_message(&[&mint_keypair, &stake_keypair], message) .send_and_confirm_message(&[&mint_keypair, &stake_keypair], message)
.is_err()); .is_err());
// but we can withdraw unstaked // but we can withdraw unstaked
let split_unstaked = split_balance - split_staked - stake_rent_exempt_reserve;
assert!(split_unstaked > 0);
let message = Message::new( let message = Message::new(
&[stake_instruction::withdraw( &[stake_instruction::withdraw(
&split_stake_pubkey, &split_stake_pubkey,
&stake_pubkey, &stake_pubkey,
&solana_sdk::pubkey::new_rand(), &solana_sdk::pubkey::new_rand(),
lamports / 2 - split_staked, split_unstaked,
None, None,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
); );
// assert we can withdraw unstaked tokens
assert!(bank_client assert!(bank_client
.send_and_confirm_message(&[&mint_keypair, &stake_keypair], message) .send_and_confirm_message(&[&mint_keypair, &stake_keypair], message)
.is_ok()); .is_ok());
@ -474,12 +514,13 @@ fn test_stake_account_lifetime() {
let bank_client = BankClient::new_shared(&bank); let bank_client = BankClient::new_shared(&bank);
// Test that we can withdraw everything else out of the split // Test that we can withdraw everything else out of the split
let split_remaining_balance = split_balance - split_unstaked;
let message = Message::new( let message = Message::new(
&[stake_instruction::withdraw( &[stake_instruction::withdraw(
&split_stake_pubkey, &split_stake_pubkey,
&stake_pubkey, &stake_pubkey,
&solana_sdk::pubkey::new_rand(), &solana_sdk::pubkey::new_rand(),
split_staked, split_remaining_balance,
None, None,
)], )],
Some(&mint_pubkey), Some(&mint_pubkey),
@ -490,7 +531,7 @@ fn test_stake_account_lifetime() {
// verify all the math sums to zero // verify all the math sums to zero
assert_eq!(bank.get_balance(&split_stake_pubkey), 0); assert_eq!(bank.get_balance(&split_stake_pubkey), 0);
assert_eq!(bank.get_balance(&stake_pubkey), lamports - lamports / 2); assert_eq!(bank.get_balance(&stake_pubkey), stake_remaining_balance);
} }
#[test] #[test]
@ -537,6 +578,13 @@ fn test_create_stake_account_from_seed() {
.expect("failed to create vote account"); .expect("failed to create vote account");
let authorized = Authorized::auto(&mint_pubkey); let authorized = Authorized::auto(&mint_pubkey);
let (balance, delegation) = {
let rent = &bank.rent_collector().rent;
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = solana_stake_program::get_minimum_delegation(&bank.feature_set);
(rent_exempt_reserve + minimum_delegation, minimum_delegation)
};
// Create stake account and delegate to vote account // Create stake account and delegate to vote account
let message = Message::new( let message = Message::new(
&stake_instruction::create_account_with_seed_and_delegate_stake( &stake_instruction::create_account_with_seed_and_delegate_stake(
@ -547,7 +595,7 @@ fn test_create_stake_account_from_seed() {
&vote_pubkey, &vote_pubkey,
&authorized, &authorized,
&Lockup::default(), &Lockup::default(),
1_000_000, balance,
), ),
Some(&mint_pubkey), Some(&mint_pubkey),
); );
@ -559,7 +607,7 @@ fn test_create_stake_account_from_seed() {
let account = bank.get_account(&stake_pubkey).expect("account not found"); let account = bank.get_account(&stake_pubkey).expect("account not found");
let stake_state = account.state().expect("couldn't unpack account data"); let stake_state = account.state().expect("couldn't unpack account data");
if let StakeState::Stake(_meta, stake) = stake_state { if let StakeState::Stake(_meta, stake) = stake_state {
assert_eq!(stake.delegation.stake, 1_000_000); assert_eq!(stake.delegation.stake, delegation);
} else { } else {
panic!("wrong account type found") panic!("wrong account type found")
} }