parent
7021e1c584
commit
fb8e2d8cdb
|
@ -10,13 +10,15 @@ use solana_sdk::{
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashMap, HashSet},
|
collections::{BTreeMap, HashMap, HashSet, VecDeque},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
time::Instant,
|
||||||
};
|
};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use trees::{Tree, TreeWalk};
|
use trees::{Tree, TreeWalk};
|
||||||
|
|
||||||
pub type ForkWeight = u64;
|
pub type ForkWeight = u64;
|
||||||
|
const MAX_ROOT_PRINT_SECONDS: u64 = 30;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord)]
|
#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord)]
|
||||||
enum UpdateLabel {
|
enum UpdateLabel {
|
||||||
|
@ -55,18 +57,22 @@ struct ForkInfo {
|
||||||
children: Vec<Slot>,
|
children: Vec<Slot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct HeaviestSubtreeForkChoice {
|
pub struct HeaviestSubtreeForkChoice {
|
||||||
fork_infos: HashMap<Slot, ForkInfo>,
|
fork_infos: HashMap<Slot, ForkInfo>,
|
||||||
latest_votes: HashMap<Pubkey, Slot>,
|
latest_votes: HashMap<Pubkey, Slot>,
|
||||||
root: Slot,
|
root: Slot,
|
||||||
|
last_root_time: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeaviestSubtreeForkChoice {
|
impl HeaviestSubtreeForkChoice {
|
||||||
pub(crate) fn new(root: Slot) -> Self {
|
pub(crate) fn new(root: Slot) -> Self {
|
||||||
let mut heaviest_subtree_fork_choice = Self {
|
let mut heaviest_subtree_fork_choice = Self {
|
||||||
root,
|
root,
|
||||||
..HeaviestSubtreeForkChoice::default()
|
// Doesn't implement default because `root` must
|
||||||
|
// exist in all the fields
|
||||||
|
fork_infos: HashMap::new(),
|
||||||
|
latest_votes: HashMap::new(),
|
||||||
|
last_root_time: Instant::now(),
|
||||||
};
|
};
|
||||||
heaviest_subtree_fork_choice.add_new_leaf_slot(root, None);
|
heaviest_subtree_fork_choice.add_new_leaf_slot(root, None);
|
||||||
heaviest_subtree_fork_choice
|
heaviest_subtree_fork_choice
|
||||||
|
@ -153,6 +159,7 @@ impl HeaviestSubtreeForkChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_root(&mut self, root: Slot) {
|
pub fn set_root(&mut self, root: Slot) {
|
||||||
|
self.last_root_time = Instant::now();
|
||||||
self.root = root;
|
self.root = root;
|
||||||
let mut pending_slots = vec![root];
|
let mut pending_slots = vec![root];
|
||||||
let mut new_fork_infos = HashMap::new();
|
let mut new_fork_infos = HashMap::new();
|
||||||
|
@ -176,6 +183,11 @@ impl HeaviestSubtreeForkChoice {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_new_leaf_slot(&mut self, slot: Slot, parent: Option<Slot>) {
|
pub fn add_new_leaf_slot(&mut self, slot: Slot, parent: Option<Slot>) {
|
||||||
|
if self.last_root_time.elapsed().as_secs() > MAX_ROOT_PRINT_SECONDS {
|
||||||
|
self.print_state();
|
||||||
|
self.last_root_time = Instant::now();
|
||||||
|
}
|
||||||
|
|
||||||
self.fork_infos
|
self.fork_infos
|
||||||
.entry(slot)
|
.entry(slot)
|
||||||
.and_modify(|slot_info| slot_info.parent = parent)
|
.and_modify(|slot_info| slot_info.parent = parent)
|
||||||
|
@ -401,6 +413,17 @@ impl HeaviestSubtreeForkChoice {
|
||||||
.unwrap_or(None)
|
.unwrap_or(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_state(&self) {
|
||||||
|
let best_slot = self.best_overall_slot();
|
||||||
|
let mut best_path: VecDeque<_> = self.ancestor_iterator(best_slot).collect();
|
||||||
|
best_path.push_front(best_slot);
|
||||||
|
info!(
|
||||||
|
"Latest known votes by vote pubkey: {:#?}, best path: {:?}",
|
||||||
|
self.latest_votes,
|
||||||
|
best_path.iter().rev().collect::<Vec<&Slot>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn stake_voted_at(&self, slot: Slot) -> Option<u64> {
|
fn stake_voted_at(&self, slot: Slot) -> Option<u64> {
|
||||||
self.fork_infos
|
self.fork_infos
|
||||||
|
|
Loading…
Reference in New Issue