Skip to content

Commit

Permalink
Refactor block finalization
Browse files Browse the repository at this point in the history
  • Loading branch information
upbqdn committed Aug 24, 2022
1 parent c464381 commit f7d1ccd
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
11 changes: 11 additions & 0 deletions zebra-state/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ pub struct FinalizedWithTrees {
pub treestate: Option<Treestate>,
}

impl FinalizedWithTrees {
pub fn new(block: ContextuallyValidBlock, treestate: Treestate) -> Self {
let finalized = FinalizedBlock::from(block);

Self {
finalized,
treestate: Some(treestate),
}
}
}

impl From<Arc<Block>> for FinalizedWithTrees {
fn from(block: Arc<Block>) -> Self {
Self::from(FinalizedBlock::from(block))
Expand Down
26 changes: 11 additions & 15 deletions zebra-state/src/service/non_finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use zebra_chain::{
use crate::{
request::{ContextuallyValidBlock, FinalizedWithTrees},
service::{check, finalized_state::ZebraDb},
FinalizedBlock, PreparedBlock, ValidateContextError,
PreparedBlock, ValidateContextError,
};

mod chain;
Expand Down Expand Up @@ -92,51 +92,47 @@ impl NonFinalizedState {
let mut best_chain = chains.next_back().expect("there's at least one chain");

// clone if required
let write_best_chain = Arc::make_mut(&mut best_chain);
let mut_best_chain = Arc::make_mut(&mut best_chain);

// extract the rest into side_chains so they can be mutated
let side_chains = chains;

// Pop the lowest height block from the best chain to be finalized, and
// also obtain its associated treestate.
let (finalizing, treestate) = write_best_chain.pop_root();
let (best_chain_root, root_treestate) = mut_best_chain.pop_root();

// add best_chain back to `self.chain_set`
if !best_chain.is_empty() {
self.chain_set.insert(best_chain);
}

// for each remaining chain in side_chains
for mut chain in side_chains {
if chain.non_finalized_root_hash() != finalizing.hash {
for mut side_chain in side_chains {
if side_chain.non_finalized_root_hash() != best_chain_root.hash {
// If we popped the root, the chain would be empty or orphaned,
// so just drop it now.
drop(chain);
drop(side_chain);

continue;
}

// otherwise, the popped root block is the same as the finalizing block

// clone if required
let write_chain = Arc::make_mut(&mut chain);
let mut_side_chain = Arc::make_mut(&mut side_chain);

// remove the first block from `chain`
let (chain_start, _treestate) = write_chain.pop_root();
assert_eq!(chain_start.hash, finalizing.hash);
let (side_chain_root, _treestate) = mut_side_chain.pop_root();
assert_eq!(side_chain_root.hash, best_chain_root.hash);

// add the chain back to `self.chain_set`
self.chain_set.insert(chain);
self.chain_set.insert(side_chain);
}

self.update_metrics_for_chains();

// Add the treestate to the finalized block.
let finalized = FinalizedBlock::from(finalizing);
let mut finalized_with_trees = FinalizedWithTrees::from(finalized);
finalized_with_trees.treestate = Some(treestate);

finalized_with_trees
FinalizedWithTrees::new(best_chain_root, root_treestate)
}

/// Commit block to the non-finalized state, on top of:
Expand Down

0 comments on commit f7d1ccd

Please sign in to comment.