Skip to content

Commit

Permalink
Actively manage dead slots in AncestorHashesService (solana-labs#18912)
Browse files Browse the repository at this point in the history
  • Loading branch information
carllin authored Aug 2, 2021
1 parent c16bf02 commit 03353d5
Show file tree
Hide file tree
Showing 10 changed files with 1,170 additions and 103 deletions.
2 changes: 1 addition & 1 deletion core/benches/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1,197 changes: 1,126 additions & 71 deletions core/src/ancestor_hashes_service.rs

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions core/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions core/src/duplicate_repair_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion core/src/heaviest_subtree_fork_choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion core/src/optimistic_confirmation_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
18 changes: 9 additions & 9 deletions core/src/replay_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>,
Expand Down Expand Up @@ -2800,19 +2800,19 @@ 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,
leader_schedule_cache: Arc<LeaderScheduleCache>,
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>,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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!();
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion core/src/serve_repair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl AncestorHashesRepairType {
}
}

#[derive(Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub enum AncestorHashesResponseVersion {
Current(Vec<SlotHash>),
}
Expand Down
31 changes: 19 additions & 12 deletions core/src/vote_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion ledger/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl Blockstore {
self.db
}

pub fn ledger_path(&self) -> &Path {
pub fn ledger_path(&self) -> &PathBuf {
&self.ledger_path
}

Expand Down

0 comments on commit 03353d5

Please sign in to comment.