Fix propagation on startup from snapshot (#12177)
This commit is contained in:
parent
484c8cb8a8
commit
9c490e06b0
|
@ -168,7 +168,7 @@ impl ForkProgress {
|
||||||
num_dropped_blocks_on_fork: u64,
|
num_dropped_blocks_on_fork: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let validator_fork_info = {
|
let validator_fork_info = {
|
||||||
if bank.collector_id() == my_pubkey && bank.slot() > 0 {
|
if bank.collector_id() == my_pubkey {
|
||||||
let stake = bank.epoch_vote_account_stake(voting_pubkey);
|
let stake = bank.epoch_vote_account_stake(voting_pubkey);
|
||||||
Some(ValidatorStakeInfo::new(
|
Some(ValidatorStakeInfo::new(
|
||||||
*voting_pubkey,
|
*voting_pubkey,
|
||||||
|
|
|
@ -1594,13 +1594,13 @@ impl ReplayStage {
|
||||||
loop {
|
loop {
|
||||||
// These cases mean confirmation of propagation on any earlier
|
// These cases mean confirmation of propagation on any earlier
|
||||||
// leader blocks must have been reached
|
// leader blocks must have been reached
|
||||||
if current_leader_slot == None || current_leader_slot.unwrap() <= root {
|
if current_leader_slot == None || current_leader_slot.unwrap() < root {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let leader_propagated_stats = progress
|
let leader_propagated_stats = progress
|
||||||
.get_propagated_stats_mut(current_leader_slot.unwrap())
|
.get_propagated_stats_mut(current_leader_slot.unwrap())
|
||||||
.expect("current_leader_slot > root, so must exist in the progress map");
|
.expect("current_leader_slot >= root, so must exist in the progress map");
|
||||||
|
|
||||||
// If a descendant has reached propagation threshold, then
|
// If a descendant has reached propagation threshold, then
|
||||||
// all its ancestor banks have also reached propagation
|
// all its ancestor banks have also reached propagation
|
||||||
|
@ -3319,6 +3319,10 @@ pub(crate) mod tests {
|
||||||
let stake_per_validator = 10_000;
|
let stake_per_validator = 10_000;
|
||||||
let (mut bank_forks, mut progress_map, _) =
|
let (mut bank_forks, mut progress_map, _) =
|
||||||
initialize_state(&keypairs, stake_per_validator);
|
initialize_state(&keypairs, stake_per_validator);
|
||||||
|
progress_map
|
||||||
|
.get_propagated_stats_mut(0)
|
||||||
|
.unwrap()
|
||||||
|
.is_leader_slot = true;
|
||||||
bank_forks.set_root(0, &None, None);
|
bank_forks.set_root(0, &None, None);
|
||||||
let total_epoch_stake = bank_forks.root_bank().total_epoch_stake();
|
let total_epoch_stake = bank_forks.root_bank().total_epoch_stake();
|
||||||
|
|
||||||
|
@ -3396,6 +3400,10 @@ pub(crate) mod tests {
|
||||||
let stake_per_validator = 10_000;
|
let stake_per_validator = 10_000;
|
||||||
let (mut bank_forks, mut progress_map, _) =
|
let (mut bank_forks, mut progress_map, _) =
|
||||||
initialize_state(&keypairs, stake_per_validator);
|
initialize_state(&keypairs, stake_per_validator);
|
||||||
|
progress_map
|
||||||
|
.get_propagated_stats_mut(0)
|
||||||
|
.unwrap()
|
||||||
|
.is_leader_slot = true;
|
||||||
bank_forks.set_root(0, &None, None);
|
bank_forks.set_root(0, &None, None);
|
||||||
|
|
||||||
let total_epoch_stake = num_validators as u64 * stake_per_validator;
|
let total_epoch_stake = num_validators as u64 * stake_per_validator;
|
||||||
|
@ -3728,6 +3736,70 @@ pub(crate) mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_leader_snapshot_restart_propagation() {
|
||||||
|
let ReplayBlockstoreComponents {
|
||||||
|
validator_voting_keys,
|
||||||
|
mut progress,
|
||||||
|
bank_forks,
|
||||||
|
leader_schedule_cache,
|
||||||
|
..
|
||||||
|
} = replay_blockstore_components();
|
||||||
|
|
||||||
|
let root_bank = bank_forks.read().unwrap().root_bank().clone();
|
||||||
|
let my_pubkey = leader_schedule_cache
|
||||||
|
.slot_leader_at(root_bank.slot(), Some(&root_bank))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Check that we are the leader of the root bank
|
||||||
|
assert!(
|
||||||
|
progress
|
||||||
|
.get_propagated_stats(root_bank.slot())
|
||||||
|
.unwrap()
|
||||||
|
.is_leader_slot
|
||||||
|
);
|
||||||
|
let ancestors = bank_forks.read().unwrap().ancestors();
|
||||||
|
|
||||||
|
// Freeze bank so it shows up in frozen banks
|
||||||
|
root_bank.freeze();
|
||||||
|
let mut frozen_banks: Vec<_> = bank_forks
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.frozen_banks()
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Compute bank stats, make sure vote is propagated back to starting root bank
|
||||||
|
let vote_tracker = VoteTracker::default();
|
||||||
|
|
||||||
|
// Add votes
|
||||||
|
for vote_key in validator_voting_keys.values() {
|
||||||
|
vote_tracker.insert_vote(root_bank.slot(), Arc::new(*vote_key));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(!progress.is_propagated(root_bank.slot()));
|
||||||
|
|
||||||
|
// Update propagation status
|
||||||
|
let tower = Tower::new_for_tests(0, 0.67);
|
||||||
|
ReplayStage::compute_bank_stats(
|
||||||
|
&my_pubkey,
|
||||||
|
&ancestors,
|
||||||
|
&mut frozen_banks,
|
||||||
|
&tower,
|
||||||
|
&mut progress,
|
||||||
|
&vote_tracker,
|
||||||
|
&ClusterSlots::default(),
|
||||||
|
&bank_forks,
|
||||||
|
&mut PubkeyReferences::default(),
|
||||||
|
&mut HeaviestSubtreeForkChoice::new_from_bank_forks(&bank_forks.read().unwrap()),
|
||||||
|
&mut BankWeightForkChoice::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check status is true
|
||||||
|
assert!(progress.is_propagated(root_bank.slot()));
|
||||||
|
}
|
||||||
|
|
||||||
fn setup_forks() -> (RwLock<BankForks>, ProgressMap) {
|
fn setup_forks() -> (RwLock<BankForks>, ProgressMap) {
|
||||||
/*
|
/*
|
||||||
Build fork structure:
|
Build fork structure:
|
||||||
|
|
Loading…
Reference in New Issue