Skip to content

Commit

Permalink
Refactor pruning proof least common ancestor in store logic
Browse files Browse the repository at this point in the history
  • Loading branch information
coderofstuff committed Jan 30, 2025
1 parent 015735c commit 47bb54c
Showing 1 changed file with 43 additions and 25 deletions.
68 changes: 43 additions & 25 deletions consensus/src/processes/pruning_proof/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ use crate::{

use super::{PruningProofManager, PruningProofManagerInternalResult};

// The amount of extra depth we try to create per level after the usual 2M
const SAFETY_MARGIN: u64 = 100;

#[derive(Clone)]
struct RelationsStoreInFutureOfRoot<T: RelationsStoreReader, U: ReachabilityService> {
relations_store: T,
Expand Down Expand Up @@ -91,19 +94,14 @@ impl PruningProofManager {
.block_at_depth(&*ghostdag_stores[level + 1], selected_tip_by_level[level + 1], self.pruning_proof_m)
.map_err(|err| format!("level + 1: {}, err: {}", level + 1, err))
.unwrap();
if self.reachability_service.is_dag_ancestor_of(block_at_depth_m_at_next_level, block_at_depth_2m) {
block_at_depth_m_at_next_level
} else if self.reachability_service.is_dag_ancestor_of(block_at_depth_2m, block_at_depth_m_at_next_level) {
block_at_depth_2m
} else {
self.find_common_ancestor_in_chain_of_a(
&*ghostdag_stores[level],
block_at_depth_m_at_next_level,
block_at_depth_2m,
)
.map_err(|err| format!("level: {}, err: {}", level, err))
.unwrap()
}

self.find_least_common_ancestor_in_store(
&*ghostdag_stores[level],
block_at_depth_m_at_next_level,
block_at_depth_2m,
)
.map_err(|err| format!("level: {}, err: {}", level, err))
.unwrap()
} else {
block_at_depth_2m
};
Expand Down Expand Up @@ -204,6 +202,33 @@ impl PruningProofManager {
)
}

/// Given two hashes (both are assumed to exist in the passed ghostdag store),
/// find their least common ancestor. The least common ancestor is minimum block
/// such that both 'a' and 'b' are either equal to it or in its future.
/// This ancestor must also be in the selected parent chain of 'a'.
///
/// Additional Notes:
/// - 'a' and 'b' are expected to be hashes acquired via block_at_depth.
/// By virtue of this, they are both chain block hashes.
fn find_least_common_ancestor_in_store(
&self,
ghostdag_store: &DbGhostdagStore,
a: Hash,
b: Hash,
) -> Result<Hash, PruningProofManagerInternalError> {
// These two hashes are expected to be acquired from the passed ghostdag store
assert!(ghostdag_store.has(a).unwrap());
assert!(ghostdag_store.has(b).unwrap());

if self.reachability_service.is_dag_ancestor_of(a, b) {
Ok(a)
} else if self.reachability_service.is_dag_ancestor_of(b, a) {
Ok(b)
} else {
self.find_common_ancestor_in_chain_of_a(ghostdag_store, a, b)
}
}

/// Find a sufficient root at a given level by going through the headers store and looking
/// for a deep enough level block
/// For each root candidate, fill in the ghostdag data to see if it actually is deep enough.
Expand Down Expand Up @@ -234,7 +259,7 @@ impl PruningProofManager {
// We need to look deeper at higher levels (2x deeper every level) to find 2M (plus margin) blocks at that level
let mut required_base_level_depth = self.estimated_blue_depth_at_level_0(
level,
required_level_depth + 100, // We take a safety margin
required_level_depth + SAFETY_MARGIN, // We take a safety margin
current_dag_level,
);

Expand Down Expand Up @@ -295,23 +320,16 @@ impl PruningProofManager {
if root != self.genesis_hash {
// Try to adjust the root forward with the new known block_at_depth_2m_buffered
let block_at_depth_2m_buffered =
self.block_at_depth(&*ghostdag_store, selected_tip, required_level_depth + 100).unwrap();
self.block_at_depth(&*ghostdag_store, selected_tip, required_level_depth + SAFETY_MARGIN).unwrap();

root = if self.reachability_service.is_dag_ancestor_of(block_at_depth_2m_buffered, block_at_depth_m_at_next_level)
{
block_at_depth_2m_buffered
} else if self.reachability_service.is_dag_ancestor_of(block_at_depth_m_at_next_level, block_at_depth_2m_buffered)
{
block_at_depth_m_at_next_level
} else {
self.find_common_ancestor_in_chain_of_a(
root = self
.find_least_common_ancestor_in_store(
&*ghostdag_store,
block_at_depth_m_at_next_level,
block_at_depth_2m_buffered,
)
.map_err(|err| format!("level: {}, err: {}", level, err))
.unwrap()
};
.unwrap();
}

break Ok((ghostdag_store, selected_tip, root));
Expand Down

0 comments on commit 47bb54c

Please sign in to comment.