Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Eval EXEC <[email protected]>
  • Loading branch information
eval-exec committed Dec 5, 2024
1 parent 9df053c commit 770b84c
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 104 deletions.
24 changes: 16 additions & 8 deletions chain/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,22 @@ impl ConsumeUnverifiedBlockProcessor {
switch: Option<Switch>,
) -> VerifyResult {
let switch: Switch = switch.unwrap_or_else(|| {
let mut assume_valid_target = self.shared.assume_valid_target();
match *assume_valid_target {
Some(ref target) => {
// if the target has been reached, delete it
if target
== &ckb_types::prelude::Unpack::<H256>::unpack(&BlockView::hash(block))
{
assume_valid_target.take();
let mut assume_valid_targets = self.shared.assume_valid_targets();
match *assume_valid_targets {
Some(ref mut targets) => {
//
let block_hash: H256 =
ckb_types::prelude::Unpack::<H256>::unpack(&BlockView::hash(block));
if targets.first().eq(&Some(&block_hash)) {
targets.remove(0);
info!("CKB reached one assume_valid_target: {}", block_hash);
}

if targets.is_empty() {
assume_valid_targets.take();
info!(
"CKB reached all assume_valid_targets, will do full verification now"
);
Switch::NONE
} else {
Switch::DISABLE_SCRIPT
Expand Down
4 changes: 2 additions & 2 deletions ckb-bin/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ default(TestNet): {}\n\n
You can explicitly set the value to 0x0000000000000000000000000000000000000000000000000000000000000000 \
to disable the default behavior and execute full verification for all blocks, \
",
ckb_constant::default_assume_valid_target::mainnet::DEFAULT_ASSUME_VALID_TARGET,
ckb_constant::default_assume_valid_target::testnet::DEFAULT_ASSUME_VALID_TARGET))
ckb_constant::latest_assume_valid_target::mainnet::DEFAULT_ASSUME_VALID_TARGET,
ckb_constant::latest_assume_valid_target::testnet::DEFAULT_ASSUME_VALID_TARGET))
).arg(
Arg::new(ARG_INDEXER)
.long(ARG_INDEXER)
Expand Down
60 changes: 37 additions & 23 deletions ckb-bin/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ckb_app_config::{
};
use ckb_chain_spec::{consensus::Consensus, ChainSpec};
use ckb_jsonrpc_types::ScriptHashType;
use ckb_logger::info;
use ckb_logger::{error, info};
use ckb_types::{u256, H256, U256};
use clap::ArgMatches;
use std::{path::PathBuf, str::FromStr};
Expand Down Expand Up @@ -71,33 +71,47 @@ impl Setup {
} else {
u256!("0x0")
};

let arg_assume_valid_target = matches.get_one::<String>(cli::ARG_ASSUME_VALID_TARGET);

config.network.sync.assume_valid_target =
arg_assume_valid_target.and_then(|s| H256::from_str(&s[2..]).ok());
if config.network.sync.assume_valid_target.is_none() {
config.network.sync.assume_valid_target = match consensus.id.as_str() {
config.network.sync.assume_valid_targets = matches
.get_one::<String>(cli::ARG_ASSUME_VALID_TARGET)
.map(|concacate_targets| {
concacate_targets
.split(',')
.map(|s| H256::from_str(&s[2..]))
.collect::<Result<Vec<H256>, _>>()
.map_err(|err| {
error!("Invalid assume valid target: {}", err);
ExitCode::Cli
})
})
.transpose()?; // Converts Result<Option<T>, E> to Option<Result<T, E>>

if config.network.sync.assume_valid_targets.is_none() {
config.network.sync.assume_valid_targets = match consensus.id.as_str() {
ckb_constant::hardfork::mainnet::CHAIN_SPEC_NAME => Some(
H256::from_str(&ckb_constant::default_assume_valid_target::mainnet::DEFAULT_ASSUME_VALID_TARGET[2..])
.expect("default assume_valid_target for mainnet must be valid"),
),
ckb_constant::default_assume_valid_target::mainnet::default_assume_valid_targets().iter().map(|target|
H256::from_str(&target[2..]).expect("default assume_valid_target for mainnet must be valid")).collect::<Vec<H256>>()),
ckb_constant::hardfork::testnet::CHAIN_SPEC_NAME => Some(
H256::from_str(&ckb_constant::default_assume_valid_target::testnet::DEFAULT_ASSUME_VALID_TARGET[2..])
.expect("default assume_valid_target for testnet must be valid"),
),
_ => None,
ckb_constant::default_assume_valid_target::testnet::default_assume_valid_targets().iter().map(|target|
H256::from_str(&target[2..]).expect("default assume_valid_target for testnet must be valid")).collect::<Vec<H256>>()),
_ => None,
};
}

if let Some(ref assume_valid_target) = config.network.sync.assume_valid_target {
if assume_valid_target
== &H256::from_slice(&[0; 32]).expect("must parse Zero h256 successful")
{
info!("Disable assume valid target since assume_valid_target is zero");
config.network.sync.assume_valid_target = None
} else {
info!("assume_valid_target set to 0x{}", assume_valid_target);
if let Some(ref assume_valid_targets) = config.network.sync.assume_valid_targets {
if let Some(first_target) = assume_valid_targets.first() {
if assume_valid_targets.len() == 1 {
if first_target
== &H256::from_slice(&[0; 32]).expect("must parse Zero h256 successful")
{
info!("Disable assume valid targets since assume_valid_targets is zero");
config.network.sync.assume_valid_targets = None;
} else {
info!(
"assume_valid_targets set to {:?}",
config.network.sync.assume_valid_targets
);
}
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions devtools/release/update_default_valid_target.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ TEXT_MAINNET=$(print_60_days_ago_block mainnet https://mainnet.ckb.dev https://e

printf "TestNet:\n"
TEXT_TESTNET=$(print_60_days_ago_block testnet https://testnet.ckb.dev https://pudge.explorer.nervos.org)
echo "${TEXT_HEADER}" > util/constant/src/default_assume_valid_target.rs
echo "${TEXT_MAINNET}" >> util/constant/src/default_assume_valid_target.rs
echo "${TEXT_TESTNET}" >> util/constant/src/default_assume_valid_target.rs
echo "${TEXT_HEADER}" > util/constant/src/latest_assume_valid_target.rs
echo "${TEXT_MAINNET}" >> util/constant/src/latestassume_valid_target.rs
echo "${TEXT_TESTNET}" >> util/constant/src/latest_assume_valid_target.rs
echo
echo this script has overwrite file: util/constant/src/default_assume_valid_target.rs
echo this script has overwrite file: util/constant/src/latest_assume_valid_target.rs
echo Please review the changes
2 changes: 1 addition & 1 deletion rpc/src/module/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ impl NetRpc for NetRpcImpl {
let unverified_tip = shared.get_unverified_tip();
let sync_state = SyncState {
ibd: chain.is_initial_block_download(),
assume_valid_target_reached: shared.assume_valid_target().is_none(),
assume_valid_target_reached: shared.assume_valid_targets().is_none(),
assume_valid_target: shared
.assume_valid_target_specified()
.as_ref()
Expand Down
10 changes: 5 additions & 5 deletions shared/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub struct Shared {
pub(crate) async_handle: Handle,
pub(crate) ibd_finished: Arc<AtomicBool>,

pub(crate) assume_valid_target: Arc<Mutex<Option<H256>>>,
pub(crate) assume_valid_targets: Arc<Mutex<Option<Vec<H256>>>>,
pub(crate) assume_valid_target_specified: Arc<Option<H256>>,

pub header_map: Arc<HeaderMap>,
Expand All @@ -83,7 +83,7 @@ impl Shared {
async_handle: Handle,
ibd_finished: Arc<AtomicBool>,

assume_valid_target: Arc<Mutex<Option<H256>>>,
assume_valid_targets: Arc<Mutex<Option<Vec<H256>>>>,
assume_valid_target_specified: Arc<Option<H256>>,
header_map: Arc<HeaderMap>,
block_status_map: Arc<DashMap<Byte32, BlockStatus>>,
Expand All @@ -106,7 +106,7 @@ impl Shared {
snapshot_mgr,
async_handle,
ibd_finished,
assume_valid_target,
assume_valid_targets,
assume_valid_target_specified,
header_map,
block_status_map,
Expand Down Expand Up @@ -467,8 +467,8 @@ impl Shared {
);
}

pub fn assume_valid_target(&self) -> MutexGuard<Option<H256>> {
self.assume_valid_target.lock()
pub fn assume_valid_targets(&self) -> MutexGuard<Option<Vec<H256>>> {
self.assume_valid_targets.lock()
}

pub fn assume_valid_target_specified(&self) -> Arc<Option<H256>> {
Expand Down
24 changes: 16 additions & 8 deletions shared/src/shared_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use ckb_tx_pool::{
};
use ckb_types::core::hardfork::HardForks;
use ckb_types::prelude::Pack;
use ckb_types::H256;
use ckb_types::{
core::service::PoolTransactionEntry, core::tx_pool::Reject, core::EpochExt, core::HeaderView,
};
Expand Down Expand Up @@ -352,10 +353,12 @@ impl SharedBuilder {
sync_config: &SyncConfig,
snapshot: &Snapshot,
) -> bool {
if let Some(ref target) = sync_config.assume_valid_target {
if snapshot.block_exists(&target.pack()) {
info!("assume valid target is already in db, CKB will do full verification from now on");
return true;
if let Some(ref target) = sync_config.assume_valid_targets {
if let Some(last_target) = target.last() {
if snapshot.block_exists(&last_target.pack()) {
info!("assume valid target is already in db, CKB will do full verification from now on");
return true;
}
}
}
false
Expand Down Expand Up @@ -442,14 +445,19 @@ impl SharedBuilder {

let block_status_map = Arc::new(DashMap::new());

let assume_valid_target = Arc::new(Mutex::new({
let assume_valid_targets = Arc::new(Mutex::new({
if Self::check_assume_valid_target_already_exists(&sync_config, &snapshot) {
None
} else {
sync_config.assume_valid_target.clone()
sync_config.assume_valid_targets.clone()
}
}));
let assume_valid_target_specified = Arc::new(sync_config.assume_valid_target);

let assume_valid_target_specified: Arc<Option<H256>> = Arc::new(
sync_config
.assume_valid_targets
.and_then(|targets| targets.last().cloned()),
);

let shared = Shared::new(
store,
Expand All @@ -460,7 +468,7 @@ impl SharedBuilder {
snapshot_mgr,
async_handle,
ibd_finished,
assume_valid_target,
assume_valid_targets,
assume_valid_target_specified,
header_map,
block_status_map,
Expand Down
8 changes: 6 additions & 2 deletions sync/src/synchronizer/block_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ckb_network::PeerIndex;
use ckb_shared::block_status::BlockStatus;
use ckb_shared::types::{HeaderIndex, HeaderIndexView};
use ckb_systemtime::unix_time_as_millis;
use ckb_types::core::BlockNumber;
use ckb_types::packed;
use ckb_types::BlockNumberAndHash;
use std::cmp::min;
Expand Down Expand Up @@ -91,7 +92,7 @@ impl BlockFetcher {
Some(last_common)
}

pub fn fetch(self) -> Option<Vec<Vec<packed::Byte32>>> {
pub fn fetch(self, fetch_end: BlockNumber) -> Option<Vec<Vec<packed::Byte32>>> {
let _trace_timecost: Option<HistogramTimer> = {
ckb_metrics::handle().map(|handle| handle.ckb_sync_block_fetch_duration.start_timer())
};
Expand Down Expand Up @@ -186,7 +187,10 @@ impl BlockFetcher {
IBDState::Out => last_common.number() + 1,
}
};
let mut end = min(best_known.number(), start + BLOCK_DOWNLOAD_WINDOW);
let mut end = min(
fetch_end,
min(best_known.number(), start + BLOCK_DOWNLOAD_WINDOW),
);
let n_fetch = min(
end.saturating_sub(start) as usize + 1,
state.read_inflight_blocks().peer_can_fetch_count(self.peer),
Expand Down
74 changes: 51 additions & 23 deletions sync/src/synchronizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const NOT_IBD_BLOCK_FETCH_INTERVAL: Duration = Duration::from_millis(200);

#[derive(Copy, Clone)]
enum CanStart {
FetchToTarget(BlockNumber),
Ready,
MinWorkNotReach,
AssumeValidNotFound,
Expand All @@ -90,25 +91,34 @@ impl BlockFetchCMD {
fn process_fetch_cmd(&mut self, cmd: FetchCMD) {
let FetchCMD { peers, ibd_state }: FetchCMD = cmd;

match self.can_start() {
CanStart::Ready => {
for peer in peers {
if ckb_stop_handler::has_received_stop_signal() {
return;
}
let fetch_blocks_fn = |cmd: &mut BlockFetchCMD, assume_target: BlockNumber| {
for peer in peers {
if ckb_stop_handler::has_received_stop_signal() {
return;
}

if let Some(fetch) =
BlockFetcher::new(Arc::clone(&self.sync_shared), peer, ibd_state).fetch()
{
for item in fetch {
if ckb_stop_handler::has_received_stop_signal() {
return;
}
BlockFetchCMD::send_getblocks(item, &self.p2p_control, peer);
let mut fetch_end: BlockNumber = u64::MAX;
if assume_target != 0 {
fetch_end = assume_target
}

if let Some(fetch) =
BlockFetcher::new(Arc::clone(&cmd.sync_shared), peer, ibd_state)
.fetch(fetch_end)
{
for item in fetch {
if ckb_stop_handler::has_received_stop_signal() {
return;
}
BlockFetchCMD::send_getblocks(item, &cmd.p2p_control, peer);
}
}
}
};

match self.can_start() {
CanStart::FetchToTarget(assume_target) => fetch_blocks_fn(self, assume_target),
CanStart::Ready => fetch_blocks_fn(self, BlockNumber::MAX),
CanStart::MinWorkNotReach => {
let best_known = self.sync_shared.state().shared_best_header_ref();
let number = best_known.number();
Expand All @@ -129,8 +139,9 @@ impl BlockFetchCMD {
let best_known = state.shared_best_header_ref();
let number = best_known.number();
let assume_valid_target: Byte32 = shared
.assume_valid_target()
.assume_valid_targets()
.as_ref()
.and_then(|targets| targets.first())
.map(Pack::pack)
.expect("assume valid target must exist");

Expand Down Expand Up @@ -234,15 +245,28 @@ impl BlockFetchCMD {
};

let assume_valid_target_find = |flag: &mut CanStart| {
let mut assume_valid_target = shared.assume_valid_target();
if let Some(ref target) = *assume_valid_target {
match shared.header_map().get(&target.pack()) {
let mut assume_valid_targets = shared.assume_valid_targets();
if let Some(ref targets) = *assume_valid_targets {
if targets.is_empty() {
assume_valid_targets.take();
*flag = CanStart::Ready;
return;
}
let first_target = targets
.first()
.expect("has checked targets is not empty, assume valid target must exist");
match shared.header_map().get(&first_target.pack()) {
Some(header) => {
*flag = CanStart::Ready;
info!("assume valid target found in header_map; CKB will start fetch blocks now");
if matches!(*flag, CanStart::FetchToTarget(fetch_target) if fetch_target == header.number())
{
// BlockFetchCMD has set the fetch target, no need to set it again
} else {
*flag = CanStart::FetchToTarget(header.number());
info!("assume valid target found in header_map; CKB will start fetch blocks to {:?} now", header.number_and_hash());
}
// Blocks that are no longer in the scope of ibd must be forced to verify
if unix_time_as_millis().saturating_sub(header.timestamp()) < MAX_TIP_AGE {
assume_valid_target.take();
assume_valid_targets.take();
warn!("the duration gap between 'assume valid target' and 'now' is less than 24h; CKB will ignore the specified assume valid target and do full verification from now on");
}
}
Expand All @@ -254,7 +278,7 @@ impl BlockFetchCMD {
{
warn!("the duration gap between 'shared_best_header' and 'now' is less than 24h, but CKB haven't found the assume valid target in header_map; CKB will ignore the specified assume valid target and do full verification from now on");
*flag = CanStart::Ready;
assume_valid_target.take();
assume_valid_targets.take();
}
}
}
Expand All @@ -264,6 +288,10 @@ impl BlockFetchCMD {
};

match self.can_start {
CanStart::FetchToTarget(_) => {
assume_valid_target_find(&mut self.can_start);
self.can_start
}
CanStart::Ready => self.can_start,
CanStart::MinWorkNotReach => {
min_work_reach(&mut self.can_start);
Expand Down Expand Up @@ -453,7 +481,7 @@ impl Synchronizer {
peer: PeerIndex,
ibd: IBDState,
) -> Option<Vec<Vec<packed::Byte32>>> {
BlockFetcher::new(Arc::clone(&self.shared), peer, ibd).fetch()
BlockFetcher::new(Arc::clone(&self.shared), peer, ibd).fetch(BlockNumber::MAX)
}

pub(crate) fn on_connected(&self, nc: &dyn CKBProtocolContext, peer: PeerIndex) {
Expand Down
Loading

0 comments on commit 770b84c

Please sign in to comment.