Actively manage dead slots in AncestorHashesService (#18912)

This commit is contained in:
carllin 2021-08-02 14:33:28 -07:00 committed by GitHub
parent c16bf02448
commit 03353d500f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1171 additions and 104 deletions

View File

@ -59,7 +59,7 @@ fn bench_generate_ancestors_descendants(bench: &mut Bencher) {
let num_banks = 500;
let forks = tr(0);
let mut vote_simulator = VoteSimulator::new(2);
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
vote_simulator.create_and_vote_new_branch(
0,
num_banks,

File diff suppressed because it is too large Load Diff

View File

@ -1469,7 +1469,7 @@ pub mod test {
let mut cluster_votes = HashMap::new();
let votes = vec![0, 1, 2, 3, 4, 5];
cluster_votes.insert(node_pubkey, votes.clone());
vote_simulator.fill_bank_forks(forks, &cluster_votes);
vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
// Simulate the votes
for vote in votes {
@ -1526,7 +1526,7 @@ pub mod test {
/ tr(112))));
// Fill the BankForks according to the above fork structure
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
fork_progress.fork_stats.computed = true;
}
@ -1947,7 +1947,7 @@ pub mod test {
let mut cluster_votes: HashMap<Pubkey, Vec<Slot>> = HashMap::new();
cluster_votes.insert(vote_simulator.node_pubkeys[1], vec![46]);
cluster_votes.insert(vote_simulator.node_pubkeys[2], vec![47]);
vote_simulator.fill_bank_forks(forks, &cluster_votes);
vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
// Vote on the first minor fork at slot 14, should succeed
assert!(vote_simulator
@ -2023,7 +2023,7 @@ pub mod test {
// Make the other validator vote fork to pass the threshold checks
let other_votes = my_votes.clone();
cluster_votes.insert(vote_simulator.node_pubkeys[1], other_votes);
vote_simulator.fill_bank_forks(forks, &cluster_votes);
vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
// Simulate the votes.
for vote in &my_votes {
@ -2567,7 +2567,7 @@ pub mod test {
/ (tr(110) / tr(111))))));
// Fill the BankForks according to the above fork structure
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
fork_progress.fork_stats.computed = true;
}
@ -2667,7 +2667,7 @@ pub mod test {
let replayed_root_slot = 44;
// Fill the BankForks according to the above fork structure
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
fork_progress.fork_stats.computed = true;
}

View File

@ -325,6 +325,11 @@ impl DeadSlotAncestorRequestStatus {
pub fn is_expired(&self) -> bool {
timestamp() - self.start_ts > RETRY_INTERVAL_SECONDS as u64 * 1000
}
#[cfg(test)]
pub fn make_expired(&mut self) {
self.start_ts = timestamp() - RETRY_INTERVAL_SECONDS as u64 * 1000 - 1;
}
}
#[cfg(test)]

View File

@ -1237,7 +1237,7 @@ mod test {
*/
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3)));
let mut vote_simulator = VoteSimulator::new(1);
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
let bank_forks = vote_simulator.bank_forks;
let mut frozen_banks: Vec<_> = bank_forks
.read()

View File

@ -343,7 +343,7 @@ mod test {
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5) / (tr(6)))));
let mut vote_simulator = VoteSimulator::new(1);
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
vote_simulator
}
}

View File

@ -853,7 +853,7 @@ impl ReplayStage {
(progress, heaviest_subtree_fork_choice)
}
fn dump_then_repair_correct_slots(
pub fn dump_then_repair_correct_slots(
duplicate_slots_to_repair: &mut DuplicateSlotsToRepair,
ancestors: &mut HashMap<Slot, HashSet<Slot>>,
descendants: &mut HashMap<Slot, HashSet<Slot>>,
@ -2800,8 +2800,8 @@ pub mod tests {
assert!(ReplayStage::is_partition_detected(&ancestors, 4, 3));
}
struct ReplayBlockstoreComponents {
blockstore: Arc<Blockstore>,
pub struct ReplayBlockstoreComponents {
pub blockstore: Arc<Blockstore>,
validator_node_to_vote_keys: HashMap<Pubkey, Pubkey>,
my_pubkey: Pubkey,
cluster_info: ClusterInfo,
@ -2809,10 +2809,10 @@ pub mod tests {
poh_recorder: Mutex<PohRecorder>,
tower: Tower,
rpc_subscriptions: Arc<RpcSubscriptions>,
vote_simulator: VoteSimulator,
pub vote_simulator: VoteSimulator,
}
fn replay_blockstore_components(
pub fn replay_blockstore_components(
forks: Option<Tree<Slot>>,
num_validators: usize,
generate_votes: Option<GenerateVotes>,
@ -3764,7 +3764,7 @@ pub mod tests {
// Create the tree of banks in a BankForks object
let forks = tr(0) / (tr(1)) / (tr(2));
vote_simulator.fill_bank_forks(forks, &HashMap::new());
vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
let mut frozen_banks: Vec<_> = vote_simulator
.bank_forks
.read()
@ -3841,7 +3841,7 @@ pub mod tests {
let mut cluster_votes = HashMap::new();
let votes = vec![0, 2];
cluster_votes.insert(my_node_pubkey, votes.clone());
vote_simulator.fill_bank_forks(forks, &cluster_votes);
vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
// Fill banks with votes
for vote in votes {
@ -4821,7 +4821,7 @@ pub mod tests {
]
.into_iter()
.collect();
vote_simulator.fill_bank_forks(forks, &validator_votes);
vote_simulator.fill_bank_forks(forks, &validator_votes, true);
let (bank_forks, mut progress) = (vote_simulator.bank_forks, vote_simulator.progress);
let ledger_path = get_tmp_ledger_path!();
@ -5721,7 +5721,7 @@ pub mod tests {
let cluster_votes = generate_votes
.map(|generate_votes| generate_votes(pubkeys))
.unwrap_or_default();
vote_simulator.fill_bank_forks(tree.clone(), &cluster_votes);
vote_simulator.fill_bank_forks(tree.clone(), &cluster_votes, true);
let ledger_path = get_tmp_ledger_path!();
let blockstore = Blockstore::open(&ledger_path).unwrap();
blockstore.add_tree(tree, false, true, 2, Hash::default());

View File

@ -102,7 +102,7 @@ impl AncestorHashesRepairType {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub enum AncestorHashesResponseVersion {
Current(Vec<SlotHash>),
}

View File

@ -56,7 +56,12 @@ impl VoteSimulator {
latest_validator_votes_for_frozen_banks: LatestValidatorVotesForFrozenBanks::default(),
}
}
pub fn fill_bank_forks(&mut self, forks: Tree<u64>, cluster_votes: &HashMap<Pubkey, Vec<u64>>) {
pub fn fill_bank_forks(
&mut self,
forks: Tree<u64>,
cluster_votes: &HashMap<Pubkey, Vec<u64>>,
is_frozen: bool,
) {
let root = *forks.root().data();
assert!(self.bank_forks.read().unwrap().get(root).is_some());
@ -107,15 +112,17 @@ impl VoteSimulator {
while new_bank.tick_height() < new_bank.max_tick_height() {
new_bank.register_tick(&Hash::new_unique());
}
new_bank.freeze();
self.progress
.get_fork_stats_mut(new_bank.slot())
.expect("All frozen banks must exist in the Progress map")
.bank_hash = Some(new_bank.hash());
self.heaviest_subtree_fork_choice.add_new_leaf_slot(
(new_bank.slot(), new_bank.hash()),
Some((new_bank.parent_slot(), new_bank.parent_hash())),
);
if !visit.node().has_no_child() || is_frozen {
new_bank.freeze();
self.progress
.get_fork_stats_mut(new_bank.slot())
.expect("All frozen banks must exist in the Progress map")
.bank_hash = Some(new_bank.hash());
self.heaviest_subtree_fork_choice.add_new_leaf_slot(
(new_bank.slot(), new_bank.hash()),
Some((new_bank.parent_slot(), new_bank.parent_hash())),
);
}
self.bank_forks.write().unwrap().insert(new_bank);
walk.forward();
@ -221,7 +228,7 @@ impl VoteSimulator {
.filter_map(|slot| {
let mut fork_tip_parent = tr(slot - 1);
fork_tip_parent.push_front(tr(slot));
self.fill_bank_forks(fork_tip_parent, cluster_votes);
self.fill_bank_forks(fork_tip_parent, cluster_votes, true);
if votes_to_simulate.contains(&slot) {
Some((slot, self.simulate_vote(slot, my_pubkey, tower)))
} else {
@ -264,7 +271,7 @@ impl VoteSimulator {
let mut fork_tip_parent = tr(start_slot + i - 1);
// The tip of the fork
fork_tip_parent.push_front(tr(start_slot + i));
self.fill_bank_forks(fork_tip_parent, cluster_votes);
self.fill_bank_forks(fork_tip_parent, cluster_votes, true);
if self
.simulate_vote(i + start_slot, my_pubkey, tower)
.is_empty()

View File

@ -284,7 +284,7 @@ impl Blockstore {
self.db
}
pub fn ledger_path(&self) -> &Path {
pub fn ledger_path(&self) -> &PathBuf {
&self.ledger_path
}