Skip to content

Commit

Permalink
Refactor: move ForkChanges to independent module
Browse files Browse the repository at this point in the history
  • Loading branch information
eval-exec committed Aug 1, 2024
1 parent 9b0da11 commit 8946eaa
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 84 deletions.
85 changes: 3 additions & 82 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! CKB chain service.
#![allow(missing_docs)]

use crate::forkchanges::ForkChanges;
use ckb_channel::{self as channel, select, Sender};
use ckb_error::{Error, InternalErrorKind};
use ckb_logger::Level::Trace;
Expand All @@ -19,11 +20,10 @@ use ckb_types::{
resolve_transaction, BlockCellProvider, HeaderChecker, OverlayCellProvider,
ResolvedTransaction,
},
hardfork::HardForks,
service::Request,
BlockExt, BlockNumber, BlockView, Cycle, HeaderView,
},
packed::{Byte32, ProposalShortId},
packed::Byte32,
utilities::merkle_mountain_range::ChainRootMMR,
U256,
};
Expand All @@ -33,7 +33,7 @@ use ckb_verification_contextual::{ContextualBlockVerifier, VerifyContext};
use ckb_verification_traits::{Switch, Verifier};
#[cfg(debug_assertions)]
use is_sorted::IsSorted;
use std::collections::{HashSet, VecDeque};
use std::collections::HashSet;
use std::sync::Arc;
use std::time::Instant;
use std::{cmp, thread};
Expand Down Expand Up @@ -102,85 +102,6 @@ impl ChainController {
}
}

/// The struct represent fork
#[derive(Debug, Default)]
pub struct ForkChanges {
/// Blocks attached to index after forks
pub(crate) attached_blocks: VecDeque<BlockView>,
/// Blocks detached from index after forks
pub(crate) detached_blocks: VecDeque<BlockView>,
/// HashSet with proposal_id detached to index after forks
pub(crate) detached_proposal_id: HashSet<ProposalShortId>,
/// to be updated exts
pub(crate) dirty_exts: VecDeque<BlockExt>,
}

impl ForkChanges {
/// blocks attached to index after forks
pub fn attached_blocks(&self) -> &VecDeque<BlockView> {
&self.attached_blocks
}

/// blocks detached from index after forks
pub fn detached_blocks(&self) -> &VecDeque<BlockView> {
&self.detached_blocks
}

/// proposal_id detached to index after forks
pub fn detached_proposal_id(&self) -> &HashSet<ProposalShortId> {
&self.detached_proposal_id
}

/// are there any block should be detached
pub fn has_detached(&self) -> bool {
!self.detached_blocks.is_empty()
}

/// cached verified attached block num
pub fn verified_len(&self) -> usize {
self.attached_blocks.len() - self.dirty_exts.len()
}

/// assertion for make sure attached_blocks and detached_blocks are sorted
#[cfg(debug_assertions)]
pub fn is_sorted(&self) -> bool {
IsSorted::is_sorted_by_key(&mut self.attached_blocks().iter(), |blk| {
blk.header().number()
}) && IsSorted::is_sorted_by_key(&mut self.detached_blocks().iter(), |blk| {
blk.header().number()
})
}

pub fn during_hardfork(&self, hardfork_switch: &HardForks) -> bool {
let hardfork_during_detach =
self.check_if_hardfork_during_blocks(hardfork_switch, &self.detached_blocks);
let hardfork_during_attach =
self.check_if_hardfork_during_blocks(hardfork_switch, &self.attached_blocks);

hardfork_during_detach || hardfork_during_attach
}

fn check_if_hardfork_during_blocks(
&self,
hardfork: &HardForks,
blocks: &VecDeque<BlockView>,
) -> bool {
if blocks.is_empty() {
false
} else {
// This method assumes that the input blocks are sorted and unique.
let rfc_0049 = hardfork.ckb2023.rfc_0049();
let epoch_first = blocks.front().unwrap().epoch().number();
let epoch_next = blocks
.back()
.unwrap()
.epoch()
.minimum_epoch_number_after_n_blocks(1);
epoch_first < rfc_0049 && rfc_0049 <= epoch_next
}
}
}

pub(crate) struct GlobalIndex {
pub(crate) number: BlockNumber,
pub(crate) hash: Byte32,
Expand Down
84 changes: 84 additions & 0 deletions chain/src/forkchanges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use ckb_rust_unstable_port::IsSorted;
use ckb_types::core::hardfork::HardForks;
use ckb_types::core::{BlockExt, BlockView};
use ckb_types::packed::ProposalShortId;
use std::collections::{HashSet, VecDeque};

/// The struct represent fork
#[derive(Debug, Default)]
pub struct ForkChanges {
/// Blocks attached to index after forks
pub(crate) attached_blocks: VecDeque<BlockView>,
/// Blocks detached from index after forks
pub(crate) detached_blocks: VecDeque<BlockView>,
/// HashSet with proposal_id detached to index after forks
pub(crate) detached_proposal_id: HashSet<ProposalShortId>,
/// to be updated exts
pub(crate) dirty_exts: VecDeque<BlockExt>,
}

impl ForkChanges {
/// blocks attached to index after forks
pub fn attached_blocks(&self) -> &VecDeque<BlockView> {
&self.attached_blocks
}

/// blocks detached from index after forks
pub fn detached_blocks(&self) -> &VecDeque<BlockView> {
&self.detached_blocks
}

/// proposal_id detached to index after forks
pub fn detached_proposal_id(&self) -> &HashSet<ProposalShortId> {
&self.detached_proposal_id
}

/// are there any block should be detached
pub fn has_detached(&self) -> bool {
!self.detached_blocks.is_empty()
}

/// cached verified attached block num
pub fn verified_len(&self) -> usize {
self.attached_blocks.len() - self.dirty_exts.len()
}

/// assertion for make sure attached_blocks and detached_blocks are sorted
#[cfg(debug_assertions)]
pub fn is_sorted(&self) -> bool {
IsSorted::is_sorted_by_key(&mut self.attached_blocks().iter(), |blk| {
blk.header().number()
}) && IsSorted::is_sorted_by_key(&mut self.detached_blocks().iter(), |blk| {
blk.header().number()
})
}

pub fn during_hardfork(&self, hardfork_switch: &HardForks) -> bool {
let hardfork_during_detach =
self.check_if_hardfork_during_blocks(hardfork_switch, &self.detached_blocks);
let hardfork_during_attach =
self.check_if_hardfork_during_blocks(hardfork_switch, &self.attached_blocks);

hardfork_during_detach || hardfork_during_attach
}

fn check_if_hardfork_during_blocks(
&self,
hardfork: &HardForks,
blocks: &VecDeque<BlockView>,
) -> bool {
if blocks.is_empty() {
false
} else {
// This method assumes that the input blocks are sorted and unique.
let rfc_0049 = hardfork.ckb2023.rfc_0049();
let epoch_first = blocks.front().unwrap().epoch().number();
let epoch_next = blocks
.back()
.unwrap()
.epoch()
.minimum_epoch_number_after_n_blocks(1);
epoch_first < rfc_0049 && rfc_0049 <= epoch_next
}
}
}
1 change: 1 addition & 0 deletions chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
//! [`ChainController`]: chain/struct.ChainController.html
pub mod chain;
mod forkchanges;
#[cfg(test)]
mod tests;
5 changes: 3 additions & 2 deletions chain/src/tests/find_fork.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::chain::{ChainService, ForkChanges};
use crate::chain::ChainService;
use crate::forkchanges::ForkChanges;
use ckb_chain_spec::consensus::{Consensus, ProposalWindow};
use ckb_shared::SharedBuilder;
use ckb_store::ChainStore;
Expand Down Expand Up @@ -495,7 +496,7 @@ fn test_fork_proposal_table() {
assert_eq!(
&vec![
packed::ProposalShortId::new([0u8, 0, 0, 0, 0, 0, 0, 0, 0, 3]),
packed::ProposalShortId::new([1u8, 0, 0, 0, 0, 0, 0, 0, 0, 4])
packed::ProposalShortId::new([1u8, 0, 0, 0, 0, 0, 0, 0, 0, 4]),
]
.into_iter()
.collect::<HashSet<_>>(),
Expand Down

0 comments on commit 8946eaa

Please sign in to comment.