Actively manage dead slots in AncestorHashesService (#18912)
This commit is contained in:
parent
c16bf02448
commit
03353d500f
|
@ -59,7 +59,7 @@ fn bench_generate_ancestors_descendants(bench: &mut Bencher) {
|
||||||
let num_banks = 500;
|
let num_banks = 500;
|
||||||
let forks = tr(0);
|
let forks = tr(0);
|
||||||
let mut vote_simulator = VoteSimulator::new(2);
|
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(
|
vote_simulator.create_and_vote_new_branch(
|
||||||
0,
|
0,
|
||||||
num_banks,
|
num_banks,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1469,7 +1469,7 @@ pub mod test {
|
||||||
let mut cluster_votes = HashMap::new();
|
let mut cluster_votes = HashMap::new();
|
||||||
let votes = vec![0, 1, 2, 3, 4, 5];
|
let votes = vec![0, 1, 2, 3, 4, 5];
|
||||||
cluster_votes.insert(node_pubkey, votes.clone());
|
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
|
// Simulate the votes
|
||||||
for vote in votes {
|
for vote in votes {
|
||||||
|
@ -1526,7 +1526,7 @@ pub mod test {
|
||||||
/ tr(112))));
|
/ tr(112))));
|
||||||
|
|
||||||
// Fill the BankForks according to the above fork structure
|
// 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() {
|
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
|
||||||
fork_progress.fork_stats.computed = true;
|
fork_progress.fork_stats.computed = true;
|
||||||
}
|
}
|
||||||
|
@ -1947,7 +1947,7 @@ pub mod test {
|
||||||
let mut cluster_votes: HashMap<Pubkey, Vec<Slot>> = HashMap::new();
|
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[1], vec![46]);
|
||||||
cluster_votes.insert(vote_simulator.node_pubkeys[2], vec![47]);
|
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
|
// Vote on the first minor fork at slot 14, should succeed
|
||||||
assert!(vote_simulator
|
assert!(vote_simulator
|
||||||
|
@ -2023,7 +2023,7 @@ pub mod test {
|
||||||
// Make the other validator vote fork to pass the threshold checks
|
// Make the other validator vote fork to pass the threshold checks
|
||||||
let other_votes = my_votes.clone();
|
let other_votes = my_votes.clone();
|
||||||
cluster_votes.insert(vote_simulator.node_pubkeys[1], other_votes);
|
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.
|
// Simulate the votes.
|
||||||
for vote in &my_votes {
|
for vote in &my_votes {
|
||||||
|
@ -2567,7 +2567,7 @@ pub mod test {
|
||||||
/ (tr(110) / tr(111))))));
|
/ (tr(110) / tr(111))))));
|
||||||
|
|
||||||
// Fill the BankForks according to the above fork structure
|
// 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() {
|
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
|
||||||
fork_progress.fork_stats.computed = true;
|
fork_progress.fork_stats.computed = true;
|
||||||
}
|
}
|
||||||
|
@ -2667,7 +2667,7 @@ pub mod test {
|
||||||
let replayed_root_slot = 44;
|
let replayed_root_slot = 44;
|
||||||
|
|
||||||
// Fill the BankForks according to the above fork structure
|
// 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() {
|
for (_, fork_progress) in vote_simulator.progress.iter_mut() {
|
||||||
fork_progress.fork_stats.computed = true;
|
fork_progress.fork_stats.computed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,6 +325,11 @@ impl DeadSlotAncestorRequestStatus {
|
||||||
pub fn is_expired(&self) -> bool {
|
pub fn is_expired(&self) -> bool {
|
||||||
timestamp() - self.start_ts > RETRY_INTERVAL_SECONDS as u64 * 1000
|
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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1237,7 +1237,7 @@ mod test {
|
||||||
*/
|
*/
|
||||||
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3)));
|
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3)));
|
||||||
let mut vote_simulator = VoteSimulator::new(1);
|
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 bank_forks = vote_simulator.bank_forks;
|
||||||
let mut frozen_banks: Vec<_> = bank_forks
|
let mut frozen_banks: Vec<_> = bank_forks
|
||||||
.read()
|
.read()
|
||||||
|
|
|
@ -343,7 +343,7 @@ mod test {
|
||||||
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5) / (tr(6)))));
|
let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5) / (tr(6)))));
|
||||||
|
|
||||||
let mut vote_simulator = VoteSimulator::new(1);
|
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
|
vote_simulator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -853,7 +853,7 @@ impl ReplayStage {
|
||||||
(progress, heaviest_subtree_fork_choice)
|
(progress, heaviest_subtree_fork_choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_then_repair_correct_slots(
|
pub fn dump_then_repair_correct_slots(
|
||||||
duplicate_slots_to_repair: &mut DuplicateSlotsToRepair,
|
duplicate_slots_to_repair: &mut DuplicateSlotsToRepair,
|
||||||
ancestors: &mut HashMap<Slot, HashSet<Slot>>,
|
ancestors: &mut HashMap<Slot, HashSet<Slot>>,
|
||||||
descendants: &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));
|
assert!(ReplayStage::is_partition_detected(&ancestors, 4, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReplayBlockstoreComponents {
|
pub struct ReplayBlockstoreComponents {
|
||||||
blockstore: Arc<Blockstore>,
|
pub blockstore: Arc<Blockstore>,
|
||||||
validator_node_to_vote_keys: HashMap<Pubkey, Pubkey>,
|
validator_node_to_vote_keys: HashMap<Pubkey, Pubkey>,
|
||||||
my_pubkey: Pubkey,
|
my_pubkey: Pubkey,
|
||||||
cluster_info: ClusterInfo,
|
cluster_info: ClusterInfo,
|
||||||
|
@ -2809,10 +2809,10 @@ pub mod tests {
|
||||||
poh_recorder: Mutex<PohRecorder>,
|
poh_recorder: Mutex<PohRecorder>,
|
||||||
tower: Tower,
|
tower: Tower,
|
||||||
rpc_subscriptions: Arc<RpcSubscriptions>,
|
rpc_subscriptions: Arc<RpcSubscriptions>,
|
||||||
vote_simulator: VoteSimulator,
|
pub vote_simulator: VoteSimulator,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replay_blockstore_components(
|
pub fn replay_blockstore_components(
|
||||||
forks: Option<Tree<Slot>>,
|
forks: Option<Tree<Slot>>,
|
||||||
num_validators: usize,
|
num_validators: usize,
|
||||||
generate_votes: Option<GenerateVotes>,
|
generate_votes: Option<GenerateVotes>,
|
||||||
|
@ -3764,7 +3764,7 @@ pub mod tests {
|
||||||
|
|
||||||
// Create the tree of banks in a BankForks object
|
// Create the tree of banks in a BankForks object
|
||||||
let forks = tr(0) / (tr(1)) / (tr(2));
|
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
|
let mut frozen_banks: Vec<_> = vote_simulator
|
||||||
.bank_forks
|
.bank_forks
|
||||||
.read()
|
.read()
|
||||||
|
@ -3841,7 +3841,7 @@ pub mod tests {
|
||||||
let mut cluster_votes = HashMap::new();
|
let mut cluster_votes = HashMap::new();
|
||||||
let votes = vec![0, 2];
|
let votes = vec![0, 2];
|
||||||
cluster_votes.insert(my_node_pubkey, votes.clone());
|
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
|
// Fill banks with votes
|
||||||
for vote in votes {
|
for vote in votes {
|
||||||
|
@ -4821,7 +4821,7 @@ pub mod tests {
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.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 (bank_forks, mut progress) = (vote_simulator.bank_forks, vote_simulator.progress);
|
||||||
let ledger_path = get_tmp_ledger_path!();
|
let ledger_path = get_tmp_ledger_path!();
|
||||||
|
@ -5721,7 +5721,7 @@ pub mod tests {
|
||||||
let cluster_votes = generate_votes
|
let cluster_votes = generate_votes
|
||||||
.map(|generate_votes| generate_votes(pubkeys))
|
.map(|generate_votes| generate_votes(pubkeys))
|
||||||
.unwrap_or_default();
|
.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 ledger_path = get_tmp_ledger_path!();
|
||||||
let blockstore = Blockstore::open(&ledger_path).unwrap();
|
let blockstore = Blockstore::open(&ledger_path).unwrap();
|
||||||
blockstore.add_tree(tree, false, true, 2, Hash::default());
|
blockstore.add_tree(tree, false, true, 2, Hash::default());
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl AncestorHashesRepairType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum AncestorHashesResponseVersion {
|
pub enum AncestorHashesResponseVersion {
|
||||||
Current(Vec<SlotHash>),
|
Current(Vec<SlotHash>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,12 @@ impl VoteSimulator {
|
||||||
latest_validator_votes_for_frozen_banks: LatestValidatorVotesForFrozenBanks::default(),
|
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();
|
let root = *forks.root().data();
|
||||||
assert!(self.bank_forks.read().unwrap().get(root).is_some());
|
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() {
|
while new_bank.tick_height() < new_bank.max_tick_height() {
|
||||||
new_bank.register_tick(&Hash::new_unique());
|
new_bank.register_tick(&Hash::new_unique());
|
||||||
}
|
}
|
||||||
new_bank.freeze();
|
if !visit.node().has_no_child() || is_frozen {
|
||||||
self.progress
|
new_bank.freeze();
|
||||||
.get_fork_stats_mut(new_bank.slot())
|
self.progress
|
||||||
.expect("All frozen banks must exist in the Progress map")
|
.get_fork_stats_mut(new_bank.slot())
|
||||||
.bank_hash = Some(new_bank.hash());
|
.expect("All frozen banks must exist in the Progress map")
|
||||||
self.heaviest_subtree_fork_choice.add_new_leaf_slot(
|
.bank_hash = Some(new_bank.hash());
|
||||||
(new_bank.slot(), new_bank.hash()),
|
self.heaviest_subtree_fork_choice.add_new_leaf_slot(
|
||||||
Some((new_bank.parent_slot(), new_bank.parent_hash())),
|
(new_bank.slot(), new_bank.hash()),
|
||||||
);
|
Some((new_bank.parent_slot(), new_bank.parent_hash())),
|
||||||
|
);
|
||||||
|
}
|
||||||
self.bank_forks.write().unwrap().insert(new_bank);
|
self.bank_forks.write().unwrap().insert(new_bank);
|
||||||
|
|
||||||
walk.forward();
|
walk.forward();
|
||||||
|
@ -221,7 +228,7 @@ impl VoteSimulator {
|
||||||
.filter_map(|slot| {
|
.filter_map(|slot| {
|
||||||
let mut fork_tip_parent = tr(slot - 1);
|
let mut fork_tip_parent = tr(slot - 1);
|
||||||
fork_tip_parent.push_front(tr(slot));
|
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) {
|
if votes_to_simulate.contains(&slot) {
|
||||||
Some((slot, self.simulate_vote(slot, my_pubkey, tower)))
|
Some((slot, self.simulate_vote(slot, my_pubkey, tower)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -264,7 +271,7 @@ impl VoteSimulator {
|
||||||
let mut fork_tip_parent = tr(start_slot + i - 1);
|
let mut fork_tip_parent = tr(start_slot + i - 1);
|
||||||
// The tip of the fork
|
// The tip of the fork
|
||||||
fork_tip_parent.push_front(tr(start_slot + i));
|
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
|
if self
|
||||||
.simulate_vote(i + start_slot, my_pubkey, tower)
|
.simulate_vote(i + start_slot, my_pubkey, tower)
|
||||||
.is_empty()
|
.is_empty()
|
||||||
|
|
|
@ -284,7 +284,7 @@ impl Blockstore {
|
||||||
self.db
|
self.db
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ledger_path(&self) -> &Path {
|
pub fn ledger_path(&self) -> &PathBuf {
|
||||||
&self.ledger_path
|
&self.ledger_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue