Skip to content

Commit 521789e

Browse files
committed
Remove all unused functions and cleanup comments
1 parent 935a657 commit 521789e

1 file changed

Lines changed: 3 additions & 292 deletions

File tree

  • consensus/src/processes/pruning_proof

‎consensus/src/processes/pruning_proof/build.rs‎

Lines changed: 3 additions & 292 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ impl<T: RelationsStoreReader, U: ReachabilityService> RelationsStoreReader for R
5757
hashes
5858
.iter()
5959
.copied()
60-
// TODO(relaxed): consider removing this filtering altogether - in the context this is currently called
61-
// blocks should not be inserted if they do not fulfill this condition
62-
.filter(|h| self.reachability_service.is_dag_ancestor_of_result(self.root, *h).optional().unwrap().unwrap_or(false))
60+
.filter(|h| {
61+
self.reachability_service.is_dag_ancestor_of_result(self.root, *h).optional().unwrap().unwrap_or(false)
62+
})
6363
.collect_vec(),
6464
)
6565
})
@@ -199,9 +199,6 @@ impl PruningProofManager {
199199
}
200200

201201
fn calc_all_level_proof_stores(&self, pp_header: &HeaderWithBlockLevel, temp_db: Arc<DB>) -> MultiLevelProofContext {
202-
// TODO: Uncomment line and send as argument to find_sufficiently_deep_level_root
203-
// once full fix to minimize proof sizes comes
204-
// let current_dag_level = self.find_current_dag_level(&pp_header.header);
205202
let mut level_proof_stores_vec: Vec<Option<LevelProofContext>> = vec![None; (self.max_block_level + 1).into()];
206203
for level in (0..=self.max_block_level).rev() {
207204
let level_usize = level as usize;
@@ -229,75 +226,6 @@ impl PruningProofManager {
229226
MultiLevelProofContext { transient_ghostdag_stores, transient_relations_stores, selected_tip_by_level, roots_by_level }
230227
}
231228

232-
/// Builds and returns a store of parents-children relations at a given level
233-
/// to facilitate forward traversal of a snippet of the Dag at that level.
234-
/// This relation store contains all reachable blocks
235-
/// that belong in the future of root and the past of tip.
236-
/// Non reachable blocks are filtered out as they are not conceptually a part of the Dag at that level
237-
/// but simply remain in node storage for other reasons.
238-
fn populate_relation_store_at_level(
239-
&self,
240-
temp_db: Arc<DB>,
241-
tip: Hash,
242-
root: Hash,
243-
level: BlockLevel,
244-
try_number: u8,
245-
) -> DbRelationsStore {
246-
//TODO(relaxed): currently we rebuild the relation store in its entirety for each try.
247-
// A more efficient implementation could instead extend the store constructed in the previous try
248-
//TODO: Remove sanity checks when convinced code is stable and correct
249-
let mut queue = VecDeque::new();
250-
let mut visited = BlockHashSet::new();
251-
queue.push_back(tip);
252-
let cache_policy = CachePolicy::Count(2 * self.pruning_proof_m as usize);
253-
let mut level_relation_store = DbRelationsStore::new_temp(temp_db.clone(), level, try_number, cache_policy, cache_policy);
254-
255-
level_relation_store.insert(ORIGIN, BlockHashes::new(vec![])).unwrap();
256-
257-
// sanity check
258-
assert!(self.reachability_service.is_dag_ancestor_of(root, tip));
259-
while let Some(hash) = queue.pop_front() {
260-
if !visited.insert(hash) {
261-
continue;
262-
}
263-
if hash == ORIGIN {
264-
continue;
265-
}
266-
let header = self.headers_store.get_header(hash).unwrap();
267-
let parents = Arc::new(
268-
self.parents_manager
269-
.parents_at_level(&header, level)
270-
.iter()
271-
.copied()
272-
.filter(|&p| self.reachability_service.is_dag_ancestor_of_result(root, p).optional().unwrap().unwrap_or(false))
273-
.collect::<Vec<_>>()
274-
.push_if_empty(ORIGIN),
275-
);
276-
// sanity check
277-
if hash == root {
278-
assert_eq!(parents.len(), 1);
279-
assert_eq!(parents[0], ORIGIN);
280-
}
281-
// Write parents to the relations store
282-
level_relation_store.insert(hash, parents.clone()).unwrap();
283-
284-
// Enqueue parents to fill full upper chain
285-
for &p in parents.iter() {
286-
queue.push_back(p);
287-
}
288-
}
289-
//sanity checks
290-
for hash in visited {
291-
assert!(level_relation_store.has(hash).unwrap());
292-
}
293-
let children_read = level_relation_store.get_children(ORIGIN).unwrap();
294-
let origin_children = children_read.read();
295-
assert!(origin_children.len() == 1);
296-
assert!(origin_children.contains(&root));
297-
298-
level_relation_store
299-
}
300-
301229
/// Given a current hash, count the blocks in its future
302230
/// Do this by:
303231
/// 1. Getting the largest child in terms of future size (this ensures that the rest of the iteration is minimized since most of the future is covered)
@@ -507,129 +435,6 @@ impl PruningProofManager {
507435
panic!("Failed to find sufficient root for level {level} after exhausting all known headers.");
508436
}
509437

510-
/// Find a sufficient root at a given level by going through the headers store and looking
511-
/// for a deep enough level block
512-
/// For each root candidate, fill in the ghostdag data to see if it actually is deep enough.
513-
/// If the root is deep enough, it will satisfy these conditions
514-
/// 1. block at depth 2m at this level ∈ Future(root)
515-
/// 2. block at depth m at the next level ∈ Future(root)
516-
///
517-
/// Returns: the filled ghostdag store from root to tip, the selected tip and the root
518-
fn find_sufficiently_deep_level_root(
519-
&self,
520-
pp_header: &HeaderWithBlockLevel,
521-
level: BlockLevel,
522-
required_block: Option<Hash>,
523-
temp_db: Arc<DB>,
524-
) -> PruningProofManagerInternalResult<LevelProofContext> {
525-
// Step 1: Determine which selected tip to use
526-
let selected_tip = if pp_header.block_level >= level {
527-
pp_header.header.hash
528-
} else {
529-
self.find_approximate_selected_parent_header_at_level(&pp_header.header, level)?.hash
530-
};
531-
532-
let cache_policy = CachePolicy::Count(2 * self.pruning_proof_m as usize);
533-
let required_level_depth = 2 * self.pruning_proof_m;
534-
535-
// We only have the headers store (which has level 0 blue_scores) to assemble the proof data from.
536-
// We need to look deeper at higher levels (2x deeper every level) to find 2M (plus margin) blocks at that level
537-
// TODO: uncomment when the full fix to minimize proof sizes comes, and add current_dag_level as an argument
538-
// let mut required_base_level_depth = self.estimated_blue_depth_at_level_0(
539-
// level,
540-
// required_level_depth + 100, // We take a safety margin
541-
// current_dag_level,
542-
// );
543-
// NOTE: Starting from required_level_depth (a much lower starting point than normal) will typically require O(N) iterations
544-
// for level L + N where L is the current dag level. This is fine since the steps per iteration are still exponential
545-
// and so we will complete each level in not much more than N iterations per level.
546-
// We start here anyway so we can try to minimize the proof size when the current dag level goes down significantly.
547-
let mut required_base_level_depth = required_level_depth + 100;
548-
549-
let mut is_last_level_header;
550-
let mut tries = 0;
551-
552-
let block_at_depth_m_at_next_level = required_block.unwrap_or(selected_tip);
553-
554-
loop {
555-
// Step 2 - Find a deep enough root candidate
556-
let block_at_depth_2m = match self.level_block_at_base_depth(level, selected_tip, required_base_level_depth) {
557-
Ok((header, is_last_header)) => {
558-
is_last_level_header = is_last_header;
559-
header
560-
}
561-
Err(e) => return Err(e),
562-
};
563-
564-
let root = if self.reachability_service.is_dag_ancestor_of(block_at_depth_2m, block_at_depth_m_at_next_level) {
565-
block_at_depth_2m
566-
} else if self.reachability_service.is_dag_ancestor_of(block_at_depth_m_at_next_level, block_at_depth_2m) {
567-
block_at_depth_m_at_next_level
568-
} else {
569-
// find common ancestor of block_at_depth_m_at_next_level and block_at_depth_2m in chain of block_at_depth_m_at_next_level
570-
let mut common_ancestor = self.headers_store.get_header(block_at_depth_m_at_next_level).unwrap();
571-
while !self.reachability_service.is_dag_ancestor_of(common_ancestor.hash, block_at_depth_2m) {
572-
common_ancestor = match self.find_approximate_selected_parent_header_at_level(&common_ancestor, level) {
573-
Ok(header) => header,
574-
// Try to give this last header a chance at being root
575-
Err(PruningProofManagerInternalError::NotEnoughHeadersToBuildProof(_)) => break,
576-
Err(e) => return Err(e),
577-
};
578-
}
579-
580-
common_ancestor.hash
581-
};
582-
583-
// Step 3 - Fill the ghostdag data from root to tip.
584-
//
585-
// First, derive the relevant relations down to the candidate root.
586-
let transient_relation_store =
587-
Arc::new(RwLock::new(self.populate_relation_store_at_level(temp_db.clone(), selected_tip, root, level, tries)));
588-
589-
let transient_ghostdag_store =
590-
Arc::new(DbGhostdagStore::new_temp(temp_db.clone(), level, cache_policy, cache_policy, tries));
591-
let has_required_block = self.fill_level_proof_ghostdag_data(
592-
root,
593-
pp_header.header.hash,
594-
&transient_ghostdag_store,
595-
Some(block_at_depth_m_at_next_level),
596-
level,
597-
&transient_relation_store,
598-
self.ghostdag_k,
599-
);
600-
601-
// Step 4 - Check if we actually have enough depth.
602-
// Need to ensure this does the same 2M+1 depth that block_at_depth does
603-
if has_required_block
604-
&& (root == self.genesis_hash
605-
|| transient_ghostdag_store.get_blue_score(selected_tip).unwrap() >= required_level_depth)
606-
{
607-
if tries >= 1 {
608-
debug!("Found sufficient root for level {level} after {tries} tries.");
609-
}
610-
break Ok((transient_ghostdag_store, transient_relation_store, selected_tip, root));
611-
}
612-
613-
tries += 1;
614-
if is_last_level_header {
615-
if has_required_block {
616-
// Normally this scenario doesn't occur when syncing with nodes that already have the safety margin change in place.
617-
// However, when syncing with an older node version that doesn't have a safety margin for the proof, it's possible to
618-
// try to find 2500 depth worth of headers at a level, but the proof only contains about 2000 headers. To be able to sync
619-
// with such an older node. As long as we found the required block, we can still proceed.
620-
debug!("Failed to find sufficient root for level {level} after {tries} tries. Headers below the current depth of {required_base_level_depth} are already pruned. Required block found so trying anyway.");
621-
break Ok((transient_ghostdag_store, transient_relation_store, selected_tip, root));
622-
} else {
623-
panic!("Failed to find sufficient root for level {level} after {tries} tries. Headers below the current depth of {required_base_level_depth} are already pruned");
624-
}
625-
}
626-
627-
// If we don't have enough depth now, we need to look deeper
628-
required_base_level_depth = (required_base_level_depth as f64 * 1.1) as u64;
629-
debug!("Failed to find sufficient root for level {level} after {tries} tries. Retrying again to find with depth {required_base_level_depth}");
630-
}
631-
}
632-
633438
/// BFS forward iterates from root until selected tip, ignoring blocks in the antipast of selected_tip.
634439
/// For each block along the way, insert that hash into the ghostdag_store
635440
/// If we have a required_block to find, this will return true if that block was found along the way
@@ -701,33 +506,6 @@ impl PruningProofManager {
701506
has_required_block
702507
}
703508

704-
// The "current dag level" is the level right before the level whose parents are
705-
// not the same as our header's direct parents
706-
//
707-
// Find the current DAG level by going through all the parents at each level,
708-
// starting from the bottom level and see which is the first level that has
709-
// parents that are NOT our current pp_header's direct parents.
710-
fn find_current_dag_level(&self, pp_header: &Header) -> BlockLevel {
711-
let direct_parents = BlockHashSet::from_iter(pp_header.direct_parents().iter().copied());
712-
pp_header
713-
.parents_by_level
714-
.expanded_iter()
715-
.enumerate()
716-
.skip(1) // skip checking direct parents
717-
.find_map(|(level, parents)| {
718-
if BlockHashSet::from_iter(parents.iter().copied()) == direct_parents {
719-
None
720-
} else {
721-
Some((level - 1) as BlockLevel)
722-
}
723-
})
724-
.unwrap_or(self.max_block_level)
725-
}
726-
727-
fn estimated_blue_depth_at_level_0(&self, level: BlockLevel, level_depth: u64, current_dag_level: BlockLevel) -> u64 {
728-
level_depth.checked_shl(level.saturating_sub(current_dag_level) as u32).unwrap_or(level_depth)
729-
}
730-
731509
/// selected parent at level = the parent of the header at the level
732510
/// with the highest blue_work
733511
fn find_approximate_selected_parent_header_at_level(
@@ -752,73 +530,6 @@ impl PruningProofManager {
752530
Ok(self.headers_store.get_header(sp.hash).expect("unwrapped above"))
753531
}
754532

755-
/// Finds a block on a given level that is at base_depth deep from it.
756-
/// Also returns if the block was the last one in the level
757-
/// base_depth = the blue score depth at level 0
758-
fn level_block_at_base_depth(
759-
&self,
760-
level: BlockLevel,
761-
high: Hash,
762-
base_depth: u64,
763-
) -> PruningProofManagerInternalResult<(Hash, bool)> {
764-
let high_header = self
765-
.headers_store
766-
.get_header(high)
767-
.map_err(|err| PruningProofManagerInternalError::BlockAtDepth(format!("high: {high}, depth: {base_depth}, {err}")))?;
768-
let high_header_score = high_header.blue_score;
769-
let mut current_header = high_header;
770-
771-
let mut is_last_header = false;
772-
// The current block is considered seen
773-
// This counts all the blocks we've seen, including the anticone of the current header
774-
// The anticone size of the root/current header can be removed from this to get the estimated number of blocks
775-
// fully in the set of Future(root) ∩ Past(high)
776-
let mut seen = 1;
777-
778-
let mut anticone = Vec::new();
779-
let depth_2m = 2 * self.pruning_proof_m as usize;
780-
781-
// The block is of sufficient depth if:
782-
// 1. It has the required base depth AND
783-
// 2. We've seen 2M+1 blocks in it's future (See other references to 2M+1 in this file)
784-
while current_header.blue_score + base_depth >= high_header_score || seen - anticone.len() <= depth_2m {
785-
if current_header.direct_parents().is_empty() {
786-
// Reached genesis
787-
break;
788-
}
789-
790-
let mut known_parents = self
791-
.parents_manager
792-
.parents_at_level(&current_header, level)
793-
.iter()
794-
.copied()
795-
.filter(|&p| self.reachability_service.has_reachability_data(p))
796-
.collect_vec();
797-
798-
seen += known_parents.len();
799-
800-
current_header = match self.find_approximate_selected_parent_header_at_level(&current_header, level) {
801-
Ok(header) => header,
802-
Err(PruningProofManagerInternalError::NotEnoughHeadersToBuildProof(_)) => {
803-
// We want to give this root a shot if all its past is pruned
804-
is_last_header = true;
805-
break;
806-
}
807-
Err(e) => return Err(e),
808-
};
809-
810-
// Maintain the anticone by adding all the known parents of the previous header
811-
// and then removing all of those that are not ancestors of the current header
812-
anticone.append(&mut known_parents);
813-
anticone = anticone
814-
.iter()
815-
.filter(|&b| !self.reachability_service.is_dag_ancestor_of(current_header.hash, *b))
816-
.copied()
817-
.collect_vec();
818-
}
819-
Ok((current_header.hash, is_last_header))
820-
}
821-
822533
/// Copy of `block_at_depth` which returns the full chain up to depth. Temporarily used for assertion purposes.
823534
fn chain_up_to_depth(
824535
&self,

0 commit comments

Comments
 (0)