fix epoch_stakes again (#5396)
This commit is contained in:
parent
4298b1f595
commit
f7d3f55566
|
@ -214,8 +214,7 @@ impl Tower {
|
|||
}
|
||||
|
||||
pub fn is_recent_epoch(&self, bank: &Bank) -> bool {
|
||||
let bank_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
||||
bank_epoch >= self.epoch_stakes.epoch
|
||||
bank.epoch() >= self.epoch_stakes.epoch
|
||||
}
|
||||
|
||||
pub fn update_epoch(&mut self, bank: &Bank) {
|
||||
|
@ -224,8 +223,7 @@ impl Tower {
|
|||
bank.slot(),
|
||||
self.epoch_stakes.epoch
|
||||
);
|
||||
let bank_epoch = bank.get_epoch_and_slot_index(bank.slot()).0;
|
||||
if bank_epoch != self.epoch_stakes.epoch {
|
||||
if bank.epoch() != self.epoch_stakes.epoch {
|
||||
assert!(
|
||||
self.is_recent_epoch(bank),
|
||||
"epoch_stakes cannot move backwards"
|
||||
|
|
|
@ -150,23 +150,15 @@ pub(crate) mod tests {
|
|||
|
||||
// First epoch has the bootstrap leader
|
||||
expected.insert(voting_keypair.pubkey(), leader_stake.stake(0));
|
||||
assert_eq!(
|
||||
vote_account_stakes_at_epoch(&bank, 0),
|
||||
Some(expected.clone())
|
||||
);
|
||||
|
||||
// henceforth, verify that we have snapshots of stake at epoch 0
|
||||
let expected = Some(expected);
|
||||
assert_eq!(vote_account_stakes_at_epoch(&bank, 0), expected);
|
||||
|
||||
// Second epoch carries same information
|
||||
let bank = new_from_parent(&Arc::new(bank), 1);
|
||||
assert_eq!(
|
||||
vote_account_stakes_at_epoch(&bank, 0),
|
||||
Some(expected.clone())
|
||||
);
|
||||
|
||||
expected.insert(voting_keypair.pubkey(), leader_stake.stake(1));
|
||||
assert_eq!(
|
||||
vote_account_stakes_at_epoch(&bank, 1),
|
||||
Some(expected.clone())
|
||||
);
|
||||
assert_eq!(vote_account_stakes_at_epoch(&bank, 0), expected);
|
||||
assert_eq!(vote_account_stakes_at_epoch(&bank, 1), expected);
|
||||
}
|
||||
|
||||
pub(crate) fn setup_vote_and_stake_accounts(
|
||||
|
@ -233,7 +225,7 @@ pub(crate) mod tests {
|
|||
..
|
||||
} = create_genesis_block(10_000);
|
||||
|
||||
let mut bank = Bank::new(&genesis_block);
|
||||
let bank = Bank::new(&genesis_block);
|
||||
let vote_pubkey = Pubkey::new_rand();
|
||||
|
||||
// Give the validator some stake but don't setup a staking account
|
||||
|
@ -252,23 +244,28 @@ pub(crate) mod tests {
|
|||
stake,
|
||||
);
|
||||
|
||||
// simulated stake
|
||||
let other_stake = Stake {
|
||||
stake,
|
||||
activated: bank.get_stakers_epoch(bank.slot()),
|
||||
activated: bank.epoch(),
|
||||
..Stake::default()
|
||||
};
|
||||
|
||||
let epoch = bank.get_stakers_epoch(bank.slot());
|
||||
// find the first slot in the next staker's epoch
|
||||
while bank.epoch() <= epoch {
|
||||
let slot = bank.slot() + 1;
|
||||
bank = new_from_parent(&Arc::new(bank), slot);
|
||||
let mut slot = 1;
|
||||
while bank.get_stakers_epoch(slot) <= epoch {
|
||||
slot += 1;
|
||||
}
|
||||
let bank = new_from_parent(&Arc::new(bank), slot);
|
||||
let epoch = bank.get_stakers_epoch(slot);
|
||||
|
||||
let result: Vec<_> = epoch_stakes_and_lockouts(&bank, 0);
|
||||
assert_eq!(result, vec![(leader_stake.stake(0), None)]);
|
||||
|
||||
let mut result: Vec<_> = epoch_stakes_and_lockouts(&bank, bank.epoch());
|
||||
// epoch stakes and lockouts are saved off for the future epoch, should
|
||||
// match current bank state
|
||||
let mut result: Vec<_> = epoch_stakes_and_lockouts(&bank, epoch);
|
||||
result.sort();
|
||||
let mut expected = vec![
|
||||
(leader_stake.stake(bank.epoch()), None),
|
||||
|
|
|
@ -217,7 +217,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||
new_stake,
|
||||
vote_account.unsigned_key(),
|
||||
&vote_account.state()?,
|
||||
clock.stakers_epoch,
|
||||
clock.epoch,
|
||||
);
|
||||
|
||||
self.set_state(&StakeState::Stake(stake))
|
||||
|
@ -231,7 +231,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||
}
|
||||
|
||||
if let StakeState::Stake(mut stake) = self.state()? {
|
||||
stake.deactivate(clock.stakers_epoch);
|
||||
stake.deactivate(clock.epoch);
|
||||
|
||||
self.set_state(&StakeState::Stake(stake))
|
||||
} else {
|
||||
|
@ -291,7 +291,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||
if stake.deactivated == std::u64::MAX {
|
||||
return Err(InstructionError::InsufficientFunds);
|
||||
}
|
||||
let staked = if stake.stake(clock.stakers_epoch) == 0 {
|
||||
let staked = if stake.stake(clock.epoch) == 0 {
|
||||
0
|
||||
} else {
|
||||
// Assume full stake if the stake is under warmup/cooldown
|
||||
|
@ -358,7 +358,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_stake_delegate_stake() {
|
||||
let clock = sysvar::clock::Clock {
|
||||
stakers_epoch: 1,
|
||||
epoch: 1,
|
||||
..sysvar::clock::Clock::default()
|
||||
};
|
||||
|
||||
|
@ -406,7 +406,7 @@ mod tests {
|
|||
voter_pubkey: vote_keypair.pubkey(),
|
||||
credits_observed: vote_state.credits(),
|
||||
stake: stake_lamports,
|
||||
activated: clock.stakers_epoch,
|
||||
activated: clock.epoch,
|
||||
deactivated: std::u64::MAX,
|
||||
})
|
||||
);
|
||||
|
@ -464,7 +464,7 @@ mod tests {
|
|||
Account::new(stake_lamports, std::mem::size_of::<StakeState>(), &id());
|
||||
|
||||
let clock = sysvar::clock::Clock {
|
||||
stakers_epoch: 1,
|
||||
epoch: 1,
|
||||
..sysvar::clock::Clock::default()
|
||||
};
|
||||
|
||||
|
@ -548,7 +548,7 @@ mod tests {
|
|||
// deactivate the stake before withdrawal
|
||||
assert_eq!(stake_keyed_account.deactivate_stake(&clock), Ok(()));
|
||||
// simulate time passing
|
||||
clock.stakers_epoch += STAKE_WARMUP_EPOCHS;
|
||||
clock.epoch += STAKE_WARMUP_EPOCHS;
|
||||
|
||||
// Try to withdraw more than what's available
|
||||
assert_eq!(
|
||||
|
@ -581,7 +581,7 @@ mod tests {
|
|||
|
||||
let clock = sysvar::clock::Clock::default();
|
||||
let mut future = sysvar::clock::Clock::default();
|
||||
future.stakers_epoch += 16;
|
||||
future.epoch += 16;
|
||||
|
||||
let to = Pubkey::new_rand();
|
||||
let mut to_account = Account::new(1, 0, &system_program::id());
|
||||
|
|
|
@ -301,8 +301,7 @@ impl Bank {
|
|||
{
|
||||
let stakes = bank.stakes.read().unwrap();
|
||||
for epoch in 0..=bank.get_stakers_epoch(bank.slot) {
|
||||
bank.epoch_stakes
|
||||
.insert(epoch, stakes.clone_with_epoch(epoch));
|
||||
bank.epoch_stakes.insert(epoch, stakes.clone());
|
||||
}
|
||||
}
|
||||
bank.update_clock();
|
||||
|
@ -372,7 +371,7 @@ impl Bank {
|
|||
// if my parent didn't populate for this epoch, we've
|
||||
// crossed a boundary
|
||||
if epoch_stakes.get(&epoch).is_none() {
|
||||
epoch_stakes.insert(epoch, self.stakes.read().unwrap().clone_with_epoch(epoch));
|
||||
epoch_stakes.insert(epoch, self.stakes.read().unwrap().clone());
|
||||
}
|
||||
epoch_stakes
|
||||
};
|
||||
|
@ -2488,8 +2487,10 @@ mod tests {
|
|||
let vote_accounts = parent.epoch_vote_accounts(epoch);
|
||||
assert!(vote_accounts.is_some());
|
||||
|
||||
// epoch_stakes are a snapshot at the stakers_slot_offset boundary
|
||||
// in the prior epoch (0 in this case)
|
||||
assert_eq!(
|
||||
leader_stake.stake(epoch),
|
||||
leader_stake.stake(0),
|
||||
vote_accounts.unwrap().get(&leader_vote_account).unwrap().0
|
||||
);
|
||||
|
||||
|
@ -2505,7 +2506,7 @@ mod tests {
|
|||
|
||||
assert!(child.epoch_vote_accounts(epoch).is_some());
|
||||
assert_eq!(
|
||||
leader_stake.stake(epoch),
|
||||
leader_stake.stake(child.epoch()),
|
||||
child
|
||||
.epoch_vote_accounts(epoch)
|
||||
.unwrap()
|
||||
|
@ -2515,13 +2516,22 @@ mod tests {
|
|||
);
|
||||
|
||||
// child crosses epoch boundary but isn't the first slot in the epoch, still
|
||||
// makes an epoch stakes
|
||||
// makes an epoch stakes snapshot at 1
|
||||
let child = Bank::new_from_parent(
|
||||
&parent,
|
||||
&leader_pubkey,
|
||||
SLOTS_PER_EPOCH - (STAKERS_SLOT_OFFSET % SLOTS_PER_EPOCH) + 1,
|
||||
);
|
||||
assert!(child.epoch_vote_accounts(epoch).is_some());
|
||||
assert_eq!(
|
||||
leader_stake.stake(child.epoch()),
|
||||
child
|
||||
.epoch_vote_accounts(epoch)
|
||||
.unwrap()
|
||||
.get(&leader_vote_account)
|
||||
.unwrap()
|
||||
.0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue