diff --git a/chain/src/verify.rs b/chain/src/verify.rs index dbd1839b64..7b103714b8 100644 --- a/chain/src/verify.rs +++ b/chain/src/verify.rs @@ -199,14 +199,21 @@ impl ConsumeUnverifiedBlockProcessor { switch: Option, ) -> 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::::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::::unpack(&BlockView::hash(block)); + if targets.first().eq(&Some(&block_hash)) { + targets.remove(0); + info!("CKB reached one asume_valid_target: {}", block_hash); + // assume_valid_targets.replace(targets.clone()); + } + + if targets.is_empty() { + assume_valid_targets.take(); + info!("CKB reached all asume_valid_targets, will do full verification now"); Switch::NONE } else { Switch::DISABLE_SCRIPT diff --git a/ckb-bin/src/cli.rs b/ckb-bin/src/cli.rs index fbda878d75..a8870861ef 100644 --- a/ckb-bin/src/cli.rs +++ b/ckb-bin/src/cli.rs @@ -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) diff --git a/ckb-bin/src/setup.rs b/ckb-bin/src/setup.rs index 789323d250..0df2aa5c70 100644 --- a/ckb-bin/src/setup.rs +++ b/ckb-bin/src/setup.rs @@ -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}; @@ -71,33 +71,47 @@ impl Setup { } else { u256!("0x0") }; - - let arg_assume_valid_target = matches.get_one::(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::(cli::ARG_ASSUME_VALID_TARGET) + .map(|concacate_targets| { + concacate_targets + .split(',') + .map(|s| H256::from_str(&s[2..])) + .collect::, _>>() + .map_err(|err| { + error!("Invalid assume valid target: {}", err); + ExitCode::Cli + }) + }) + .transpose()?; // Converts Result, E> to Option> + + 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::>()), 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::>()), + _ => 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 + ); + } + } } } diff --git a/devtools/release/update_default_valid_target.sh b/devtools/release/update_default_valid_target.sh index 5f7cb21e30..ef98161f6d 100755 --- a/devtools/release/update_default_valid_target.sh +++ b/devtools/release/update_default_valid_target.sh @@ -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 diff --git a/rpc/src/module/net.rs b/rpc/src/module/net.rs index de75699e68..855cefae7a 100644 --- a/rpc/src/module/net.rs +++ b/rpc/src/module/net.rs @@ -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() diff --git a/shared/src/shared.rs b/shared/src/shared.rs index 2939230a5f..8b523bfc83 100644 --- a/shared/src/shared.rs +++ b/shared/src/shared.rs @@ -62,7 +62,7 @@ pub struct Shared { pub(crate) async_handle: Handle, pub(crate) ibd_finished: Arc, - pub(crate) assume_valid_target: Arc>>, + pub(crate) assume_valid_targets: Arc>>>, pub(crate) assume_valid_target_specified: Arc>, pub header_map: Arc, @@ -83,7 +83,7 @@ impl Shared { async_handle: Handle, ibd_finished: Arc, - assume_valid_target: Arc>>, + assume_valid_targets: Arc>>>, assume_valid_target_specified: Arc>, header_map: Arc, block_status_map: Arc>, @@ -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, @@ -467,8 +467,8 @@ impl Shared { ); } - pub fn assume_valid_target(&self) -> MutexGuard> { - self.assume_valid_target.lock() + pub fn assume_valid_targets(&self) -> MutexGuard>> { + self.assume_valid_targets.lock() } pub fn assume_valid_target_specified(&self) -> Arc> { diff --git a/shared/src/shared_builder.rs b/shared/src/shared_builder.rs index 47f0a85e4e..72b0ce3343 100644 --- a/shared/src/shared_builder.rs +++ b/shared/src/shared_builder.rs @@ -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, }; @@ -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 @@ -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> = Arc::new( + sync_config + .assume_valid_targets + .and_then(|targets| targets.last().cloned()), + ); let shared = Shared::new( store, @@ -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, diff --git a/sync/src/synchronizer/block_fetcher.rs b/sync/src/synchronizer/block_fetcher.rs index b4d87cb3f6..2fdebbeed4 100644 --- a/sync/src/synchronizer/block_fetcher.rs +++ b/sync/src/synchronizer/block_fetcher.rs @@ -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; @@ -91,7 +92,7 @@ impl BlockFetcher { Some(last_common) } - pub fn fetch(self) -> Option>> { + pub fn fetch(self, fetch_end: BlockNumber) -> Option>> { let _trace_timecost: Option = { ckb_metrics::handle().map(|handle| handle.ckb_sync_block_fetch_duration.start_timer()) }; @@ -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), diff --git a/sync/src/synchronizer/mod.rs b/sync/src/synchronizer/mod.rs index 83aa1213c3..eadfd35082 100644 --- a/sync/src/synchronizer/mod.rs +++ b/sync/src/synchronizer/mod.rs @@ -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, @@ -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(); @@ -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"); @@ -234,15 +245,23 @@ 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"); + *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"); } } @@ -254,7 +273,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(); } } } @@ -264,7 +283,7 @@ impl BlockFetchCMD { }; match self.can_start { - CanStart::Ready => self.can_start, + CanStart::FetchToTarget(_) | CanStart::Ready => self.can_start, CanStart::MinWorkNotReach => { min_work_reach(&mut self.can_start); if let CanStart::AssumeValidNotFound = self.can_start { @@ -453,7 +472,7 @@ impl Synchronizer { peer: PeerIndex, ibd: IBDState, ) -> Option>> { - 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) { diff --git a/util/app-config/src/configs/network.rs b/util/app-config/src/configs/network.rs index 70d8cb3550..159f511f55 100644 --- a/util/app-config/src/configs/network.rs +++ b/util/app-config/src/configs/network.rs @@ -103,7 +103,7 @@ pub struct SyncConfig { pub header_map: HeaderMapConfig, /// Block hash of assume valid target #[serde(skip, default)] - pub assume_valid_target: Option, + pub assume_valid_targets: Option>, /// Proof of minimum work during synchronization #[serde(skip, default)] pub min_chain_work: U256, diff --git a/util/constant/src/default_assume_valid_target.rs b/util/constant/src/default_assume_valid_target.rs index b3638c3ee4..04bc67dbcc 100644 --- a/util/constant/src/default_assume_valid_target.rs +++ b/util/constant/src/default_assume_valid_target.rs @@ -1,31 +1,55 @@ -/// The mod mainnet and mod testnet's codes are generated -/// by script: ./devtools/release/update_default_valid_target.sh -/// Please don't modify them manually. -/// +/// Get default assume valid targets -/// sync config related to mainnet +/// mainnet pub mod mainnet { - /// Default assume valid target for mainnet, expect to be a block 60 days ago. - /// - /// Need to update when CKB's new release - /// in mainnet: the 60 days ago block is: - /// height: 13735790 - /// hash: 0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd - /// date: Sun Aug 11 07:55:39 AM CST 2024 - /// you can view this block in https://explorer.nervos.org/block/0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd - pub const DEFAULT_ASSUME_VALID_TARGET: &str = - "0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd"; + use crate::latest_assume_valid_target; + + /// get mainnet related default assume valid targets + pub fn default_assume_valid_targets() -> Vec<&'static str> { + vec![ + // + // height: 500,0000; https://explorer.nervos.org/block/0xb72f4d9758a36a2f9d4b8aea5a11d232e3e48332b76ec350f0a375fac10317a4 + "0xb72f4d9758a36a2f9d4b8aea5a11d232e3e48332b76ec350f0a375fac10317a4", + // + // height: 1,000,000; https://explorer.nervos.org/block/0x7544e2a9db2054fbe42215ece2e5d31f175972cfeccaa7597c8ff3ec5c8b7d67 + "0x7544e2a9db2054fbe42215ece2e5d31f175972cfeccaa7597c8ff3ec5c8b7d67", + // + // height: 2,000,000; https://explorer.nervos.org/block/0xc0c1ca7dcfa5862b9d2afeb5ea94db14744b8146c9005982879030f01e1f47cb + "0xc0c1ca7dcfa5862b9d2afeb5ea94db14744b8146c9005982879030f01e1f47cb", + // + // height: 4,000,000; https://explorer.nervos.org/block/0xcd925c9baa8c3110980546c916dad122dc69111780e49b50c3bb407ab7b6aa1c + "0xcd925c9baa8c3110980546c916dad122dc69111780e49b50c3bb407ab7b6aa1c", + // + // height: 8,000,000; https://explorer.nervos.org/block/0x063ccfcdbad01922792914f0bd61e47930bbb4a531f711013a24210638c0174a + "0x063ccfcdbad01922792914f0bd61e47930bbb4a531f711013a24210638c0174a", + latest_assume_valid_target::mainnet::DEFAULT_ASSUME_VALID_TARGET, + ] + } } -/// sync config related to testnet + +/// testnet pub mod testnet { - /// Default assume valid target for testnet, expect to be a block 60 days ago. - /// - /// Need to update when CKB's new release - /// in testnet: the 60 days ago block is: - /// height: 14203467 - /// hash: 0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445 - /// date: Sun Aug 11 07:56:19 AM CST 2024 - /// you can view this block in https://pudge.explorer.nervos.org/block/0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445 - pub const DEFAULT_ASSUME_VALID_TARGET: &str = - "0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445"; + use crate::latest_assume_valid_target; + + /// get testnet related default assume valid targets + pub fn default_assume_valid_targets() -> Vec<&'static str> { + vec![ + // + // height: 500,000; https://pudge.explorer.nervos.org/block/0xf9c73f3db9a7c6707c3c6800a9a0dbd5a2edf69e3921832f65275dcd71f7871c + "0xf9c73f3db9a7c6707c3c6800a9a0dbd5a2edf69e3921832f65275dcd71f7871c", + // + // height: 1,000,000; https://pudge.explorer.nervos.org/block/0x935a48f2660fd141121114786edcf17ef5789c6c2fe7aca04ea27813b30e1fa3 + "0x935a48f2660fd141121114786edcf17ef5789c6c2fe7aca04ea27813b30e1fa3", + // + // height: 2,000,000; https://pudge.explorer.nervos.org/block/0xf4d1648131b7bc4a0c9dbc442d240395c89a0c77b0cc197dce8794cd93669b32 + "0xf4d1648131b7bc4a0c9dbc442d240395c89a0c77b0cc197dce8794cd93669b32", + // + // height: 4,000,000; https://pudge.explorer.nervos.org/block/0xb33c0e0a649003ab65062e93a3126a2235f6e7c3ca1b16fe9938816d846bb14f + "0xb33c0e0a649003ab65062e93a3126a2235f6e7c3ca1b16fe9938816d846bb14f", + // + // height: 8,000,000; https://pudge.explorer.nervos.org/block/0x2be0f327e78032f495f90da159883da84f2efd5025fde106a6a7590b8fca6647 + "0x2be0f327e78032f495f90da159883da84f2efd5025fde106a6a7590b8fca6647", + latest_assume_valid_target::testnet::DEFAULT_ASSUME_VALID_TARGET, + ] + } } diff --git a/util/constant/src/latest_assume_valid_target.rs b/util/constant/src/latest_assume_valid_target.rs new file mode 100644 index 0000000000..b3638c3ee4 --- /dev/null +++ b/util/constant/src/latest_assume_valid_target.rs @@ -0,0 +1,31 @@ +/// The mod mainnet and mod testnet's codes are generated +/// by script: ./devtools/release/update_default_valid_target.sh +/// Please don't modify them manually. +/// + +/// sync config related to mainnet +pub mod mainnet { + /// Default assume valid target for mainnet, expect to be a block 60 days ago. + /// + /// Need to update when CKB's new release + /// in mainnet: the 60 days ago block is: + /// height: 13735790 + /// hash: 0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd + /// date: Sun Aug 11 07:55:39 AM CST 2024 + /// you can view this block in https://explorer.nervos.org/block/0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd + pub const DEFAULT_ASSUME_VALID_TARGET: &str = + "0x1dc6ebf09bf066b6d4c6b9bf1ded8e4c692c55b14f98bff231a4cb26720412cd"; +} +/// sync config related to testnet +pub mod testnet { + /// Default assume valid target for testnet, expect to be a block 60 days ago. + /// + /// Need to update when CKB's new release + /// in testnet: the 60 days ago block is: + /// height: 14203467 + /// hash: 0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445 + /// date: Sun Aug 11 07:56:19 AM CST 2024 + /// you can view this block in https://pudge.explorer.nervos.org/block/0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445 + pub const DEFAULT_ASSUME_VALID_TARGET: &str = + "0xa13450d53528d80fb5886f35386cf0119eea74cc63092c1138c38971416fe445"; +} diff --git a/util/constant/src/lib.rs b/util/constant/src/lib.rs index 41ce1df37b..fd84010230 100644 --- a/util/constant/src/lib.rs +++ b/util/constant/src/lib.rs @@ -11,5 +11,8 @@ pub mod store; /// sync constant pub mod sync; -/// hardcoded default assume valid target +/// default assume valid target pub mod default_assume_valid_target; + +/// hardcoded default assume valid target +pub mod latest_assume_valid_target;