From ff3cab93902e61c6b9de0e96c1836751b9bd4185 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Wed, 15 May 2024 08:03:28 +0800 Subject: [PATCH] Temporary put parent header to PreloadUnverified, put small BlockView to LonelyBlockHash Signed-off-by: Eval EXEC --- Cargo.lock | 5 +- chain/Cargo.toml | 1 + chain/src/lib.rs | 23 ++++++--- chain/src/orphan_broker.rs | 19 ++++--- .../src/preload_unverified_blocks_channel.rs | 51 ++++++++++++++----- 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1788d6842..19d423f391 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -745,6 +745,7 @@ dependencies = [ "ckb-verification-traits", "crossbeam", "dashmap", + "either", "faux", "is_sorted", "lazy_static", @@ -2364,9 +2365,9 @@ checksum = "8d978bd5d343e8ab9b5c0fc8d93ff9c602fdc96616ffff9c05ac7a155419b824" [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "encode_unicode" diff --git a/chain/Cargo.toml b/chain/Cargo.toml index 95b145c2d5..5fc05d661a 100644 --- a/chain/Cargo.toml +++ b/chain/Cargo.toml @@ -36,6 +36,7 @@ ckb-network = { path = "../network", version = "= 0.116.0-pre" } ckb-tx-pool = { path = "../tx-pool", version = "= 0.116.0-pre" } minstant = "0.1.4" dashmap = "4.0" +either = "1.11.0" [dev-dependencies] ckb-test-chain-utils = { path = "../util/test-chain-utils", version = "= 0.116.0-pre" } diff --git a/chain/src/lib.rs b/chain/src/lib.rs index ab81e02232..b656243f2c 100644 --- a/chain/src/lib.rs +++ b/chain/src/lib.rs @@ -31,6 +31,7 @@ use ckb_logger::{error, info}; use ckb_store::{ChainDB, ChainStore}; use ckb_types::prelude::{Pack, Unpack}; use ckb_types::H256; +use either::Either; pub use init::start_chain_services; type ProcessBlockRequest = Request; @@ -70,7 +71,7 @@ pub struct LonelyBlock { /// LonelyBlock is the block which we have not check weather its parent is stored yet pub struct LonelyBlockHash { /// block - pub block_number_and_hash: BlockNumberAndHash, + pub block_number_and_hash: Either>, pub parent_hash: Byte32, @@ -99,9 +100,14 @@ impl From for LonelyBlockHash { let epoch_number: EpochNumber = block.epoch().number(); LonelyBlockHash { - block_number_and_hash: BlockNumberAndHash { - number: block_number, - hash: block_hash, + block_number_and_hash: if block.data().serialized_size_without_uncle_proposals() > 12800 + { + Either::Right(block) + } else { + Either::Left(BlockNumberAndHash { + number: block_number, + hash: block_hash, + }) }, parent_hash, epoch_number, @@ -119,7 +125,10 @@ impl LonelyBlockHash { } pub fn number_hash(&self) -> BlockNumberAndHash { - self.block_number_and_hash.clone() + match self.block_number_and_hash.as_ref() { + Either::Left(block_number_and_hash) => block_number_and_hash.to_owned(), + Either::Right(block) => BlockNumberAndHash::new(block.number(), block.hash()), + } } pub fn epoch_number(&self) -> EpochNumber { @@ -127,7 +136,7 @@ impl LonelyBlockHash { } pub fn hash(&self) -> Byte32 { - self.block_number_and_hash.hash() + self.number_hash().hash() } pub fn parent_hash(&self) -> Byte32 { @@ -135,7 +144,7 @@ impl LonelyBlockHash { } pub fn number(&self) -> BlockNumber { - self.block_number_and_hash.number() + self.number_hash().number() } } diff --git a/chain/src/orphan_broker.rs b/chain/src/orphan_broker.rs index 56fdd82382..c23d5221a6 100644 --- a/chain/src/orphan_broker.rs +++ b/chain/src/orphan_broker.rs @@ -80,16 +80,16 @@ impl OrphanBroker { } fn delete_block(&self, lonely_block: &LonelyBlockHash) { - let block_hash = lonely_block.block_number_and_hash.hash(); - let block_number = lonely_block.block_number_and_hash.number(); + let block_hash = lonely_block.hash(); + let block_number = lonely_block.number(); let parent_hash = lonely_block.parent_hash(); delete_unverified_block(self.shared.store(), block_hash, block_number, parent_hash); } fn process_invalid_block(&self, lonely_block: LonelyBlockHash) { - let block_hash = lonely_block.block_number_and_hash.hash(); - let block_number = lonely_block.block_number_and_hash.number(); + let block_hash = lonely_block.hash(); + let block_number = lonely_block.number(); let parent_hash = lonely_block.parent_hash(); self.delete_block(&lonely_block); @@ -107,8 +107,8 @@ impl OrphanBroker { } pub(crate) fn process_lonely_block(&self, lonely_block: LonelyBlockHash) { - let block_hash = lonely_block.block_number_and_hash.hash(); - let block_number = lonely_block.block_number_and_hash.number(); + let block_hash = lonely_block.hash(); + let block_number = lonely_block.number(); let parent_hash = lonely_block.parent_hash(); let parent_is_pending_verify = self.is_pending_verify.contains(&parent_hash); let parent_status = self.shared.get_block_status(&parent_hash); @@ -162,8 +162,8 @@ impl OrphanBroker { } fn send_unverified_block(&self, lonely_block: LonelyBlockHash) { - let block_number = lonely_block.block_number_and_hash.number(); - let block_hash = lonely_block.block_number_and_hash.hash(); + let block_number = lonely_block.number(); + let block_hash = lonely_block.hash(); if let Some(metrics) = ckb_metrics::handle() { metrics @@ -203,8 +203,7 @@ impl OrphanBroker { } fn process_descendant(&self, lonely_block: LonelyBlockHash) { - self.is_pending_verify - .insert(lonely_block.block_number_and_hash.hash()); + self.is_pending_verify.insert(lonely_block.hash()); self.send_unverified_block(lonely_block) } diff --git a/chain/src/preload_unverified_blocks_channel.rs b/chain/src/preload_unverified_blocks_channel.rs index 23f593bd79..b75753b50d 100644 --- a/chain/src/preload_unverified_blocks_channel.rs +++ b/chain/src/preload_unverified_blocks_channel.rs @@ -3,7 +3,10 @@ use ckb_channel::{Receiver, Sender}; use ckb_logger::{debug, error, info}; use ckb_shared::Shared; use ckb_store::ChainStore; +use ckb_types::core::HeaderView; use crossbeam::select; +use either::Either; +use std::cell::Cell; use std::sync::Arc; pub(crate) struct PreloadUnverifiedBlocksChannel { @@ -13,6 +16,9 @@ pub(crate) struct PreloadUnverifiedBlocksChannel { unverified_block_tx: Sender, stop_rx: Receiver<()>, + + // after we load a block from store, we put block.parent_header into this cell + prev_header: Cell, } impl PreloadUnverifiedBlocksChannel { @@ -22,11 +28,19 @@ impl PreloadUnverifiedBlocksChannel { unverified_block_tx: Sender, stop_rx: Receiver<()>, ) -> Self { + let tip_hash = shared.snapshot().tip_hash(); + + let tip_header = shared + .store() + .get_block_header(&tip_hash) + .expect("must get tip header"); + PreloadUnverifiedBlocksChannel { shared, preload_unverified_rx, unverified_block_tx, stop_rx, + prev_header: Cell::new(tip_header), } } @@ -51,8 +65,8 @@ impl PreloadUnverifiedBlocksChannel { } fn preload_unverified_channel(&self, task: LonelyBlockHash) { - let block_number = task.block_number_and_hash.number(); - let block_hash = task.block_number_and_hash.hash(); + let block_number = task.number(); + let block_hash = task.hash(); let unverified_block: UnverifiedBlock = self.load_full_unverified_block_by_hash(task); if let Some(metrics) = ckb_metrics::handle() { @@ -82,17 +96,30 @@ impl PreloadUnverifiedBlocksChannel { verify_callback, } = task; - let block_view = self - .shared - .store() - .get_block(&block_number_and_hash.hash()) - .expect("block stored"); - let block = Arc::new(block_view); + let block = { + match block_number_and_hash { + Either::Left(number_and_hash) => { + let block_view = self + .shared + .store() + .get_block(&number_and_hash.hash()) + .expect("block stored"); + Arc::new(block_view) + } + Either::Right(block) => block, + } + }; + let parent_header = { - self.shared - .store() - .get_block_header(&parent_hash) - .expect("parent header stored") + let prev_header = self.prev_header.replace(block.header()); + if prev_header.hash() == parent_hash { + prev_header + } else { + self.shared + .store() + .get_block_header(&parent_hash) + .expect("parent header stored") + } }; UnverifiedBlock {