Skip to content

Commit

Permalink
debug, thinking and trying
Browse files Browse the repository at this point in the history
  • Loading branch information
eval-exec committed Apr 24, 2023
1 parent 21db95f commit 39784bb
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
8 changes: 7 additions & 1 deletion chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,13 @@ impl ChainController {

// Relay need this
pub fn get_orphan_block(&self, hash: &Byte32) -> Option<BlockView> {
todo!("load orphan block")
if self.orphan_block_broker.exist(hash){
// TODO we should store BlockView in memory when CKB node not in IBD mode (Relay protocol need load orphan block)
// store orphan blocks to RocksDB only when CKB node in IBD mode
todo!("load orphan block")
return Some();
}
None
}
}

Expand Down
54 changes: 40 additions & 14 deletions chain/src/orphan_block_pool.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
use ckb_logger::debug;
use ckb_types::core::EpochNumber;
use ckb_types::packed::Byte32;
use ckb_types::{core, packed};
use ckb_util::{parking_lot::RwLock, shrink_to_fit};
use std::collections::{HashMap, HashSet, VecDeque};

pub type ParentHash = packed::Byte32;
pub struct OrphanBlockId(ParentHash, packed::Byte32);

impl OrphanBlockId {
pub fn new(parent_hash: ParentHash, block_hash: Byte32) -> Self {
OrphanBlockId(parent_hash, block_hash)
}
pub fn parent_hash(&self) -> ParentHash {
self.0.clone()
}
pub fn block_hash(&self) -> ParentHash {
self.1.clone()
}
}

const SHRINK_THRESHOLD: usize = 100;
const EXPIRED_EPOCH: u64 = 6;

#[derive(Default)]
struct InnerPool {
// Group by blocks in the pool by the parent hash.
blocks: HashMap<ParentHash, HashMap<packed::Byte32, core::BlockView>>,
blocks: HashMap<ParentHash, HashSet<Byte32>>,
// The map tells the parent hash when given the hash of a block in the pool.
//
// The block is in the orphan pool if and only if the block hash exists as a key in this map.
Expand All @@ -30,13 +44,13 @@ impl InnerPool {
}
}

fn insert(&mut self, block: core::BlockView) {
let hash = block.header().hash();
let parent_hash = block.data().header().raw().parent_hash();
fn insert(&mut self, block: OrphanBlockId) {
let hash = block.hash();
let parent_hash = block.parent_hash();
self.blocks
.entry(parent_hash.clone())
.or_insert_with(HashMap::default)
.insert(hash.clone(), block);
.insert(hash.clone());
// Out-of-order insertion needs to be deduplicated
self.leaders.remove(&hash);
// It is a possible optimization to make the judgment in advance,
Expand All @@ -50,7 +64,7 @@ impl InnerPool {
self.parents.insert(hash, parent_hash);
}

pub fn remove_blocks_by_parent(&mut self, parent_hash: &ParentHash) -> Vec<core::BlockView> {
pub fn remove_blocks_by_parent(&mut self, parent_hash: &ParentHash) -> Vec<OrphanBlockId> {
// try remove leaders first
if !self.leaders.remove(parent_hash) {
return Vec::new();
Expand All @@ -59,7 +73,7 @@ impl InnerPool {
let mut queue: VecDeque<packed::Byte32> = VecDeque::new();
queue.push_back(parent_hash.to_owned());

let mut removed: Vec<core::BlockView> = Vec::new();
let mut removed: Vec<OrphanBlockId> = Vec::new();
while let Some(parent_hash) = queue.pop_front() {
if let Some(orphaned) = self.blocks.remove(&parent_hash) {
let (hashes, blocks): (Vec<_>, Vec<_>) = orphaned.into_iter().unzip();
Expand All @@ -84,14 +98,22 @@ impl InnerPool {
removed
}

pub fn get_block(&self, hash: &packed::Byte32) -> Option<core::BlockView> {
pub fn exist(&self, hash: &packed::Byte32) -> bool {
self.parents.get(hash).and_then(|parent_hash| {
self.blocks
.get(parent_hash)
.and_then(|blocks| blocks.get(hash).cloned())
.and_then(|blocks| blocks.get(hash).is_some())
})
}

// pub fn get_block(&self, hash: &packed::Byte32) -> Option<OrphanBlockId> {
// self.parents.get(hash).and_then(|parent_hash| {
// self.blocks
// .get(parent_hash)
// .and_then(|blocks| blocks.get(hash).cloned())
// })
// }

/// cleanup expired blocks(epoch + EXPIRED_EPOCH < tip_epoch)
pub fn clean_expired_blocks(&mut self, tip_epoch: EpochNumber) -> Vec<packed::Byte32> {
let mut result = vec![];
Expand All @@ -100,7 +122,7 @@ impl InnerPool {
if self.need_clean(hash, tip_epoch) {
// remove items in orphan pool and return hash to callee(clean header map)
let descendants = self.remove_blocks_by_parent(hash);
result.extend(descendants.iter().map(|block| block.hash()));
result.extend(descendants.iter().map(|block| block.block_hash()));
}
}
result
Expand Down Expand Up @@ -135,16 +157,20 @@ impl OrphanBlockPool {
}

/// Insert orphaned block, for which we have already requested its parent block
pub fn insert(&self, block: core::BlockView) {
pub fn insert(&self, block: OrphanBlockId) {
self.inner.write().insert(block);
}

pub fn remove_blocks_by_parent(&self, parent_hash: &ParentHash) -> Vec<core::BlockView> {
pub fn remove_blocks_by_parent(&self, parent_hash: &ParentHash) -> Vec<OrphanBlockId> {
self.inner.write().remove_blocks_by_parent(parent_hash)
}

pub fn get_block(&self, hash: &packed::Byte32) -> Option<core::BlockView> {
self.inner.read().get_block(hash)
// pub fn get_block(&self, hash: &packed::Byte32) -> Option<core::BlockView> {
// self.inner.read().get_block(hash)
// }

pub fn exist(&self, hash: &packed::Byte32) -> bool {
self.inner.read().exist(hash)
}

pub fn clean_expired_blocks(&self, epoch: EpochNumber) -> Vec<packed::Byte32> {
Expand Down

0 comments on commit 39784bb

Please sign in to comment.