From fed0faf66066c76f2d932ddacd800d45e3e35677 Mon Sep 17 00:00:00 2001 From: coderofstuff <114628839+coderofstuff@users.noreply.github.com> Date: Wed, 29 Jan 2025 23:57:48 -0700 Subject: [PATCH] Refactor pruning proof least common ancestor in store logic --- .../src/processes/pruning_proof/build.rs | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/consensus/src/processes/pruning_proof/build.rs b/consensus/src/processes/pruning_proof/build.rs index 3dfe6d939..29f8c2cc1 100644 --- a/consensus/src/processes/pruning_proof/build.rs +++ b/consensus/src/processes/pruning_proof/build.rs @@ -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 { relations_store: T, @@ -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 }; @@ -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 { + // 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. @@ -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, ); @@ -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));