Skip to content

Commit

Permalink
unrelated: reachability docs
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsutton committed Nov 15, 2024
1 parent 0da94d7 commit 072bac7
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
21 changes: 21 additions & 0 deletions consensus/src/model/services/reachability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,35 @@ use crate::processes::reachability::{inquirer, Result};
use kaspa_hashes::Hash;

pub trait ReachabilityService {
/// Checks if `this` block is a chain ancestor of `queried` block (i.e., `this ∈ chain(queried) ∪ {queried}`).
/// Note that we use the graph theory convention here which defines that a block is also an ancestor of itself.
fn is_chain_ancestor_of(&self, this: Hash, queried: Hash) -> bool;

/// Result version of [`is_dag_ancestor_of`] (avoids unwrapping internally)
fn is_dag_ancestor_of_result(&self, this: Hash, queried: Hash) -> Result<bool>;

/// Returns true if `this` is a DAG ancestor of `queried` (i.e., `queried ∈ future(this) ∪ {this}`).
/// Note: this method will return true if `this == queried`.
/// The complexity of this method is `O(log(|future_covering_set(this)|))`
fn is_dag_ancestor_of(&self, this: Hash, queried: Hash) -> bool;

/// Checks if `this` is DAG ancestor of any of the blocks in `queried`. See [`is_dag_ancestor_of`] as well.
fn is_dag_ancestor_of_any(&self, this: Hash, queried: &mut impl Iterator<Item = Hash>) -> bool;

/// Checks if any of the blocks in `list` is DAG ancestor of `queried`. See [`is_dag_ancestor_of`] as well.
fn is_any_dag_ancestor(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> bool;

/// Result version of [`is_any_dag_ancestor`] (avoids unwrapping internally)
fn is_any_dag_ancestor_result(&self, list: &mut impl Iterator<Item = Hash>, queried: Hash) -> Result<bool>;

/// Finds the tree child of `ancestor` which is also a chain ancestor of `descendant`.
/// (A "tree child of X" is a block which X is its chain parent)
fn get_next_chain_ancestor(&self, descendant: Hash, ancestor: Hash) -> Hash;

/// Returns the chain parent of `this`
fn get_chain_parent(&self, this: Hash) -> Hash;

/// Checks whether `this` has reachability data
fn has_reachability_data(&self, this: Hash) -> bool;
}

Expand Down
12 changes: 6 additions & 6 deletions consensus/src/processes/reachability/inquirer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,21 @@ pub fn hint_virtual_selected_parent(store: &mut (impl ReachabilityStore + ?Sized
)
}

/// Checks if the `this` block is a strict chain ancestor of the `queried` block (aka `this ∈ chain(queried)`).
/// Checks if the `this` block is a strict chain ancestor of the `queried` block (i.e., `this ∈ chain(queried)`).
/// Note that this results in `false` if `this == queried`
pub fn is_strict_chain_ancestor_of(store: &(impl ReachabilityStoreReader + ?Sized), this: Hash, queried: Hash) -> Result<bool> {
Ok(store.get_interval(this)?.strictly_contains(store.get_interval(queried)?))
}

/// Checks if `this` block is a chain ancestor of `queried` block (aka `this ∈ chain(queried) ∪ {queried}`).
/// Checks if `this` block is a chain ancestor of `queried` block (i.e., `this ∈ chain(queried) ∪ {queried}`).
/// Note that we use the graph theory convention here which defines that a block is also an ancestor of itself.
pub fn is_chain_ancestor_of(store: &(impl ReachabilityStoreReader + ?Sized), this: Hash, queried: Hash) -> Result<bool> {
Ok(store.get_interval(this)?.contains(store.get_interval(queried)?))
}

/// Returns true if `this` is a DAG ancestor of `queried` (aka `queried ∈ future(this) ∪ {this}`).
/// Returns true if `this` is a DAG ancestor of `queried` (i.e., `queried ∈ future(this) ∪ {this}`).
/// Note: this method will return true if `this == queried`.
/// The complexity of this method is O(log(|future_covering_set(this)|))
/// The complexity of this method is `O(log(|future_covering_set(this)|))`
pub fn is_dag_ancestor_of(store: &(impl ReachabilityStoreReader + ?Sized), this: Hash, queried: Hash) -> Result<bool> {
// First, check if `this` is a chain ancestor of queried
if is_chain_ancestor_of(store, this, queried)? {
Expand All @@ -184,7 +184,7 @@ pub fn is_dag_ancestor_of(store: &(impl ReachabilityStoreReader + ?Sized), this:
}
}

/// Finds the child of `ancestor` which is also a chain ancestor of `descendant`.
/// Finds the tree child of `ancestor` which is also a chain ancestor of `descendant`.
pub fn get_next_chain_ancestor(store: &(impl ReachabilityStoreReader + ?Sized), descendant: Hash, ancestor: Hash) -> Result<Hash> {
if descendant == ancestor {
// The next ancestor does not exist
Expand All @@ -200,7 +200,7 @@ pub fn get_next_chain_ancestor(store: &(impl ReachabilityStoreReader + ?Sized),
}

/// Note: it is important to keep the unchecked version for internal module use,
/// since in some scenarios during reindexing `descendant` might have a modified
/// since in some scenarios during reindexing `ancestor` might have a modified
/// interval which was not propagated yet.
pub(super) fn get_next_chain_ancestor_unchecked(
store: &(impl ReachabilityStoreReader + ?Sized),
Expand Down

0 comments on commit 072bac7

Please sign in to comment.