Make stake integration tests aware of stake minimum delegation (#24809)
This commit is contained in:
parent
8f6e469d92
commit
b4ade0d48a
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue