,
consensus: Parlia,
- client: Client,
+ provider: Provider,
+ snapshot_reader: SnapshotReader,
to_engine: UnboundedSender>,
network_block_event_rx: Arc>>,
storage: Storage,
@@ -87,10 +108,12 @@ impl
block_interval: u64,
) {
let (fork_choice_tx, fork_choice_rx) = mpsc::unbounded_channel();
+ let (chain_tracker_tx, chain_tracker_rx) = mpsc::unbounded_channel();
let this = Self {
chain_spec,
consensus,
- client,
+ provider,
+ snapshot_reader: Arc::new(snapshot_reader),
to_engine,
network_block_event_rx,
storage,
@@ -98,10 +121,13 @@ impl
block_interval,
fork_choice_tx,
fork_choice_rx: Arc::new(Mutex::new(fork_choice_rx)),
+ chain_tracker_tx,
+ chain_tracker_rx: Arc::new(Mutex::new(chain_tracker_rx)),
};
this.start_block_event_listening();
this.start_fork_choice_update_notifier();
+ this.start_chain_tracker_notifier();
}
/// Start listening to the network block event
@@ -111,10 +137,11 @@ impl
let mut interval = interval(Duration::from_secs(block_interval));
let chain_spec = self.chain_spec.clone();
let storage = self.storage.clone();
- let client = self.client.clone();
+ let client = self.provider.clone();
let block_fetcher = self.block_fetcher.clone();
let consensus = self.consensus.clone();
let fork_choice_tx = self.fork_choice_tx.clone();
+ let chain_tracker_tx = self.chain_tracker_tx.clone();
let fetch_header_timeout_duration = Duration::from_secs(block_interval);
tokio::spawn(async move {
@@ -225,7 +252,7 @@ impl
// header number the timestamp of latest header should be bigger
// than the predicted timestamp and less than the current timestamp.
let predicted_timestamp = trusted_header.timestamp +
- block_interval * (latest_header.number - trusted_header.number);
+ block_interval * (latest_header.number - 1 - trusted_header.number);
let sealed_header = latest_header.clone().seal_slow();
let is_valid_header = match consensus
.validate_header_with_predicted_timestamp(&sealed_header, predicted_timestamp)
@@ -241,21 +268,84 @@ impl
continue
};
+ let mut disconnected_headers = Vec::new();
+ disconnected_headers.push(sealed_header.clone());
+ let pipeline_sync = (trusted_header.number + EPOCH_SLOTS) < sealed_header.number;
+ if !pipeline_sync && (sealed_header.number - 1) > trusted_header.number {
+ let fetch_headers_result = match timeout(
+ fetch_header_timeout_duration,
+ block_fetcher.get_headers(HeadersRequest {
+ start: BlockHashOrNumber::Hash(sealed_header.parent_hash),
+ limit: (sealed_header.number - 1) - trusted_header.number,
+ direction: HeadersDirection::Falling,
+ }),
+ )
+ .await
+ {
+ Ok(result) => result,
+ Err(_) => {
+ trace!(target: "consensus::parlia", "Fetch header timeout");
+ continue
+ }
+ };
+ if fetch_headers_result.is_err() {
+ trace!(target: "consensus::parlia", "Failed to fetch header");
+ continue
+ }
+
+ let headers = fetch_headers_result.unwrap().into_data();
+ for header in headers {
+ let sealed_header = header.clone().seal_slow();
+ let predicted_timestamp = trusted_header.timestamp +
+ block_interval * (sealed_header.number - 1 - trusted_header.number);
+ if consensus
+ .validate_header_with_predicted_timestamp(
+ &sealed_header,
+ predicted_timestamp,
+ )
+ .is_err()
+ {
+ trace!(target: "consensus::parlia", "Invalid header");
+ continue
+ }
+ disconnected_headers.push(sealed_header.clone());
+ }
+ };
+
// cache header and block
let mut storage = storage.write().await;
- storage.insert_new_header(sealed_header.clone());
if info.block.is_some() {
storage.insert_new_block(
sealed_header.clone(),
BlockBody::from(info.block.clone().unwrap()),
);
}
- drop(storage);
- let result = fork_choice_tx
- .send(ForkChoiceMessage::NewBlock(HashEvent { hash: sealed_header.hash() }));
+
+ for header in disconnected_headers {
+ storage.insert_new_header(header.clone());
+ let result =
+ fork_choice_tx.send(ForkChoiceMessage::NewHeader(NewHeaderEvent {
+ header: header.clone(),
+ // if the pipeline sync is true, the fork choice will not use the safe
+ // and finalized hash.
+ // this can make Block Sync Engine to use pipeline sync mode.
+ pipeline_sync,
+ trusted_header: trusted_header.clone(),
+ }));
+ if result.is_err() {
+ error!(target: "consensus::parlia", "Failed to send new block event to fork choice");
+ }
+ }
+
+ let result = chain_tracker_tx.send(ForkChoiceMessage::NewHeader(NewHeaderEvent {
+ header: sealed_header.clone(),
+ pipeline_sync,
+ trusted_header: trusted_header.clone(),
+ }));
if result.is_err() {
- error!(target: "consensus::parlia", "Failed to send new block event to fork choice");
+ error!(target: "consensus::parlia", "Failed to send new block event to chain tracker");
}
+ drop(storage);
}
});
info!(target: "consensus::parlia", "started listening to network block event")
@@ -264,6 +354,7 @@ impl
fn start_fork_choice_update_notifier(&self) {
let fork_choice_rx = self.fork_choice_rx.clone();
let to_engine = self.to_engine.clone();
+ let storage = self.storage.clone();
tokio::spawn(async move {
loop {
let mut fork_choice_rx_guard = fork_choice_rx.lock().await;
@@ -273,15 +364,24 @@ impl
continue;
}
match msg.unwrap() {
- ForkChoiceMessage::NewBlock(event) => {
+ ForkChoiceMessage::NewHeader(event) => {
// notify parlia engine
- let state = ForkchoiceState {
- head_block_hash: event.hash,
- // safe(justified) and finalized hash will be determined in the parlia consensus engine and stored in the snapshot after the block sync
+ let new_header = event.header;
+ let storage = storage.read().await;
+ let safe_hash = storage.best_safe_hash;
+ let finalized_hash = storage.best_finalized_hash;
+ drop(storage);
+
+ // safe(justified) and finalized hash will be determined in the parlia consensus engine and stored in the snapshot after the block sync
+ let mut state = ForkchoiceState {
+ head_block_hash: new_header.hash(),
safe_block_hash: B256::ZERO,
finalized_block_hash: B256::ZERO,
};
-
+ if !event.pipeline_sync {
+ state.safe_block_hash = safe_hash;
+ state.finalized_block_hash = finalized_hash;
+ }
// send the new update to the engine, this will trigger the engine
// to download and execute the block we just inserted
@@ -297,9 +397,10 @@ impl
Ok(result) => result,
Err(err)=> {
error!(target: "consensus::parlia", ?err, "Fork choice update response failed");
- continue
+ break
}
};
+
match rx_result {
Ok(fcu_response) => {
match fcu_response.forkchoice_status() {
@@ -308,14 +409,17 @@ impl
}
ForkchoiceStatus::Invalid => {
error!(target: "consensus::parlia", ?fcu_response, "Forkchoice update returned invalid response");
+ continue
}
ForkchoiceStatus::Syncing => {
- debug!(target: "consensus::parlia", ?fcu_response, "Forkchoice update returned SYNCING, waiting for VALID");
+ trace!(target: "consensus::parlia", ?fcu_response, "Forkchoice update returned SYNCING, waiting for VALID");
+ continue
}
}
}
Err(err) => {
error!(target: "consensus::parlia", %err, "Parlia fork choice update failed");
+ continue
}
}
}
@@ -330,10 +434,79 @@ impl
});
info!(target: "consensus::parlia", "started fork choice notifier")
}
+
+ fn start_chain_tracker_notifier(&self) {
+ let chain_tracker_rx = self.chain_tracker_rx.clone();
+ let snapshot_reader = self.snapshot_reader.clone();
+ let provider = self.provider.clone();
+ let storage = self.storage.clone();
+
+ tokio::spawn(async move {
+ loop {
+ let mut chain_tracker_rx_guard = chain_tracker_rx.lock().await;
+ tokio::select! {
+ msg = chain_tracker_rx_guard.recv() => {
+ if msg.is_none() {
+ continue;
+ }
+ match msg.unwrap() {
+ ForkChoiceMessage::NewHeader(event) => {
+ let new_header = event.trusted_header;
+
+ let snap = match snapshot_reader.snapshot(&new_header, None) {
+ Ok(snap) => snap,
+ Err(err) => {
+ error!(target: "consensus::parlia", %err, "Snapshot not found");
+ continue
+ }
+ };
+ // safe finalized and safe hash for next round fcu
+ let finalized_hash = snap.vote_data.source_hash;
+ let safe_hash = snap.vote_data.target_hash;
+ let mut storage = storage.write().await;
+ storage.insert_finalized_and_safe_hash(finalized_hash, safe_hash);
+ drop(storage);
+
+ // notify chain tracker to help rpc module can know the finalized and safe hash
+ match provider.sealed_header(snap.vote_data.source_number) {
+ Ok(header) => {
+ if let Some(sealed_header) = header {
+ provider.set_finalized(sealed_header.clone());
+ }
+ }
+ Err(err) => {
+ error!(target: "consensus::parlia", %err, "Failed to get source header");
+ }
+ }
+
+ match provider.sealed_header(snap.vote_data.target_number) {
+ Ok(header) => {
+ if let Some(sealed_header) = header {
+ provider.set_safe(sealed_header.clone());
+ }
+ }
+ Err(err) => {
+ error!(target: "consensus::parlia", %err, "Failed to get target header");
+ }
+ }
+ }
+
+ }
+ }
+ _ = signal::ctrl_c() => {
+ info!(target: "consensus::parlia", "chain tracker notifier shutting down...");
+ return
+ },
+ }
+ }
+ });
+
+ info!(target: "consensus::parlia", "started chain tracker notifier")
+ }
}
-impl fmt::Debug
- for ParliaEngineTask
+impl
+ fmt::Debug for ParliaEngineTask
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("chain_spec")
diff --git a/crates/bsc/evm/Cargo.toml b/crates/bsc/evm/Cargo.toml
index 53c59ce1c..6446157a6 100644
--- a/crates/bsc/evm/Cargo.toml
+++ b/crates/bsc/evm/Cargo.toml
@@ -13,6 +13,7 @@ workspace = true
[dependencies]
# Reth
reth-chainspec.workspace = true
+reth-ethereum-forks.workspace = true
reth-errors.workspace = true
reth-evm.workspace = true
reth-primitives.workspace = true
@@ -42,4 +43,4 @@ bsc = [
"reth-bsc-consensus/bsc",
"reth-primitives/bsc",
"revm-primitives/bsc",
-]
+]
\ No newline at end of file
diff --git a/crates/bsc/evm/src/config.rs b/crates/bsc/evm/src/config.rs
new file mode 100644
index 000000000..bf2ecb377
--- /dev/null
+++ b/crates/bsc/evm/src/config.rs
@@ -0,0 +1,100 @@
+use reth_chainspec::{BscHardfork, ChainSpec};
+use reth_ethereum_forks::{EthereumHardfork, Head};
+
+/// Returns the spec id at the given timestamp.
+///
+/// Note: This is only intended to be used after the merge, when hardforks are activated by
+/// timestamp.
+pub fn revm_spec_by_timestamp_after_shanghai(
+ chain_spec: &ChainSpec,
+ timestamp: u64,
+) -> revm_primitives::SpecId {
+ if chain_spec.fork(BscHardfork::HaberFix).active_at_timestamp(timestamp) {
+ revm_primitives::HABER_FIX
+ } else if chain_spec.fork(BscHardfork::Haber).active_at_timestamp(timestamp) {
+ revm_primitives::HABER
+ } else if chain_spec.fork(BscHardfork::FeynmanFix).active_at_timestamp(timestamp) {
+ revm_primitives::FEYNMAN_FIX
+ } else if chain_spec.fork(BscHardfork::Feynman).active_at_timestamp(timestamp) {
+ revm_primitives::FEYNMAN
+ } else if chain_spec.fork(BscHardfork::Kepler).active_at_timestamp(timestamp) {
+ revm_primitives::KEPLER
+ } else {
+ revm_primitives::SHANGHAI
+ }
+}
+
+/// return `revm_spec` from spec configuration.
+pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId {
+ if chain_spec.fork(BscHardfork::HaberFix).active_at_head(block) {
+ revm_primitives::HABER_FIX
+ } else if chain_spec.fork(BscHardfork::Haber).active_at_head(block) {
+ revm_primitives::HABER
+ } else if chain_spec.fork(EthereumHardfork::Cancun).active_at_head(block) {
+ revm_primitives::CANCUN
+ } else if chain_spec.fork(BscHardfork::FeynmanFix).active_at_head(block) {
+ revm_primitives::FEYNMAN_FIX
+ } else if chain_spec.fork(BscHardfork::Feynman).active_at_head(block) {
+ revm_primitives::FEYNMAN
+ } else if chain_spec.fork(BscHardfork::Kepler).active_at_head(block) {
+ revm_primitives::KEPLER
+ } else if chain_spec.fork(EthereumHardfork::Shanghai).active_at_head(block) {
+ revm_primitives::SHANGHAI
+ } else if chain_spec.fork(BscHardfork::HertzFix).active_at_head(block) {
+ revm_primitives::HERTZ_FIX
+ } else if chain_spec.fork(BscHardfork::Hertz).active_at_head(block) {
+ revm_primitives::HERTZ
+ } else if chain_spec.fork(EthereumHardfork::London).active_at_head(block) {
+ revm_primitives::LONDON
+ } else if chain_spec.fork(EthereumHardfork::Berlin).active_at_head(block) {
+ revm_primitives::BERLIN
+ } else if chain_spec.fork(BscHardfork::Plato).active_at_head(block) {
+ revm_primitives::PLATO
+ } else if chain_spec.fork(BscHardfork::Luban).active_at_head(block) {
+ revm_primitives::LUBAN
+ } else if chain_spec.fork(BscHardfork::Planck).active_at_head(block) {
+ revm_primitives::PLANCK
+ } else if chain_spec.fork(BscHardfork::Gibbs).active_at_head(block) {
+ // bsc mainnet and testnet have different order for Moran, Nano and Gibbs
+ if chain_spec.fork(BscHardfork::Moran).active_at_head(block) {
+ revm_primitives::MORAN
+ } else if chain_spec.fork(BscHardfork::Nano).active_at_head(block) {
+ revm_primitives::NANO
+ } else {
+ revm_primitives::EULER
+ }
+ } else if chain_spec.fork(BscHardfork::Moran).active_at_head(block) {
+ revm_primitives::MORAN
+ } else if chain_spec.fork(BscHardfork::Nano).active_at_head(block) {
+ revm_primitives::NANO
+ } else if chain_spec.fork(BscHardfork::Euler).active_at_head(block) {
+ revm_primitives::EULER
+ } else if chain_spec.fork(BscHardfork::Bruno).active_at_head(block) {
+ revm_primitives::BRUNO
+ } else if chain_spec.fork(BscHardfork::MirrorSync).active_at_head(block) {
+ revm_primitives::MIRROR_SYNC
+ } else if chain_spec.fork(BscHardfork::Niels).active_at_head(block) {
+ revm_primitives::NIELS
+ } else if chain_spec.fork(BscHardfork::Ramanujan).active_at_head(block) {
+ revm_primitives::RAMANUJAN
+ } else if chain_spec.fork(EthereumHardfork::MuirGlacier).active_at_head(block) {
+ revm_primitives::MUIR_GLACIER
+ } else if chain_spec.fork(EthereumHardfork::Istanbul).active_at_head(block) {
+ revm_primitives::ISTANBUL
+ } else if chain_spec.fork(EthereumHardfork::Petersburg).active_at_head(block) {
+ revm_primitives::PETERSBURG
+ } else if chain_spec.fork(EthereumHardfork::Constantinople).active_at_head(block) {
+ revm_primitives::CONSTANTINOPLE
+ } else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_head(block) {
+ revm_primitives::BYZANTIUM
+ } else if chain_spec.fork(EthereumHardfork::Homestead).active_at_head(block) {
+ revm_primitives::HOMESTEAD
+ } else if chain_spec.fork(EthereumHardfork::Frontier).active_at_head(block) {
+ revm_primitives::FRONTIER
+ } else {
+ panic!(
+ "invalid hardfork chainspec: expected at least one hardfork, got {:?}",
+ chain_spec.hardforks
+ )
+ }
+}
diff --git a/crates/bsc/evm/src/execute.rs b/crates/bsc/evm/src/execute.rs
index 186edc5c0..85a32f417 100644
--- a/crates/bsc/evm/src/execute.rs
+++ b/crates/bsc/evm/src/execute.rs
@@ -8,7 +8,7 @@ use reth_bsc_consensus::{
is_breathe_block, is_system_transaction, validate_block_post_execution, Parlia,
ValidatorElectionInfo, ValidatorsInfo,
};
-use reth_chainspec::ChainSpec;
+use reth_chainspec::{BscHardforks, ChainSpec, EthereumHardforks};
use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError};
use reth_evm::{
execute::{
@@ -18,7 +18,7 @@ use reth_evm::{
};
use reth_primitives::{
parlia::{ParliaConfig, Snapshot, VoteAddress, CHECKPOINT_INTERVAL},
- system_contracts::get_upgrade_system_contracts,
+ system_contracts::{get_upgrade_system_contracts, SLASH_CONTRACT},
Address, BlockNumber, BlockWithSenders, Bytes, Header, Receipt, Transaction, TransactionSigned,
B256, BSC_MAINNET, U256,
};
@@ -31,10 +31,10 @@ use reth_revm::{
};
use revm_primitives::{
db::{Database, DatabaseCommit},
- BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, TransactTo,
+ BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, ResultAndState, TransactTo,
};
use std::{collections::HashMap, num::NonZeroUsize, sync::Arc, time::Instant};
-use tracing::log::debug;
+use tracing::{debug, warn};
const SNAP_CACHE_NUM: usize = 2048;
@@ -83,7 +83,7 @@ where
{
fn bsc_executor(&self, db: DB) -> BscBlockExecutor
where
- DB: Database,
+ DB: Database + std::fmt::Display>,
{
BscBlockExecutor::new(
self.chain_spec.clone(),
@@ -100,25 +100,27 @@ where
P: ParliaProvider + Clone + Unpin + 'static,
EvmConfig: ConfigureEvm,
{
- type Executor> = BscBlockExecutor;
+ type Executor + std::fmt::Display>> =
+ BscBlockExecutor;
- type BatchExecutor> = BscBatchExecutor;
+ type BatchExecutor + std::fmt::Display>> =
+ BscBatchExecutor;
fn executor(&self, db: DB) -> Self::Executor
where
- DB: Database,
+ DB: Database + std::fmt::Display>,
{
self.bsc_executor(db)
}
- fn batch_executor(&self, db: DB, prune_modes: PruneModes) -> Self::BatchExecutor
+ fn batch_executor(&self, db: DB) -> Self::BatchExecutor
where
- DB: Database,
+ DB: Database + std::fmt::Display>,
{
let executor = self.bsc_executor(db);
BscBatchExecutor {
executor,
- batch_record: BlockBatchRecord::new(prune_modes),
+ batch_record: BlockBatchRecord::default(),
stats: BlockExecutorStats::default(),
snapshots: Vec::new(),
}
@@ -159,7 +161,7 @@ where
mut evm: Evm<'_, Ext, &mut State>,
) -> Result<(Vec, Vec, u64), BlockExecutionError>
where
- DB: Database,
+ DB: Database + std::fmt::Display>,
{
// execute transactions
let mut cumulative_gas_used = 0;
@@ -188,39 +190,45 @@ where
.into());
}
- self.patch_mainnet(&block.header, transaction, evm.db_mut());
- self.patch_chapel(&block.header, transaction, evm.db_mut());
+ self.patch_mainnet_before_tx(transaction, evm.db_mut());
+ self.patch_chapel_before_tx(transaction, evm.db_mut());
- EvmConfig::fill_tx_env(evm.tx_mut(), transaction, *sender);
+ self.evm_config.fill_tx_env(evm.tx_mut(), transaction, *sender);
// Execute transaction.
let ResultAndState { result, state } = evm.transact().map_err(move |err| {
+ let new_err = match err {
+ EVMError::Transaction(e) => EVMError::Transaction(e),
+ EVMError::Header(e) => EVMError::Header(e),
+ EVMError::Database(e) => EVMError::Database(e.into()),
+ EVMError::Custom(e) => EVMError::Custom(e),
+ EVMError::Precompile(e) => EVMError::Precompile(e),
+ };
// Ensure hash is calculated for error log, if not already done
BlockValidationError::EVM {
hash: transaction.recalculate_hash(),
- error: err.into(),
+ error: Box::new(new_err),
}
})?;
evm.db_mut().commit(state);
+ self.patch_mainnet_after_tx(transaction, evm.db_mut());
+ self.patch_chapel_after_tx(transaction, evm.db_mut());
+
// append gas used
cumulative_gas_used += result.gas_used();
// Push transaction changeset and calculate header bloom filter for receipt.
- receipts.push(
- #[allow(clippy::needless_update)] // side-effect of optimism fields
- Receipt {
- tx_type: transaction.tx_type(),
- // Success flag was added in `EIP-658: Embedding transaction status code in
- // receipts`.
- success: result.is_success(),
- cumulative_gas_used,
- // convert to reth log
- logs: result.into_logs(),
- ..Default::default()
- },
- );
+ receipts.push(Receipt {
+ tx_type: transaction.tx_type(),
+ // Success flag was added in `EIP-658: Embedding transaction status code in
+ // receipts`.
+ success: result.is_success(),
+ cumulative_gas_used,
+ // convert to reth log
+ logs: result.into_logs(),
+ });
}
drop(evm);
@@ -240,13 +248,13 @@ pub struct BscBlockExecutor {
/// The state to use for execution
pub(crate) state: State,
/// Extra provider for bsc
- provider: P,
+ pub(crate) provider: Arc,
/// Parlia consensus instance
- parlia: Arc,
+ pub(crate) parlia: Arc,
}
impl BscBlockExecutor {
- /// Creates a new Ethereum block executor.
+ /// Creates a new Parlia block executor.
pub fn new(
chain_spec: Arc,
evm_config: EvmConfig,
@@ -255,7 +263,13 @@ impl BscBlockExecutor {
provider: P,
) -> Self {
let parlia = Arc::new(Parlia::new(Arc::clone(&chain_spec), parlia_config));
- Self { executor: BscEvmExecutor { chain_spec, evm_config }, state, provider, parlia }
+ let shared_provider = Arc::new(provider);
+ Self {
+ executor: BscEvmExecutor { chain_spec, evm_config },
+ state,
+ provider: shared_provider,
+ parlia,
+ }
}
#[inline]
@@ -279,7 +293,7 @@ impl BscBlockExecutor {
impl BscBlockExecutor
where
EvmConfig: ConfigureEvm,
- DB: Database,
+ DB: Database + std::fmt::Display>,
P: ParliaProvider,
{
/// Configures a new evm configuration and block environment for the given block.
@@ -288,8 +302,7 @@ where
fn evm_env_for_block(&self, header: &Header, total_difficulty: U256) -> EnvWithHandlerCfg {
let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default());
let mut block_env = BlockEnv::default();
-
- EvmConfig::fill_cfg_and_block_env(
+ self.executor.evm_config.fill_cfg_and_block_env(
&mut cfg,
&mut block_env,
self.chain_spec(),
@@ -314,7 +327,8 @@ where
) -> Result {
// 1. get parent header and snapshot
let parent = &(self.get_header_by_hash(block.parent_hash)?);
- let snap = &(self.snapshot(parent, None)?);
+ let snapshot_reader = SnapshotReader::new(self.provider.clone(), self.parlia.clone());
+ let snap = &(snapshot_reader.snapshot(parent, None)?);
// 2. prepare state on new block
self.on_new_block(&block.header, parent, snap)?;
@@ -326,7 +340,7 @@ where
// 4. execute normal transactions
let env = self.evm_env_for_block(&block.header, total_difficulty);
- if !self.parlia.chain_spec().is_feynman_active_at_timestamp(block.timestamp) {
+ if !self.chain_spec().is_feynman_active_at_timestamp(block.timestamp) {
// apply system contract upgrade
self.upgrade_system_contracts(block.number, block.timestamp, parent.timestamp)?;
}
@@ -355,115 +369,6 @@ where
}
}
- pub(crate) fn find_ancient_header(
- &self,
- header: &Header,
- count: u64,
- ) -> Result {
- let mut result = header.clone();
- for _ in 0..count {
- result = self.get_header_by_hash(result.parent_hash)?;
- }
- Ok(result)
- }
-
- pub(crate) fn snapshot(
- &self,
- header: &Header,
- parent: Option<&Header>,
- ) -> Result {
- let mut cache = RECENT_SNAPS.write();
-
- let mut header = header.clone();
- let mut block_number = header.number;
- let mut block_hash = header.hash_slow();
- let mut skip_headers = Vec::new();
-
- let snap: Option;
- loop {
- // Read from cache
- if let Some(cached) = cache.get(&block_hash) {
- snap = Some(cached.clone());
- break;
- }
-
- // Read from db
- if block_number % CHECKPOINT_INTERVAL == 0 {
- if let Some(cached) =
- self.provider.get_parlia_snapshot(block_hash).map_err(|err| {
- BscBlockExecutionError::ProviderInnerError { error: err.into() }
- })?
- {
- snap = Some(cached);
- break;
- }
- }
-
- // If we're at the genesis, snapshot the initial state.
- if block_number == 0 {
- let ValidatorsInfo { consensus_addrs, vote_addrs } =
- self.parlia.parse_validators_from_header(&header).map_err(|err| {
- BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
- })?;
- snap = Some(Snapshot::new(
- consensus_addrs,
- block_number,
- block_hash,
- self.parlia.epoch(),
- vote_addrs,
- ));
- break;
- }
-
- // No snapshot for this header, gather the header and move backward
- skip_headers.push(header.clone());
- if let Some(parent) = parent {
- block_number = parent.number;
- block_hash = header.parent_hash;
- header = parent.clone();
- } else if let Ok(h) = self.get_header_by_hash(header.parent_hash) {
- block_number = h.number;
- block_hash = header.parent_hash;
- header = h;
- }
- }
-
- let mut snap = snap.ok_or_else(|| BscBlockExecutionError::SnapshotNotFound)?;
-
- // apply skip headers
- skip_headers.reverse();
- for header in &skip_headers {
- let ValidatorsInfo { consensus_addrs, vote_addrs } = if header.number > 0 &&
- header.number % self.parlia.epoch() == (snap.validators.len() / 2) as u64
- {
- // change validator set
- let checkpoint_header =
- self.find_ancient_header(header, (snap.validators.len() / 2) as u64)?;
-
- self.parlia.parse_validators_from_header(&checkpoint_header).map_err(|err| {
- BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
- })?
- } else {
- ValidatorsInfo::default()
- };
-
- let validator = self.parlia.recover_proposer(header).map_err(|err| {
- BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
- })?;
- let attestation =
- self.parlia.get_vote_attestation_from_header(header).map_err(|err| {
- BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
- })?;
-
- snap = snap
- .apply(validator, header, consensus_addrs, vote_addrs, attestation)
- .ok_or_else(|| BscBlockExecutionError::ApplySnapshotFailed)?;
- }
-
- cache.put(snap.block_hash, snap.clone());
- Ok(snap)
- }
-
pub(crate) fn get_justified_header(
&self,
snap: &Snapshot,
@@ -499,7 +404,7 @@ where
parent_block_time: u64,
) -> Result {
if let Ok(contracts) = get_upgrade_system_contracts(
- self.parlia().chain_spec(),
+ self.chain_spec(),
block_number,
block_time,
parent_block_time,
@@ -508,7 +413,7 @@ where
debug!("Upgrade system contract {:?} at height {:?}", k, block_number);
let account = self.state.load_cache_account(k).map_err(|err| {
- BscBlockExecutionError::ProviderInnerError { error: err.into() }
+ BscBlockExecutionError::ProviderInnerError { error: Box::new(err.into()) }
})?;
let mut new_info = account.account_info().unwrap_or_default();
@@ -555,9 +460,16 @@ where
block_env.basefee = U256::ZERO;
// Execute call.
- let ResultAndState { result, .. } = evm.transact().map_err(move |e| {
+ let ResultAndState { result, .. } = evm.transact().map_err(move |err| {
+ let new_err = match err {
+ EVMError::Transaction(e) => EVMError::Transaction(e),
+ EVMError::Header(e) => EVMError::Header(e),
+ EVMError::Database(e) => EVMError::Database(e.into()),
+ EVMError::Custom(e) => EVMError::Custom(e),
+ EVMError::Precompile(e) => EVMError::Precompile(e),
+ };
// Ensure hash is calculated for error log, if not already done
- BlockValidationError::EVM { hash: B256::default(), error: e.into() }
+ BlockValidationError::EVM { hash: B256::default(), error: Box::new(new_err) }
})?;
if !result.is_success() {
@@ -579,10 +491,30 @@ where
) -> Result<(), BlockExecutionError> {
let mut evm = self.executor.evm_config.evm_with_env(&mut self.state, env);
- let nonce = evm.db_mut().basic(sender).unwrap().unwrap_or_default().nonce;
+ let nonce = evm
+ .db_mut()
+ .basic(sender)
+ .map_err(|err| BscBlockExecutionError::ProviderInnerError {
+ error: Box::new(err.into()),
+ })
+ .unwrap()
+ .unwrap_or_default()
+ .nonce;
transaction.set_nonce(nonce);
let hash = transaction.signature_hash();
- if hash != system_txs[0].signature_hash() {
+ if system_txs.is_empty() || hash != system_txs[0].signature_hash() {
+ // slash tx could fail and not in the block
+ if let Some(to) = transaction.to() {
+ if to == SLASH_CONTRACT.parse::().unwrap() &&
+ (system_txs.is_empty() ||
+ system_txs[0].to().unwrap_or_default() !=
+ SLASH_CONTRACT.parse::().unwrap())
+ {
+ warn!("slash validator failed");
+ return Ok(());
+ }
+ }
+
debug!("unexpected transaction: {:?}", transaction);
for tx in system_txs.iter() {
debug!("left system tx: {:?}", tx);
@@ -614,9 +546,16 @@ where
block_env.basefee = U256::ZERO;
// Execute transaction.
- let ResultAndState { result, state } = evm.transact().map_err(move |e| {
+ let ResultAndState { result, state } = evm.transact().map_err(move |err| {
+ let new_err = match err {
+ EVMError::Transaction(e) => EVMError::Transaction(e),
+ EVMError::Header(e) => EVMError::Header(e),
+ EVMError::Database(e) => EVMError::Database(e.into()),
+ EVMError::Custom(e) => EVMError::Custom(e),
+ EVMError::Precompile(e) => EVMError::Precompile(e),
+ };
// Ensure hash is calculated for error log, if not already done
- BlockValidationError::EVM { hash, error: e.into() }
+ BlockValidationError::EVM { hash, error: Box::new(new_err) }
})?;
evm.db_mut().commit(state);
@@ -667,12 +606,9 @@ where
};
// 2. get election info
- if self.parlia().chain_spec().is_feynman_active_at_timestamp(header.timestamp) &&
+ if self.chain_spec().is_feynman_active_at_timestamp(header.timestamp) &&
is_breathe_block(parent.timestamp, header.timestamp) &&
- !self
- .parlia()
- .chain_spec()
- .is_on_feynman_at_timestamp(header.timestamp, parent.timestamp)
+ !self.chain_spec().is_on_feynman_at_timestamp(header.timestamp, parent.timestamp)
{
let (to, data) = self.parlia().get_max_elected_validators();
let bz = self.eth_call(to, data, env.clone())?;
@@ -715,7 +651,7 @@ where
number: BlockNumber,
env: EnvWithHandlerCfg,
) -> (Vec, Vec) {
- if !self.parlia().chain_spec().is_luban_active_at_block(number) {
+ if !self.chain_spec().is_luban_active_at_block(number) {
let (to, data) = self.parlia().get_current_validators_before_luban(number);
let output = self.eth_call(to, data, env).unwrap();
@@ -732,7 +668,7 @@ where
impl Executor for BscBlockExecutor
where
EvmConfig: ConfigureEvm,
- DB: Database,
+ DB: Database + std::fmt::Display>,
P: ParliaProvider,
{
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
@@ -788,7 +724,7 @@ impl BscBatchExecutor {
impl BatchExecutor for BscBatchExecutor
where
EvmConfig: ConfigureEvm,
- DB: Database,
+ DB: Database + std::fmt::Display>,
P: ParliaProvider,
{
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
@@ -843,7 +779,144 @@ where
self.batch_record.set_tip(tip);
}
+ fn set_prune_modes(&mut self, prune_modes: PruneModes) {
+ self.batch_record.set_prune_modes(prune_modes);
+ }
+
fn size_hint(&self) -> Option {
Some(self.executor.state.bundle_state.size_hint())
}
}
+
+#[derive(Debug, Clone)]
+pub struct SnapshotReader {
+ /// Extra provider for bsc
+ provider: Arc
,
+ /// Parlia consensus instance
+ parlia: Arc,
+}
+
+impl SnapshotReader
+where
+ P: ParliaProvider,
+{
+ pub fn new(provider: Arc
, parlia: Arc) -> Self {
+ Self { provider, parlia }
+ }
+
+ pub fn snapshot(
+ &self,
+ header: &Header,
+ parent: Option<&Header>,
+ ) -> Result {
+ let mut cache = RECENT_SNAPS.write();
+
+ let mut header = header.clone();
+ let mut block_number = header.number;
+ let mut block_hash = header.hash_slow();
+ let mut skip_headers = Vec::new();
+
+ let snap: Option;
+ loop {
+ // Read from cache
+ if let Some(cached) = cache.get(&block_hash) {
+ snap = Some(cached.clone());
+ break;
+ }
+
+ // Read from db
+ if block_number % CHECKPOINT_INTERVAL == 0 {
+ if let Some(cached) =
+ self.provider.get_parlia_snapshot(block_hash).map_err(|err| {
+ BscBlockExecutionError::ProviderInnerError { error: err.into() }
+ })?
+ {
+ snap = Some(cached);
+ break;
+ }
+ }
+
+ // If we're at the genesis, snapshot the initial state.
+ if block_number == 0 {
+ let ValidatorsInfo { consensus_addrs, vote_addrs } =
+ self.parlia.parse_validators_from_header(&header).map_err(|err| {
+ BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
+ })?;
+ snap = Some(Snapshot::new(
+ consensus_addrs,
+ block_number,
+ block_hash,
+ self.parlia.epoch(),
+ vote_addrs,
+ ));
+ break;
+ }
+
+ // No snapshot for this header, gather the header and move backward
+ skip_headers.push(header.clone());
+ if let Some(parent) = parent {
+ block_number = parent.number;
+ block_hash = header.parent_hash;
+ header = parent.clone();
+ } else if let Ok(h) = self.get_header_by_hash(header.parent_hash) {
+ block_number = h.number;
+ block_hash = header.parent_hash;
+ header = h;
+ }
+ }
+
+ let mut snap = snap.ok_or_else(|| BscBlockExecutionError::SnapshotNotFound)?;
+
+ // apply skip headers
+ skip_headers.reverse();
+ for header in &skip_headers {
+ let ValidatorsInfo { consensus_addrs, vote_addrs } = if header.number > 0 &&
+ header.number % self.parlia.epoch() == (snap.validators.len() / 2) as u64
+ {
+ // change validator set
+ let checkpoint_header =
+ self.find_ancient_header(header, (snap.validators.len() / 2) as u64)?;
+
+ self.parlia.parse_validators_from_header(&checkpoint_header).map_err(|err| {
+ BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
+ })?
+ } else {
+ ValidatorsInfo::default()
+ };
+
+ let validator = self.parlia.recover_proposer(header).map_err(|err| {
+ BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
+ })?;
+ let attestation =
+ self.parlia.get_vote_attestation_from_header(header).map_err(|err| {
+ BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
+ })?;
+
+ snap = snap
+ .apply(validator, header, consensus_addrs, vote_addrs, attestation)
+ .ok_or_else(|| BscBlockExecutionError::ApplySnapshotFailed)?;
+ }
+
+ cache.put(snap.block_hash, snap.clone());
+ Ok(snap)
+ }
+
+ fn get_header_by_hash(&self, block_hash: B256) -> Result {
+ self.provider
+ .header(&block_hash)
+ .map_err(|err| BscBlockExecutionError::ProviderInnerError { error: err.into() })?
+ .ok_or_else(|| BscBlockExecutionError::UnknownHeader { block_hash }.into())
+ }
+
+ fn find_ancient_header(
+ &self,
+ header: &Header,
+ count: u64,
+ ) -> Result {
+ let mut result = header.clone();
+ for _ in 0..count {
+ result = self.get_header_by_hash(result.parent_hash)?;
+ }
+ Ok(result)
+ }
+}
diff --git a/crates/bsc/evm/src/lib.rs b/crates/bsc/evm/src/lib.rs
index 1810fbb7c..4344f5944 100644
--- a/crates/bsc/evm/src/lib.rs
+++ b/crates/bsc/evm/src/lib.rs
@@ -9,13 +9,16 @@
use reth_chainspec::ChainSpec;
use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
use reth_primitives::{
- revm::{config::revm_spec, env::fill_tx_env},
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
- Address, Head, Header, TransactionSigned, U256,
+ transaction::FillTxEnv,
+ Address, Bytes, Head, Header, TransactionSigned, U256,
};
use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector};
+use revm_primitives::Env;
-pub mod execute;
+mod config;
+pub use config::{revm_spec, revm_spec_by_timestamp_after_shanghai};
+mod execute;
pub use execute::*;
mod error;
pub use error::BscBlockExecutionError;
@@ -29,11 +32,22 @@ mod pre_execution;
pub struct BscEvmConfig;
impl ConfigureEvmEnv for BscEvmConfig {
- fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
- fill_tx_env(tx_env, transaction, sender)
+ fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
+ transaction.fill_tx_env(tx_env, sender);
+ }
+
+ fn fill_tx_env_system_contract_call(
+ &self,
+ _env: &mut Env,
+ _caller: Address,
+ _contract: Address,
+ _data: Bytes,
+ ) {
+ // No system contract call on BSC
}
fn fill_cfg_env(
+ &self,
cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header,
@@ -41,7 +55,7 @@ impl ConfigureEvmEnv for BscEvmConfig {
) {
let spec_id = revm_spec(
chain_spec,
- Head {
+ &Head {
number: header.number,
timestamp: header.timestamp,
difficulty: header.difficulty,
@@ -98,7 +112,7 @@ mod tests {
let chain_spec = ChainSpec::default();
let total_difficulty = U256::ZERO;
- BscEvmConfig::fill_cfg_and_block_env(
+ BscEvmConfig::default().fill_cfg_and_block_env(
&mut cfg_env,
&mut block_env,
&chain_spec,
diff --git a/crates/bsc/evm/src/patch_hertz.rs b/crates/bsc/evm/src/patch_hertz.rs
index c4b866209..d375c9006 100644
--- a/crates/bsc/evm/src/patch_hertz.rs
+++ b/crates/bsc/evm/src/patch_hertz.rs
@@ -1,447 +1,745 @@
-use crate::execute::BscEvmExecutor;
+use crate::{execute::BscEvmExecutor, BscBlockExecutionError};
+use lazy_static::lazy_static;
use reth_errors::ProviderError;
use reth_evm::ConfigureEvm;
-use reth_primitives::{address, b256, Address, Header, TransactionSigned, B256, U256};
-use reth_revm::{
- db::{states::CacheAccount, AccountStatus::Destroyed},
- State,
-};
+use reth_primitives::{address, b256, Address, TransactionSigned, B256, U256};
+use reth_revm::{db::states::StorageSlot, State};
use revm_primitives::db::Database;
use std::{collections::HashMap, str::FromStr};
-use tracing::log::trace;
+use tracing::trace;
-impl BscEvmExecutor
-where
- EvmConfig: ConfigureEvm,
-{
- pub(crate) fn patch_mainnet(
- &self,
- header: &Header,
- transaction: &TransactionSigned,
- state: &mut State,
- ) where
- DB: Database,
- {
- let patches = vec![
- // patch 1: BlockNum 33851236, txIndex 89(patch before tx 89)
+struct StoragePatch {
+ address: Address,
+ storage: HashMap,
+}
+
+lazy_static! {
+ static ref MAINNET_PATCHES_BEFORE_TX: HashMap = HashMap::from([
+ // patch 1: BlockNum 33851236, txIndex 89
(
- b256!("022296e50021d7225b75f3873e7bc5a2bf6376a08079b4368f9dee81946d623b"),
b256!("7eba4edc7c1806d6ee1691d43513838931de5c94f9da56ec865721b402f775b0"),
- address!("00000000001f8b68515EfB546542397d3293CCfd"),
- HashMap::from([
- (
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- U256::from_str(
- "0x00000000000000000000000052db206170b430da8223651d28830e56ba3cdc04",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000002",
- )
- .unwrap(),
- U256::from_str(
- "0x000000000000000000000000bb45f138499734bf5c0948d490c65903676ea1de",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x65c95177950b486c2071bf2304da1427b9136564150fb97266ffb318b03a71cc",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x245e58a02bec784ccbdb9e022a84af83227a4125a22a5e68fcc596c7e436434e",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x1c4534c86090a60a9120f34c7b15254913c00bda3d4b276d6edb65c9f48a913f",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000004",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000019",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b4",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000000",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b5",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000000",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b6",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000000",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000005",
- )
- .unwrap(),
- U256::from_str(
- "0x00000000000000000000000000000000000000000000000000000000000fc248",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000006",
- )
- .unwrap(),
- U256::from_str(
- "0x00000000000000000000000000000000000000000000000000000000000fc132",
- )
- .unwrap(),
- ),
- ]),
+ StoragePatch {
+ address: address!("00000000001f8b68515EfB546542397d3293CCfd"),
+ storage: HashMap::from([
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x00000000000000000000000052db206170b430da8223651d28830e56ba3cdc04",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000002",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x000000000000000000000000bb45f138499734bf5c0948d490c65903676ea1de",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x65c95177950b486c2071bf2304da1427b9136564150fb97266ffb318b03a71cc",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x245e58a02bec784ccbdb9e022a84af83227a4125a22a5e68fcc596c7e436434e",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x1c4534c86090a60a9120f34c7b15254913c00bda3d4b276d6edb65c9f48a913f",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000004",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000019",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b4",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b5",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1b6",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000000",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000005",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x00000000000000000000000000000000000000000000000000000000000fc248",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000006",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x00000000000000000000000000000000000000000000000000000000000fc132",
+ )
+ .unwrap(),
+ ),
+ ]),
+ }
),
- // patch 2: BlockNum 33851236, txIndex 90(patch before tx 90)
+ // patch 2: BlockNum 33851236, txIndex 90
(
- b256!("022296e50021d7225b75f3873e7bc5a2bf6376a08079b4368f9dee81946d623b"),
b256!("5217324f0711af744fe8e12d73f13fdb11805c8e29c0c095ac747b7e4563e935"),
- address!("00000000001f8b68515EfB546542397d3293CCfd"),
- HashMap::from([
- (
- U256::from_str(
- "0xbcfc62ca570bdb58cf9828ac51ae8d7e063a1cc0fa1aee57691220a7cd78b1c8",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x30dce49ce1a4014301bf21aad0ee16893e4dcc4a4e4be8aa10e442dd13259837",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xc0582628d787ee16fe03c8e5b5f5644d3b81989686f8312280b7a1f733145525",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xfca5cf22ff2e8d58aece8e4370cce33cd0144d48d00f40a5841df4a42527694b",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xb189302b37865d2ae522a492ff1f61a5addc1db44acbdcc4b6814c312c815f46",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xfe1f1986775fc2ac905aeaecc7b1aa8b0d6722b852c90e26edacd2dac7382489",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x36052a8ddb27fecd20e2e09da15494a0f2186bf8db36deebbbe701993f8c4aae",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x4959a566d8396b889ff4bc20e18d2497602e01e5c6013af5af7a7c4657ece3e2",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xe0b5aeb100569add952966f803cb67aca86dc6ec8b638f5a49f9e0760efa9a7a",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x632467ad388b91583f956f76488afc42846e283c962cbb215d288033ffc4fb71",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x9ad4e69f52519f7b7b8ee5ae3326d57061b429428ea0c056dd32e7a7102e79a7",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x35e130c7071699eae5288b12374ef157a15e4294e2b3a352160b7c1cd4641d82",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xa0d8279f845f63979dc292228adfa0bda117de27e44d90ac2adcd44465b225e7",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x9a100b70ffda9ed9769becdadca2b2936b217e3da4c9b9817bad30d85eab25ff",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x28d67156746295d901005e2d95ce589e7093decb638f8c132d9971fd0a37e176",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x297c4e115b5df76bcd5a1654b8032661680a1803e30a0774cb42bb01891e6d97",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x5f71b88f1032d27d8866948fc9c49525f3e584bdd52a66de6060a7b1f767326f",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0xe6d8ddf6a0bbeb4840f48f0c4ffda9affa4675354bdb7d721235297f5a094f54",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
- U256::from_str(
- "0x30ba10aef6238bf19667aaa988b18b72adb4724c016e19eb64bbb52808d1a842",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
- )
- .unwrap(),
- ),
- (
+ StoragePatch {
+ address: address!("00000000001f8b68515EfB546542397d3293CCfd"),
+ storage: HashMap::from([
+ (
+ U256::from_str(
+ "0xbcfc62ca570bdb58cf9828ac51ae8d7e063a1cc0fa1aee57691220a7cd78b1c8",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x30dce49ce1a4014301bf21aad0ee16893e4dcc4a4e4be8aa10e442dd13259837",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xc0582628d787ee16fe03c8e5b5f5644d3b81989686f8312280b7a1f733145525",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xfca5cf22ff2e8d58aece8e4370cce33cd0144d48d00f40a5841df4a42527694b",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xb189302b37865d2ae522a492ff1f61a5addc1db44acbdcc4b6814c312c815f46",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xfe1f1986775fc2ac905aeaecc7b1aa8b0d6722b852c90e26edacd2dac7382489",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x36052a8ddb27fecd20e2e09da15494a0f2186bf8db36deebbbe701993f8c4aae",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x4959a566d8396b889ff4bc20e18d2497602e01e5c6013af5af7a7c4657ece3e2",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xe0b5aeb100569add952966f803cb67aca86dc6ec8b638f5a49f9e0760efa9a7a",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x632467ad388b91583f956f76488afc42846e283c962cbb215d288033ffc4fb71",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x9ad4e69f52519f7b7b8ee5ae3326d57061b429428ea0c056dd32e7a7102e79a7",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x35e130c7071699eae5288b12374ef157a15e4294e2b3a352160b7c1cd4641d82",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xa0d8279f845f63979dc292228adfa0bda117de27e44d90ac2adcd44465b225e7",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x9a100b70ffda9ed9769becdadca2b2936b217e3da4c9b9817bad30d85eab25ff",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x28d67156746295d901005e2d95ce589e7093decb638f8c132d9971fd0a37e176",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x297c4e115b5df76bcd5a1654b8032661680a1803e30a0774cb42bb01891e6d97",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x5f71b88f1032d27d8866948fc9c49525f3e584bdd52a66de6060a7b1f767326f",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xe6d8ddf6a0bbeb4840f48f0c4ffda9affa4675354bdb7d721235297f5a094f54",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x30ba10aef6238bf19667aaa988b18b72adb4724c016e19eb64bbb52808d1a842",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0x9c6806a4d6a99e4869b9a4aaf80b0a3bf5f5240a1d6032ed82edf0e86f2a2467",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xe8480d613bbf3b979aee2de4487496167735bb73df024d988e1795b3c7fa559a",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ (
+ U256::from_str(
+ "0xebfaec01f898f7f0e2abdb4b0aee3dfbf5ec2b287b1e92f9b62940f85d5f5bac",
+ )
+ .unwrap(),
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ ),
+ ]),
+ }
+ )
+ ]);
+ static ref MAINNET_PATCHES_AFTER_TX: HashMap = HashMap::from([
+ // patch 1: BlockNum 33851236, txIndex 89
+ (
+ b256!("7eba4edc7c1806d6ee1691d43513838931de5c94f9da56ec865721b402f775b0"),
+ StoragePatch {
+ address: address!("00000000001f8b68515EfB546542397d3293CCfd"),
+ storage: HashMap::from([
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000002",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x65c95177950b486c2071bf2304da1427b9136564150fb97266ffb318b03a71cc",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x245e58a02bec784ccbdb9e022a84af83227a4125a22a5e68fcc596c7e436434e",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x1c4534c86090a60a9120f34c7b15254913c00bda3d4b276d6edb65c9f48a913f",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000005",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x0000000000000000000000000000000000000000000000000000000000000006",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ ]),
+ }
+ ),
+ // patch 2: BlockNum 33851236, txIndex 90
+ (
+ b256!("5217324f0711af744fe8e12d73f13fdb11805c8e29c0c095ac747b7e4563e935"),
+ StoragePatch {
+ address: address!("00000000001f8b68515EfB546542397d3293CCfd"),
+ storage: HashMap::from([
+ (
+ U256::from_str(
+ "0xbcfc62ca570bdb58cf9828ac51ae8d7e063a1cc0fa1aee57691220a7cd78b1c8",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x30dce49ce1a4014301bf21aad0ee16893e4dcc4a4e4be8aa10e442dd13259837",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xc0582628d787ee16fe03c8e5b5f5644d3b81989686f8312280b7a1f733145525",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xfca5cf22ff2e8d58aece8e4370cce33cd0144d48d00f40a5841df4a42527694b",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xb189302b37865d2ae522a492ff1f61a5addc1db44acbdcc4b6814c312c815f46",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xfe1f1986775fc2ac905aeaecc7b1aa8b0d6722b852c90e26edacd2dac7382489",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x36052a8ddb27fecd20e2e09da15494a0f2186bf8db36deebbbe701993f8c4aae",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x4959a566d8396b889ff4bc20e18d2497602e01e5c6013af5af7a7c4657ece3e2",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xe0b5aeb100569add952966f803cb67aca86dc6ec8b638f5a49f9e0760efa9a7a",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x632467ad388b91583f956f76488afc42846e283c962cbb215d288033ffc4fb71",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x9ad4e69f52519f7b7b8ee5ae3326d57061b429428ea0c056dd32e7a7102e79a7",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x35e130c7071699eae5288b12374ef157a15e4294e2b3a352160b7c1cd4641d82",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xa0d8279f845f63979dc292228adfa0bda117de27e44d90ac2adcd44465b225e7",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x9a100b70ffda9ed9769becdadca2b2936b217e3da4c9b9817bad30d85eab25ff",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x28d67156746295d901005e2d95ce589e7093decb638f8c132d9971fd0a37e176",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x297c4e115b5df76bcd5a1654b8032661680a1803e30a0774cb42bb01891e6d97",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x5f71b88f1032d27d8866948fc9c49525f3e584bdd52a66de6060a7b1f767326f",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xe6d8ddf6a0bbeb4840f48f0c4ffda9affa4675354bdb7d721235297f5a094f54",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x30ba10aef6238bf19667aaa988b18b72adb4724c016e19eb64bbb52808d1a842",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0x9c6806a4d6a99e4869b9a4aaf80b0a3bf5f5240a1d6032ed82edf0e86f2a2467",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xe8480d613bbf3b979aee2de4487496167735bb73df024d988e1795b3c7fa559a",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ (
+ U256::from_str(
+ "0xebfaec01f898f7f0e2abdb4b0aee3dfbf5ec2b287b1e92f9b62940f85d5f5bac",
+ )
+ .unwrap(),
+ U256::ZERO,
+ ),
+ ]),
+ }
+ )
+ ]);
+ static ref CHAPEL_PATCHES_BEFORE_TX: HashMap = HashMap::from([
+ // patch 1: BlockNum 35547779, txIndex 196
+ (
+ b256!("7ce9a3cf77108fcc85c1e84e88e363e3335eca515dfcf2feb2011729878b13a7"),
+ StoragePatch {
+ address: address!("89791428868131eb109e42340ad01eb8987526b2"),
+ storage: HashMap::from([(
U256::from_str(
- "0x9c6806a4d6a99e4869b9a4aaf80b0a3bf5f5240a1d6032ed82edf0e86f2a2467",
+ "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
)
.unwrap(),
U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x0000000000000000000000000000000000000000000000f6a7831804efd2cd0a",
)
.unwrap(),
- ),
- (
+ )]),
+ },
+ ),
+ // patch 2: BlockNum 35548081, txIndex 486
+ (
+ b256!("e3895eb95605d6b43ceec7876e6ff5d1c903e572bf83a08675cb684c047a695c"),
+ StoragePatch {
+ address: address!("89791428868131eb109e42340ad01eb8987526b2"),
+ storage: HashMap::from([(
U256::from_str(
- "0xe8480d613bbf3b979aee2de4487496167735bb73df024d988e1795b3c7fa559a",
+ "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
)
.unwrap(),
U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x0000000000000000000000000000000000000000000000114be8ecea72b64003",
)
.unwrap(),
- ),
- (
+ )]),
+ },
+ ),
+ ]);
+ static ref CHAPEL_PATCHES_AFTER_TX: HashMap = HashMap::from([
+ // patch 1: BlockNum 35547779, txIndex 196
+ (
+ b256!("7ce9a3cf77108fcc85c1e84e88e363e3335eca515dfcf2feb2011729878b13a7"),
+ StoragePatch {
+ address: address!("89791428868131eb109e42340ad01eb8987526b2"),
+ storage: HashMap::from([(
U256::from_str(
- "0xebfaec01f898f7f0e2abdb4b0aee3dfbf5ec2b287b1e92f9b62940f85d5f5bac",
+ "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
)
.unwrap(),
+ U256::ZERO,
+ )]),
+ },
+ ),
+ // patch 2: BlockNum 35548081, txIndex 486
+ (
+ b256!("e3895eb95605d6b43ceec7876e6ff5d1c903e572bf83a08675cb684c047a695c"),
+ StoragePatch {
+ address: address!("89791428868131eb109e42340ad01eb8987526b2"),
+ storage: HashMap::from([(
U256::from_str(
- "0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
)
.unwrap(),
- ),
- ]),
+ U256::ZERO,
+ )]),
+ },
),
- ];
+ ]);
+}
- apply_patch(header, transaction, state, patches);
+impl BscEvmExecutor
+where
+ EvmConfig: ConfigureEvm,
+{
+ pub(crate) fn patch_mainnet_before_tx(
+ &self,
+ transaction: &TransactionSigned,
+ state: &mut State,
+ ) where
+ DB: Database + std::fmt::Display>,
+ {
+ let tx_hash = transaction.recalculate_hash();
+ if let Some(patch) = MAINNET_PATCHES_BEFORE_TX.get(&tx_hash) {
+ trace!("patch evm state for mainnet before tx {:?}", tx_hash);
+
+ apply_patch(state, patch.address, &patch.storage);
+ }
}
- pub(crate) fn patch_chapel(
+ pub(crate) fn patch_chapel_before_tx(
&self,
- header: &Header,
transaction: &TransactionSigned,
state: &mut State,
) where
- DB: Database,
+ DB: Database + std::fmt::Display>,
{
- let patches = vec![
- // patch 1: BlockNum 35547779, txIndex 196(patch before tx 196)
- (
- b256!("1237cb09a7d08c187a78e777853b70be28a41bb188c5341987408623c1a4f4aa"),
- b256!("7ce9a3cf77108fcc85c1e84e88e363e3335eca515dfcf2feb2011729878b13a7"),
- address!("89791428868131eb109e42340ad01eb8987526b2"),
- HashMap::from([(
- U256::from_str(
- "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000f6a7831804efd2cd0a",
- )
- .unwrap(),
- )]),
- ),
- // patch 2: BlockNum 35548081, txIndex 486(patch before tx 486)
- (
- b256!("cdd38b3681c8f3f1da5569a893231466ab35f47d58ba85dbd7d9217f304983bf"),
- b256!("e3895eb95605d6b43ceec7876e6ff5d1c903e572bf83a08675cb684c047a695c"),
- address!("89791428868131eb109e42340ad01eb8987526b2"),
- HashMap::from([(
- U256::from_str(
- "0xf1e9242398de526b8dd9c25d38e65fbb01926b8940377762d7884b8b0dcdc3b0",
- )
- .unwrap(),
- U256::from_str(
- "0x0000000000000000000000000000000000000000000000114be8ecea72b64003",
- )
- .unwrap(),
- )]),
- ),
- ];
+ let tx_hash = transaction.recalculate_hash();
+ if let Some(patch) = CHAPEL_PATCHES_BEFORE_TX.get(&tx_hash) {
+ trace!("patch evm state for chapel before tx {:?}", tx_hash);
- apply_patch(header, transaction, state, patches);
+ apply_patch(state, patch.address, &patch.storage);
+ }
}
-}
-fn apply_patch(
- header: &Header,
- transaction: &TransactionSigned,
- state: &mut State,
- patches: Vec<(B256, B256, Address, HashMap)>,
-) where
- DB: Database,
-{
- for (block_hash, tx_hash, address, patch) in patches {
- if header.hash_slow() == block_hash && transaction.recalculate_hash() == tx_hash {
- trace!("patch evm state at block {:?} tx {:?}", block_hash, tx_hash);
+ pub(crate) fn patch_mainnet_after_tx(
+ &self,
+ transaction: &TransactionSigned,
+ state: &mut State,
+ ) where
+ DB: Database + std::fmt::Display>,
+ {
+ let tx_hash = transaction.recalculate_hash();
+ if let Some(patch) = MAINNET_PATCHES_AFTER_TX.get(&tx_hash) {
+ trace!("patch evm state for mainnet after tx {:?}", tx_hash);
- let account = state.load_cache_account(address).unwrap().clone();
- let (info, mut storage) = account.into_components().0.unwrap();
- patch.into_iter().for_each(|(key, value)| {
- storage.insert(key, value);
- });
+ apply_patch(state, patch.address, &patch.storage);
+ }
+ }
- let mut account = CacheAccount::new_loaded(info, storage);
- account.status = Destroyed;
- state.cache.accounts.insert(address, account);
+ pub(crate) fn patch_chapel_after_tx(
+ &self,
+ transaction: &TransactionSigned,
+ state: &mut State,
+ ) where
+ DB: Database + std::fmt::Display>,
+ {
+ let tx_hash = transaction.recalculate_hash();
+ if let Some(patch) = CHAPEL_PATCHES_AFTER_TX.get(&tx_hash) {
+ trace!("patch evm state for chapel after tx {:?}", tx_hash);
+
+ apply_patch(state, patch.address, &patch.storage);
}
}
}
+
+fn apply_patch(state: &mut State, address: Address, storage: &HashMap)
+where
+ DB: Database + std::fmt::Display>,
+{
+ let account = state
+ .load_cache_account(address)
+ .map_err(|err| BscBlockExecutionError::ProviderInnerError { error: Box::new(err.into()) })
+ .unwrap();
+ let account_change = account.change(
+ account.account_info().unwrap_or_default(),
+ storage
+ .iter()
+ .map(|(key, value)| {
+ (
+ *key,
+ StorageSlot { previous_or_original_value: U256::ZERO, present_value: *value },
+ )
+ })
+ .collect(),
+ );
+
+ state.apply_transition(vec![(address, account_change)]);
+}
diff --git a/crates/bsc/evm/src/post_execution.rs b/crates/bsc/evm/src/post_execution.rs
index a7057a21d..a68b811c3 100644
--- a/crates/bsc/evm/src/post_execution.rs
+++ b/crates/bsc/evm/src/post_execution.rs
@@ -1,10 +1,11 @@
-use crate::{BscBlockExecutionError, BscBlockExecutor};
+use crate::{BscBlockExecutionError, BscBlockExecutor, SnapshotReader};
use bitset::BitSet;
use reth_bsc_consensus::{
get_top_validators_by_voting_power, is_breathe_block, ElectedValidators, ValidatorElectionInfo,
COLLECT_ADDITIONAL_VOTES_REWARD_RATIO, DIFF_INTURN, MAX_SYSTEM_REWARD, SYSTEM_REWARD_PERCENT,
};
use reth_errors::{BlockExecutionError, BlockValidationError, ProviderError};
+use reth_ethereum_forks::BscHardforks;
use reth_evm::ConfigureEvm;
use reth_primitives::{
hex,
@@ -13,10 +14,10 @@ use reth_primitives::{
Address, BlockWithSenders, GotExpected, Header, Receipt, TransactionSigned, U256,
};
use reth_provider::ParliaProvider;
-use reth_revm::{bsc::SYSTEM_ADDRESS, db::AccountStatus};
+use reth_revm::bsc::SYSTEM_ADDRESS;
use revm_primitives::{db::Database, EnvWithHandlerCfg};
use std::collections::HashMap;
-use tracing::log::debug;
+use tracing::debug;
/// Helper type for the input of post execution.
#[allow(clippy::type_complexity)]
@@ -30,7 +31,7 @@ pub(crate) struct PostExecutionInput {
impl BscBlockExecutor
where
EvmConfig: ConfigureEvm,
- DB: Database,
+ DB: Database + std::fmt::Display>,
P: ParliaProvider,
{
/// Apply post execution state changes, including system txs and other state change.
@@ -62,13 +63,12 @@ where
)?;
}
- if self.parlia().chain_spec().is_feynman_active_at_timestamp(block.timestamp) {
+ if self.chain_spec().is_feynman_active_at_timestamp(block.timestamp) {
// apply system contract upgrade
self.upgrade_system_contracts(block.number, block.timestamp, parent.timestamp)?;
}
- if self.parlia().chain_spec().is_on_feynman_at_timestamp(block.timestamp, parent.timestamp)
- {
+ if self.chain_spec().is_on_feynman_at_timestamp(block.timestamp, parent.timestamp) {
self.init_feynman_contracts(
validator,
system_txs,
@@ -81,7 +81,7 @@ where
// slash validator if it's not inturn
if block.difficulty != DIFF_INTURN {
let spoiled_val = snap.inturn_validator();
- let signed_recently = if self.parlia().chain_spec().is_plato_active_at_block(number) {
+ let signed_recently = if self.chain_spec().is_plato_active_at_block(number) {
snap.sign_recently(spoiled_val)
} else {
snap.recent_proposers.iter().any(|(_, v)| *v == spoiled_val)
@@ -101,7 +101,7 @@ where
self.distribute_incoming(header, system_txs, receipts, cumulative_gas_used, env.clone())?;
- if self.parlia().chain_spec().is_plato_active_at_block(number) {
+ if self.chain_spec().is_plato_active_at_block(number) {
self.distribute_finality_reward(
header,
system_txs,
@@ -112,7 +112,7 @@ where
}
// update validator set after Feynman upgrade
- if self.parlia().chain_spec().is_feynman_active_at_timestamp(header.timestamp) &&
+ if self.chain_spec().is_feynman_active_at_timestamp(header.timestamp) &&
is_breathe_block(parent.timestamp, header.timestamp) &&
!self
.parlia()
@@ -159,7 +159,7 @@ where
validators.sort();
let validator_num = validators.len();
- if self.parlia().chain_spec().is_on_luban_at_block(number) {
+ if self.chain_spec().is_on_luban_at_block(number) {
vote_addrs_map = validators
.iter()
.cloned()
@@ -171,7 +171,7 @@ where
.into_iter()
.flat_map(|v| {
let mut bytes = v.to_vec();
- if self.parlia().chain_spec().is_luban_active_at_block(number) {
+ if self.chain_spec().is_luban_active_at_block(number) {
bytes.extend_from_slice(vote_addrs_map[&v].as_ref());
}
bytes
@@ -265,24 +265,26 @@ where
) -> Result<(), BlockExecutionError> {
let validator = header.beneficiary;
- let system_account = self
- .state
- .load_cache_account(SYSTEM_ADDRESS)
- .map_err(|err| BscBlockExecutionError::ProviderInnerError { error: err.into() })?;
- if system_account.status == AccountStatus::LoadedNotExisting ||
- system_account.status == AccountStatus::DestroyedAgain
+ let system_account = self.state.load_cache_account(SYSTEM_ADDRESS).map_err(|err| {
+ BscBlockExecutionError::ProviderInnerError { error: Box::new(err.into()) }
+ })?;
+
+ if header.number != 1 &&
+ (system_account.account.is_none() ||
+ system_account.account.as_ref().unwrap().info.balance == U256::ZERO)
{
return Ok(());
}
let (mut block_reward, transition) = system_account.drain_balance();
self.state.apply_transition(vec![(SYSTEM_ADDRESS, transition)]);
+
+ // if block reward is zero, no need to distribute
if block_reward == 0 {
return Ok(());
}
- let mut balance_increment = HashMap::new();
- balance_increment.insert(validator, block_reward);
+ let balance_increment = HashMap::from([(validator, block_reward)]);
self.state
.increment_balances(balance_increment)
.map_err(|_| BlockValidationError::IncrementBalanceFailed)?;
@@ -290,10 +292,13 @@ where
let system_reward_balance = self
.state
.basic(SYSTEM_REWARD_CONTRACT.parse().unwrap())
+ .map_err(|err| BscBlockExecutionError::ProviderInnerError {
+ error: Box::new(err.into()),
+ })
.unwrap()
.unwrap_or_default()
.balance;
- if !self.parlia().chain_spec().is_kepler_active_at_timestamp(header.timestamp) &&
+ if !self.chain_spec().is_kepler_active_at_timestamp(header.timestamp) &&
system_reward_balance < U256::from(MAX_SYSTEM_REWARD)
{
let reward_to_system = block_reward >> SYSTEM_REWARD_PERCENT;
@@ -406,7 +411,8 @@ where
) -> Result<(), BlockExecutionError> {
let justified_header = self.get_header_by_hash(attestation.data.target_hash)?;
let parent = self.get_header_by_hash(justified_header.parent_hash)?;
- let snapshot = self.snapshot(&parent, None)?;
+ let snapshot_reader = SnapshotReader::new(self.provider.clone(), self.parlia.clone());
+ let snapshot = &(snapshot_reader.snapshot(&parent, None)?);
let validators = &snapshot.validators;
let validators_bit_set = BitSet::from_u64(attestation.vote_address_set);
diff --git a/crates/bsc/evm/src/pre_execution.rs b/crates/bsc/evm/src/pre_execution.rs
index 064114380..3f8931a04 100644
--- a/crates/bsc/evm/src/pre_execution.rs
+++ b/crates/bsc/evm/src/pre_execution.rs
@@ -1,4 +1,4 @@
-use crate::{BscBlockExecutionError, BscBlockExecutor};
+use crate::{BscBlockExecutionError, BscBlockExecutor, SnapshotReader};
use bitset::BitSet;
use blst::{
min_pk::{PublicKey, Signature},
@@ -6,6 +6,7 @@ use blst::{
};
use reth_bsc_consensus::{DIFF_INTURN, DIFF_NOTURN};
use reth_errors::{BlockExecutionError, ProviderError};
+use reth_ethereum_forks::{BscHardforks, EthereumHardforks};
use reth_evm::ConfigureEvm;
use reth_primitives::{
parlia::{Snapshot, VoteAddress, MAX_ATTESTATION_EXTRA_LENGTH},
@@ -19,7 +20,7 @@ const BLST_DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
impl BscBlockExecutor
where
EvmConfig: ConfigureEvm,
- DB: Database,
+ DB: Database + std::fmt::Display>,
P: ParliaProvider,
{
/// Apply settings and verify headers before a new block is executed.
@@ -55,7 +56,7 @@ where
header: &Header,
parent: &Header,
) -> Result<(), BlockExecutionError> {
- if self.parlia().chain_spec().is_ramanujan_active_at_block(header.number) &&
+ if self.chain_spec().is_ramanujan_active_at_block(header.number) &&
header.timestamp <
parent.timestamp +
self.parlia().period() +
@@ -77,6 +78,10 @@ where
header: &Header,
parent: &Header,
) -> Result<(), BlockExecutionError> {
+ if !self.chain_spec().is_plato_active_at_block(header.number) {
+ return Ok(());
+ }
+
let attestation =
self.parlia().get_vote_attestation_from_header(header).map_err(|err| {
BscBlockExecutionError::ParliaConsensusInnerError { error: err.into() }
@@ -116,7 +121,8 @@ where
// Get the target_number - 1 block's snapshot.
let pre_target_header = &(self.get_header_by_hash(parent.parent_hash)?);
- let snap = &(self.snapshot(pre_target_header, None)?);
+ let snapshot_reader = SnapshotReader::new(self.provider.clone(), self.parlia.clone());
+ let snap = &(snapshot_reader.snapshot(pre_target_header, None)?);
// query bls keys from snapshot.
let validators_count = snap.validators.len();
diff --git a/crates/chainspec/Cargo.toml b/crates/chainspec/Cargo.toml
index 1565567b5..ce8a79872 100644
--- a/crates/chainspec/Cargo.toml
+++ b/crates/chainspec/Cargo.toml
@@ -24,8 +24,13 @@ alloy-genesis.workspace = true
alloy-primitives = { workspace = true, features = ["rand", "rlp"] }
alloy-trie.workspace = true
+# op
+op-alloy-rpc-types = { workspace = true, optional = true }
+
+
# misc
once_cell.workspace = true
+serde = { workspace = true, optional = true }
serde_json.workspace = true
derive_more.workspace = true
@@ -39,13 +44,18 @@ alloy-genesis.workspace = true
reth-rpc-types.workspace = true
rand.workspace = true
+# op
+op-alloy-rpc-types.workspace = true
+
[features]
+default = ["std"]
bsc = [
"reth-ethereum-forks/bsc"
]
-default = ["std"]
optimism = [
- "reth-ethereum-forks/optimism"
+ "reth-ethereum-forks/optimism",
+ "serde",
+ "dep:op-alloy-rpc-types",
]
opbnb = [
"reth-ethereum-forks/opbnb"
diff --git a/crates/chainspec/src/constants/mod.rs b/crates/chainspec/src/constants/mod.rs
index 9af4f946b..cde927189 100644
--- a/crates/chainspec/src/constants/mod.rs
+++ b/crates/chainspec/src/constants/mod.rs
@@ -10,40 +10,3 @@ pub(crate) const MAINNET_DEPOSIT_CONTRACT: DepositContract = DepositContract::ne
#[cfg(feature = "optimism")]
pub(crate) mod optimism;
-
-#[cfg(test)]
-mod tests {
- use alloy_eips::calc_next_block_base_fee;
-
- #[test]
- fn calculate_base_fee_success() {
- let base_fee = [
- 1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
- 1, 2,
- ];
- let gas_used = [
- 10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
- 10000000,
- ];
- let gas_limit = [
- 10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
- 18000000, 18000000,
- ];
- let next_base_fee = [
- 1125000000, 1083333333, 1053571428, 1179939062, 1116028649, 918084097, 1063811730, 1,
- 2, 3,
- ];
-
- for i in 0..base_fee.len() {
- assert_eq!(
- next_base_fee[i],
- calc_next_block_base_fee(
- gas_used[i] as u128,
- gas_limit[i] as u128,
- base_fee[i] as u128,
- crate::BaseFeeParams::ethereum(),
- ) as u64
- );
- }
- }
-}
diff --git a/crates/chainspec/src/constants/optimism.rs b/crates/chainspec/src/constants/optimism.rs
index d4a1de6d0..1c32df6f3 100644
--- a/crates/chainspec/src/constants/optimism.rs
+++ b/crates/chainspec/src/constants/optimism.rs
@@ -44,105 +44,3 @@ pub(crate) const OP_CANYON_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
max_change_denominator: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
};
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use alloy_eips::calc_next_block_base_fee;
-
- #[test]
- fn calculate_optimism_base_fee_success() {
- let base_fee = [
- 1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
- 1, 2,
- ];
- let gas_used = [
- 10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
- 10000000,
- ];
- let gas_limit = [
- 10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
- 18000000, 18000000,
- ];
- let next_base_fee = [
- 1100000048, 1080000000, 1065714297, 1167067046, 1128881311, 1028254188, 1098203452, 1,
- 2, 3,
- ];
-
- for i in 0..base_fee.len() {
- assert_eq!(
- next_base_fee[i],
- calc_next_block_base_fee(
- gas_used[i] as u128,
- gas_limit[i] as u128,
- base_fee[i] as u128,
- OP_BASE_FEE_PARAMS,
- ) as u64
- );
- }
- }
-
- #[test]
- fn calculate_optimism_sepolia_base_fee_success() {
- let base_fee = [
- 1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
- 1, 2,
- ];
- let gas_used = [
- 10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
- 10000000,
- ];
- let gas_limit = [
- 10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
- 18000000, 18000000,
- ];
- let next_base_fee = [
- 1100000048, 1080000000, 1065714297, 1167067046, 1128881311, 1028254188, 1098203452, 1,
- 2, 3,
- ];
-
- for i in 0..base_fee.len() {
- assert_eq!(
- next_base_fee[i],
- calc_next_block_base_fee(
- gas_used[i] as u128,
- gas_limit[i] as u128,
- base_fee[i] as u128,
- OP_SEPOLIA_BASE_FEE_PARAMS,
- ) as u64
- );
- }
- }
-
- #[test]
- fn calculate_base_sepolia_base_fee_success() {
- let base_fee = [
- 1000000000, 1000000000, 1000000000, 1072671875, 1059263476, 1049238967, 1049238967, 0,
- 1, 2,
- ];
- let gas_used = [
- 10000000, 10000000, 10000000, 9000000, 10001000, 0, 10000000, 10000000, 10000000,
- 10000000,
- ];
- let gas_limit = [
- 10000000, 12000000, 14000000, 10000000, 14000000, 2000000, 18000000, 18000000,
- 18000000, 18000000,
- ];
- let next_base_fee = [
- 1180000000, 1146666666, 1122857142, 1244299375, 1189416692, 1028254188, 1144836295, 1,
- 2, 3,
- ];
-
- for i in 0..base_fee.len() {
- assert_eq!(
- next_base_fee[i],
- calc_next_block_base_fee(
- gas_used[i] as u128,
- gas_limit[i] as u128,
- base_fee[i] as u128,
- BASE_SEPOLIA_BASE_FEE_PARAMS,
- ) as u64
- );
- }
- }
-}
diff --git a/crates/chainspec/src/lib.rs b/crates/chainspec/src/lib.rs
index 6bd4bbe8b..f4f5020be 100644
--- a/crates/chainspec/src/lib.rs
+++ b/crates/chainspec/src/lib.rs
@@ -13,7 +13,7 @@ pub use alloy_chains::{Chain, ChainKind, NamedChain};
pub use info::ChainInfo;
pub use spec::{
BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, DepositContract,
- ForkBaseFeeParams, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
+ ForkBaseFeeParams, DEV, HOLESKY, MAINNET, SEPOLIA,
};
#[cfg(feature = "optimism")]
pub use spec::{BASE_MAINNET, BASE_SEPOLIA, OP_MAINNET, OP_SEPOLIA};
@@ -30,9 +30,6 @@ extern crate alloc;
/// The chain info module.
mod info;
-/// Network related constants
-pub mod net;
-
/// The chain spec module.
mod spec;
@@ -57,8 +54,8 @@ mod tests {
#[test]
fn test_named_id() {
- let chain = Chain::from_named(NamedChain::Goerli);
- assert_eq!(chain.id(), 5);
+ let chain = Chain::from_named(NamedChain::Holesky);
+ assert_eq!(chain.id(), 17000);
}
#[test]
@@ -84,9 +81,9 @@ mod tests {
#[test]
fn test_into_u256() {
- let chain = Chain::from_named(NamedChain::Goerli);
+ let chain = Chain::from_named(NamedChain::Holesky);
let n: U256 = U256::from(chain.id());
- let expected = U256::from(5);
+ let expected = U256::from(17000);
assert_eq!(n, expected);
}
diff --git a/crates/chainspec/src/net.rs b/crates/chainspec/src/net.rs
deleted file mode 100644
index 7bbfa4412..000000000
--- a/crates/chainspec/src/net.rs
+++ /dev/null
@@ -1,308 +0,0 @@
-pub use reth_network_peers::{NodeRecord, NodeRecordParseError, TrustedPeer};
-
-#[cfg(not(feature = "std"))]
-use alloc::vec::Vec;
-
-// Ethereum bootnodes come from
-// OP bootnodes come from
-
-/// Ethereum Foundation Go Bootnodes
-pub static MAINNET_BOOTNODES: [&str; 4] = [
- "enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", // bootnode-aws-ap-southeast-1-001
- "enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", // bootnode-aws-us-east-1-001
- "enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303", // bootnode-hetzner-hel
- "enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn
-];
-
-/// Ethereum Foundation Sepolia Bootnodes
-pub static SEPOLIA_BOOTNODES: [&str; 5] = [
- "enode://4e5e92199ee224a01932a377160aa432f31d0b351f84ab413a8e0a42f4f36476f8fb1cbe914af0d9aef0d51665c214cf653c651c4bbd9d5550a934f241f1682b@138.197.51.181:30303", // sepolia-bootnode-1-nyc3
- "enode://143e11fb766781d22d92a2e33f8f104cddae4411a122295ed1fdb6638de96a6ce65f5b7c964ba3763bba27961738fef7d3ecc739268f3e5e771fb4c87b6234ba@146.190.1.103:30303", // sepolia-bootnode-1-sfo3
- "enode://8b61dc2d06c3f96fddcbebb0efb29d60d3598650275dc469c22229d3e5620369b0d3dedafd929835fe7f489618f19f456fe7c0df572bf2d914a9f4e006f783a9@170.64.250.88:30303", // sepolia-bootnode-1-syd1
- "enode://10d62eff032205fcef19497f35ca8477bea0eadfff6d769a147e895d8b2b8f8ae6341630c645c30f5df6e67547c03494ced3d9c5764e8622a26587b083b028e8@139.59.49.206:30303", // sepolia-bootnode-1-blr1
- "enode://9e9492e2e8836114cc75f5b929784f4f46c324ad01daf87d956f98b3b6c5fcba95524d6e5cf9861dc96a2c8a171ea7105bb554a197455058de185fa870970c7c@138.68.123.152:30303", // sepolia-bootnode-1-ams3
-];
-
-/// Görli Bootnodes
-pub static GOERLI_BOOTNODES: [&str; 7] = [
- // Upstream bootnodes
- "enode://011f758e6552d105183b1761c5e2dea0111bc20fd5f6422bc7f91e0fabbec9a6595caf6239b37feb773dddd3f87240d99d859431891e4a642cf2a0a9e6cbb98a@51.141.78.53:30303",
- "enode://176b9417f511d05b6b2cf3e34b756cf0a7096b3094572a8f6ef4cdcb9d1f9d00683bf0f83347eebdf3b81c3521c2332086d9592802230bf528eaf606a1d9677b@13.93.54.137:30303",
- "enode://46add44b9f13965f7b9875ac6b85f016f341012d84f975377573800a863526f4da19ae2c620ec73d11591fa9510e992ecc03ad0751f53cc02f7c7ed6d55c7291@94.237.54.114:30313",
- "enode://b5948a2d3e9d486c4d75bf32713221c2bd6cf86463302339299bd227dc2e276cd5a1c7ca4f43a0e9122fe9af884efed563bd2a1fd28661f3b5f5ad7bf1de5949@18.218.250.66:30303",
-
- // Ethereum Foundation bootnode
- "enode://a61215641fb8714a373c80edbfa0ea8878243193f57c96eeb44d0bc019ef295abd4e044fd619bfc4c59731a73fb79afe84e9ab6da0c743ceb479cbb6d263fa91@3.11.147.67:30303",
-
- // Goerli Initiative bootnodes
- "enode://d4f764a48ec2a8ecf883735776fdefe0a3949eb0ca476bd7bc8d0954a9defe8fea15ae5da7d40b5d2d59ce9524a99daedadf6da6283fca492cc80b53689fb3b3@46.4.99.122:32109",
- "enode://d2b720352e8216c9efc470091aa91ddafc53e222b32780f505c817ceef69e01d5b0b0797b69db254c586f493872352f5a022b4d8479a00fc92ec55f9ad46a27e@88.99.70.182:30303",
-];
-
-/// Ethereum Foundation Holesky Bootnodes
-pub static HOLESKY_BOOTNODES: [&str; 2] = [
- "enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303",
- "enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303",
-];
-
-#[cfg(feature = "optimism")]
-/// OP stack mainnet boot nodes.
-pub static OP_BOOTNODES: &[&str] = &[
- // OP Labs
- "enode://ca2774c3c401325850b2477fd7d0f27911efbf79b1e8b335066516e2bd8c4c9e0ba9696a94b1cb030a88eac582305ff55e905e64fb77fe0edcd70a4e5296d3ec@34.65.175.185:30305",
- "enode://dd751a9ef8912be1bfa7a5e34e2c3785cc5253110bd929f385e07ba7ac19929fb0e0c5d93f77827291f4da02b2232240fbc47ea7ce04c46e333e452f8656b667@34.65.107.0:30305",
- "enode://c5d289b56a77b6a2342ca29956dfd07aadf45364dde8ab20d1dc4efd4d1bc6b4655d902501daea308f4d8950737a4e93a4dfedd17b49cd5760ffd127837ca965@34.65.202.239:30305",
- // Base
- "enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301",
- "enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301",
- "enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301",
- "enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301",
- "enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301"
-];
-
-#[cfg(feature = "optimism")]
-/// OP stack testnet boot nodes.
-pub static OP_TESTNET_BOOTNODES: &[&str] = &[
- // OP Labs
- "enode://2bd2e657bb3c8efffb8ff6db9071d9eb7be70d7c6d7d980ff80fc93b2629675c5f750bc0a5ef27cd788c2e491b8795a7e9a4a6e72178c14acc6753c0e5d77ae4@34.65.205.244:30305",
- "enode://db8e1cab24624cc62fc35dbb9e481b88a9ef0116114cd6e41034c55b5b4f18755983819252333509bd8e25f6b12aadd6465710cd2e956558faf17672cce7551f@34.65.173.88:30305",
- "enode://bfda2e0110cfd0f4c9f7aa5bf5ec66e6bd18f71a2db028d36b8bf8b0d6fdb03125c1606a6017b31311d96a36f5ef7e1ad11604d7a166745e6075a715dfa67f8a@34.65.229.245:30305",
- // Base
- "enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301",
- "enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301",
-];
-
-#[cfg(feature = "bsc")]
-/// Bsc testnet boot nodes.
-pub static BSC_MAINNET_BOOTNODES: &[&str] = &[
- "enode://433c8bfdf53a3e2268ccb1b829e47f629793291cbddf0c76ae626da802f90532251fc558e2e0d10d6725e759088439bf1cd4714716b03a259a35d4b2e4acfa7f@52.69.102.73:30311",
- "enode://571bee8fb902a625942f10a770ccf727ae2ba1bab2a2b64e121594a99c9437317f6166a395670a00b7d93647eacafe598b6bbcef15b40b6d1a10243865a3e80f@35.73.84.120:30311",
- "enode://fac42fb0ba082b7d1eebded216db42161163d42e4f52c9e47716946d64468a62da4ba0b1cac0df5e8bf1e5284861d757339751c33d51dfef318be5168803d0b5@18.203.152.54:30311",
- "enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@34.250.32.100:30311",
- "enode://ad78c64a4ade83692488aa42e4c94084516e555d3f340d9802c2bf106a3df8868bc46eae083d2de4018f40e8d9a9952c32a0943cd68855a9bc9fd07aac982a6d@34.204.214.24:30311",
- "enode://5db798deb67df75d073f8e2953dad283148133acb520625ea804c9c4ad09a35f13592a762d8f89056248f3889f6dcc33490c145774ea4ff2966982294909b37a@107.20.191.97:30311",
-];
-
-#[cfg(feature = "bsc")]
-/// Bsc testnet boot nodes.
-pub static BSC_TESTNET_BOOTNODES: &[&str] = &[
- "enode://0637d1e62026e0c8685b1db0ca1c767c78c95c3fab64abc468d1a64b12ca4b530b46b8f80c915aec96f74f7ffc5999e8ad6d1484476f420f0c10e3d42361914b@52.199.214.252:30311",
- "enode://df1e8eb59e42cad3c4551b2a53e31a7e55a2fdde1287babd1e94b0836550b489ba16c40932e4dacb16cba346bd442c432265a299c4aca63ee7bb0f832b9f45eb@52.51.80.128:30311",
- "enode://ecd664250ca19b1074dcfbfb48576a487cc18d052064222a363adacd2650f8e08fb3db9de7a7aecb48afa410eaeb3285e92e516ead01fb62598553aed91ee15e@3.209.122.123:30311",
- "enode://665cf77ca26a8421cfe61a52ac312958308d4912e78ce8e0f61d6902e4494d4cc38f9b0dd1b23a427a7a5734e27e5d9729231426b06bb9c73b56a142f83f6b68@52.72.123.113:30311",
-];
-
-#[cfg(all(feature = "optimism", feature = "opbnb"))]
-/// OPBNB mainnet boot nodes.
-pub static OPBNB_MAINNET_BOOTNODES: &[&str] = &[
- "enode://db109c6cac5c8b6225edd3176fc3764c58e0720950fe94c122c80978e706a9c9e976629b718e48b6306ea0f9126e5394d3424c9716c5703549e2e7eba216353b@52.193.218.151:30304",
- "enode://afe18782053bb31fb7ea41e1acf659ab9bd1eec181fb97331f0a6b61871a469b4f75138f903c977796be1cc2a3c985d33150a396e878d3cd6e4723b6040ff9c0@52.195.105.192:30304",
-];
-
-#[cfg(all(feature = "optimism", feature = "opbnb"))]
-/// OPBNB testnet boot nodes.
-pub static OPBNB_TESTNET_BOOTNODES: &[&str] = &[
- "enode://217cfe091047a1c3f490e96d51e2f3bd90517a9be77b8a6033b31833a193aa6c33b6d07088c4980f462162635ffbccaa413dc28cb14c4f2b96af0dd97292411f@13.112.117.88:30304",
- "enode://38c8913f87d64179bac23514ddb56a17f5b28f7e253b3825a10a2c8b9553c5df7d3b6c83a96948ad0466f384bf63236fd5e6bed6d6402156749b6b0899c82d47@54.199.235.83:30304",
-];
-
-/// Returns parsed mainnet nodes
-pub fn mainnet_nodes() -> Vec {
- parse_nodes(&MAINNET_BOOTNODES[..])
-}
-
-/// Returns parsed goerli nodes
-pub fn goerli_nodes() -> Vec {
- parse_nodes(&GOERLI_BOOTNODES[..])
-}
-
-/// Returns parsed sepolia nodes
-pub fn sepolia_nodes() -> Vec {
- parse_nodes(&SEPOLIA_BOOTNODES[..])
-}
-
-/// Returns parsed holesky nodes
-pub fn holesky_nodes() -> Vec {
- parse_nodes(&HOLESKY_BOOTNODES[..])
-}
-
-#[cfg(feature = "optimism")]
-/// Returns parsed op-stack mainnet nodes
-pub fn op_nodes() -> Vec {
- parse_nodes(OP_BOOTNODES)
-}
-
-#[cfg(feature = "optimism")]
-/// Returns parsed op-stack testnet nodes
-pub fn op_testnet_nodes() -> Vec {
- parse_nodes(OP_TESTNET_BOOTNODES)
-}
-
-#[cfg(all(feature = "optimism", feature = "opbnb"))]
-/// Returns parsed opbnb testnet nodes
-pub fn opbnb_testnet_nodes() -> Vec {
- parse_nodes(OPBNB_TESTNET_BOOTNODES)
-}
-
-#[cfg(all(feature = "optimism", feature = "opbnb"))]
-/// Returns parsed opbnb mainnet nodes
-pub fn opbnb_mainnet_nodes() -> Vec {
- parse_nodes(OPBNB_MAINNET_BOOTNODES)
-}
-
-#[cfg(feature = "optimism")]
-/// Returns parsed op-stack base mainnet nodes
-pub fn base_nodes() -> Vec {
- parse_nodes(OP_BOOTNODES)
-}
-
-#[cfg(feature = "optimism")]
-/// Returns parsed op-stack base testnet nodes
-pub fn base_testnet_nodes() -> Vec {
- parse_nodes(OP_TESTNET_BOOTNODES)
-}
-
-#[cfg(feature = "bsc")]
-/// Returns parsed bsc mainnet nodes
-pub fn bsc_mainnet_nodes() -> Vec {
- parse_nodes(BSC_MAINNET_BOOTNODES)
-}
-
-#[cfg(feature = "bsc")]
-/// Returns parsed bsc mainnet nodes
-pub fn bsc_testnet_nodes() -> Vec {
- parse_nodes(BSC_TESTNET_BOOTNODES)
-}
-
-/// Parses all the nodes
-pub fn parse_nodes(nodes: impl IntoIterator- >) -> Vec {
- nodes.into_iter().map(|s| s.as_ref().parse().unwrap()).collect()
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use alloy_rlp::Decodable;
- use rand::{thread_rng, Rng, RngCore};
- use std::net::{IpAddr, Ipv4Addr};
-
- #[test]
- fn test_mapped_ipv6() {
- let mut rng = thread_rng();
-
- let v4: Ipv4Addr = "0.0.0.0".parse().unwrap();
- let v6 = v4.to_ipv6_mapped();
-
- let record = NodeRecord {
- address: v6.into(),
- tcp_port: rng.gen(),
- udp_port: rng.gen(),
- id: rng.gen(),
- };
-
- assert!(record.clone().convert_ipv4_mapped());
- assert_eq!(record.into_ipv4_mapped().address, IpAddr::from(v4));
- }
-
- #[test]
- fn test_mapped_ipv4() {
- let mut rng = thread_rng();
- let v4: Ipv4Addr = "0.0.0.0".parse().unwrap();
-
- let record = NodeRecord {
- address: v4.into(),
- tcp_port: rng.gen(),
- udp_port: rng.gen(),
- id: rng.gen(),
- };
-
- assert!(!record.clone().convert_ipv4_mapped());
- assert_eq!(record.into_ipv4_mapped().address, IpAddr::from(v4));
- }
-
- #[test]
- fn test_noderecord_codec_ipv4() {
- let mut rng = thread_rng();
- for _ in 0..100 {
- let mut ip = [0u8; 4];
- rng.fill_bytes(&mut ip);
- let record = NodeRecord {
- address: IpAddr::V4(ip.into()),
- tcp_port: rng.gen(),
- udp_port: rng.gen(),
- id: rng.gen(),
- };
-
- let decoded = NodeRecord::decode(&mut alloy_rlp::encode(record).as_slice()).unwrap();
- assert_eq!(record, decoded);
- }
- }
-
- #[test]
- fn test_noderecord_codec_ipv6() {
- let mut rng = thread_rng();
- for _ in 0..100 {
- let mut ip = [0u8; 16];
- rng.fill_bytes(&mut ip);
- let record = NodeRecord {
- address: IpAddr::V6(ip.into()),
- tcp_port: rng.gen(),
- udp_port: rng.gen(),
- id: rng.gen(),
- };
-
- let decoded = NodeRecord::decode(&mut alloy_rlp::encode(record).as_slice()).unwrap();
- assert_eq!(record, decoded);
- }
- }
-
- #[test]
- fn test_url_parse() {
- let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301";
- let node: NodeRecord = url.parse().unwrap();
- assert_eq!(node, NodeRecord {
- address: IpAddr::V4([10, 3, 58, 6].into()),
- tcp_port: 30303,
- udp_port: 30301,
- id: "6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0".parse().unwrap(),
- })
- }
-
- #[test]
- fn test_node_display() {
- let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303";
- let node: NodeRecord = url.parse().unwrap();
- assert_eq!(url, &format!("{node}"));
- }
-
- #[test]
- fn test_node_display_discport() {
- let url = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301";
- let node: NodeRecord = url.parse().unwrap();
- assert_eq!(url, &format!("{node}"));
- }
-
- #[test]
- fn test_node_serialize() {
- let node = NodeRecord {
- address: IpAddr::V4([10, 3, 58, 6].into()),
- tcp_port: 30303u16,
- udp_port: 30301u16,
- id: "6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0".parse().unwrap(),
- };
- let ser = serde_json::to_string::(&node).expect("couldn't serialize");
- assert_eq!(ser, "\"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301\"")
- }
-
- #[test]
- fn test_node_deserialize() {
- let url = "\"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301\"";
- let node: NodeRecord = serde_json::from_str(url).expect("couldn't deserialize");
- assert_eq!(node, NodeRecord {
- address: IpAddr::V4([10, 3, 58, 6].into()),
- tcp_port: 30303u16,
- udp_port: 30301u16,
- id: "6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0".parse().unwrap(),
- })
- }
-}
diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs
index b03df5295..f010c540c 100644
--- a/crates/chainspec/src/spec.rs
+++ b/crates/chainspec/src/spec.rs
@@ -1,12 +1,6 @@
use crate::constants::MAINNET_DEPOSIT_CONTRACT;
#[cfg(not(feature = "std"))]
-use alloc::{
- collections::BTreeMap,
- format,
- string::{String, ToString},
- sync::Arc,
- vec::Vec,
-};
+use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloy_chains::{Chain, ChainKind, NamedChain};
use alloy_genesis::Genesis;
use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256};
@@ -14,20 +8,20 @@ use alloy_trie::EMPTY_ROOT_HASH;
use derive_more::From;
use once_cell::sync::Lazy;
use reth_ethereum_forks::{
- chains::ethereum::{GOERLI_HARDFORKS, HOLESKY_HARDFORKS, MAINNET_HARDFORKS, SEPOLIA_HARDFORKS},
- DisplayHardforks, ForkCondition, ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Head,
+ ChainHardforks, DisplayHardforks, EthereumHardfork, EthereumHardforks, ForkCondition,
+ ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Head, DEV_HARDFORKS,
};
use reth_network_peers::NodeRecord;
use reth_primitives_traits::{
constants::{
- EIP1559_INITIAL_BASE_FEE, EMPTY_OMMER_ROOT_HASH, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS,
- EMPTY_WITHDRAWALS,
+ DEV_GENESIS_HASH, EIP1559_INITIAL_BASE_FEE, EMPTY_WITHDRAWALS, HOLESKY_GENESIS_HASH,
+ MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH,
},
Header, SealedHeader,
};
use reth_trie_common::root::state_root_ref_unhashed;
#[cfg(feature = "std")]
-use std::{collections::BTreeMap, sync::Arc};
+use std::sync::Arc;
#[cfg(feature = "optimism")]
use crate::constants::optimism::{
@@ -35,15 +29,18 @@ use crate::constants::optimism::{
OP_CANYON_BASE_FEE_PARAMS, OP_SEPOLIA_BASE_FEE_PARAMS, OP_SEPOLIA_CANYON_BASE_FEE_PARAMS,
};
pub use alloy_eips::eip1559::BaseFeeParams;
+#[cfg(feature = "bsc")]
+use reth_ethereum_forks::BscHardfork;
#[cfg(feature = "optimism")]
-use reth_ethereum_forks::chains::optimism::*;
-
-#[cfg(feature = "optimism")]
-use crate::net::{base_nodes, base_testnet_nodes, op_nodes, op_testnet_nodes};
-use crate::net::{goerli_nodes, holesky_nodes, mainnet_nodes, sepolia_nodes};
-
+use reth_ethereum_forks::OptimismHardfork;
+use reth_network_peers::{
+ base_nodes, base_testnet_nodes, holesky_nodes, mainnet_nodes, op_nodes, op_testnet_nodes,
+ sepolia_nodes,
+};
#[cfg(feature = "bsc")]
-pub(crate) use crate::net::{bsc_mainnet_nodes, bsc_testnet_nodes};
+use reth_network_peers::{bsc_mainnet_nodes, bsc_testnet_nodes};
+#[cfg(feature = "optimism")]
+use reth_network_peers::{opbnb_mainnet_nodes, opbnb_testnet_nodes};
/// The BSC mainnet spec
#[cfg(feature = "bsc")]
@@ -56,38 +53,7 @@ pub static BSC_MAINNET: Lazy> = Lazy::new(|| {
"0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b"
)),
paris_block_and_final_difficulty: Some((0, U256::from(0))),
- hardforks: BTreeMap::from([
- (Hardfork::Frontier, ForkCondition::Block(0)),
- (Hardfork::Homestead, ForkCondition::Block(0)),
- (Hardfork::Tangerine, ForkCondition::Block(0)),
- (Hardfork::SpuriousDragon, ForkCondition::Block(0)),
- (Hardfork::Byzantium, ForkCondition::Block(0)),
- (Hardfork::Constantinople, ForkCondition::Block(0)),
- (Hardfork::Petersburg, ForkCondition::Block(0)),
- (Hardfork::Istanbul, ForkCondition::Block(0)),
- (Hardfork::MuirGlacier, ForkCondition::Block(0)),
- (Hardfork::Ramanujan, ForkCondition::Block(0)),
- (Hardfork::Niels, ForkCondition::Block(0)),
- (Hardfork::MirrorSync, ForkCondition::Block(5184000)),
- (Hardfork::Bruno, ForkCondition::Block(13082000)),
- (Hardfork::Euler, ForkCondition::Block(18907621)),
- (Hardfork::Nano, ForkCondition::Block(21962149)),
- (Hardfork::Moran, ForkCondition::Block(22107423)),
- (Hardfork::Gibbs, ForkCondition::Block(23846001)),
- (Hardfork::Planck, ForkCondition::Block(27281024)),
- (Hardfork::Luban, ForkCondition::Block(29020050)),
- (Hardfork::Plato, ForkCondition::Block(30720096)),
- (Hardfork::Berlin, ForkCondition::Block(31302048)),
- (Hardfork::London, ForkCondition::Block(31302048)),
- (Hardfork::Hertz, ForkCondition::Block(31302048)),
- (Hardfork::HertzFix, ForkCondition::Block(34140700)),
- (Hardfork::Shanghai, ForkCondition::Timestamp(1705996800)),
- (Hardfork::Kepler, ForkCondition::Timestamp(1705996800)),
- (Hardfork::Feynman, ForkCondition::Timestamp(1713419340)),
- (Hardfork::FeynmanFix, ForkCondition::Timestamp(1713419340)),
- (Hardfork::Cancun, ForkCondition::Timestamp(1718863500)),
- (Hardfork::Haber, ForkCondition::Timestamp(1718863500)),
- ]),
+ hardforks: BscHardfork::bsc_mainnet(),
deposit_contract: None,
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::new(1, 1)),
prune_delete_limit: 3500,
@@ -106,39 +72,7 @@ pub static BSC_TESTNET: Lazy> = Lazy::new(|| {
"6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"
)),
paris_block_and_final_difficulty: Some((0, U256::from(0))),
- hardforks: BTreeMap::from([
- (Hardfork::Frontier, ForkCondition::Block(0)),
- (Hardfork::Homestead, ForkCondition::Block(0)),
- (Hardfork::Tangerine, ForkCondition::Block(0)),
- (Hardfork::SpuriousDragon, ForkCondition::Block(0)),
- (Hardfork::Byzantium, ForkCondition::Block(0)),
- (Hardfork::Constantinople, ForkCondition::Block(0)),
- (Hardfork::Petersburg, ForkCondition::Block(0)),
- (Hardfork::Istanbul, ForkCondition::Block(0)),
- (Hardfork::MuirGlacier, ForkCondition::Block(0)),
- (Hardfork::Ramanujan, ForkCondition::Block(1010000)),
- (Hardfork::Niels, ForkCondition::Block(1014369)),
- (Hardfork::MirrorSync, ForkCondition::Block(5582500)),
- (Hardfork::Bruno, ForkCondition::Block(13837000)),
- (Hardfork::Euler, ForkCondition::Block(19203503)),
- (Hardfork::Gibbs, ForkCondition::Block(22800220)),
- (Hardfork::Nano, ForkCondition::Block(23482428)),
- (Hardfork::Moran, ForkCondition::Block(23603940)),
- (Hardfork::Planck, ForkCondition::Block(28196022)),
- (Hardfork::Luban, ForkCondition::Block(29295050)),
- (Hardfork::Plato, ForkCondition::Block(29861024)),
- (Hardfork::Berlin, ForkCondition::Block(31103030)),
- (Hardfork::London, ForkCondition::Block(31103030)),
- (Hardfork::Hertz, ForkCondition::Block(31103030)),
- (Hardfork::HertzFix, ForkCondition::Block(35682300)),
- (Hardfork::Shanghai, ForkCondition::Timestamp(1702972800)),
- (Hardfork::Kepler, ForkCondition::Timestamp(1702972800)),
- (Hardfork::Feynman, ForkCondition::Timestamp(1710136800)),
- (Hardfork::FeynmanFix, ForkCondition::Timestamp(1711342800)),
- (Hardfork::Cancun, ForkCondition::Timestamp(1713330442)),
- (Hardfork::Haber, ForkCondition::Timestamp(1716962820)),
- (Hardfork::HaberFix, ForkCondition::Timestamp(1719986788)),
- ]),
+ hardforks: BscHardfork::bsc_testnet(),
deposit_contract: None,
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::new(1, 1)),
prune_delete_limit: 3500,
@@ -146,24 +80,19 @@ pub static BSC_TESTNET: Lazy> = Lazy::new(|| {
.into()
});
-#[cfg(all(feature = "optimism", feature = "opbnb"))]
-pub(crate) use crate::net::{opbnb_mainnet_nodes, opbnb_testnet_nodes};
-
/// The Ethereum mainnet spec
pub static MAINNET: Lazy> = Lazy::new(|| {
ChainSpec {
chain: Chain::mainnet(),
genesis: serde_json::from_str(include_str!("../res/genesis/mainnet.json"))
.expect("Can't deserialize Mainnet genesis json"),
- genesis_hash: Some(b256!(
- "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
- )),
+ genesis_hash: Some(MAINNET_GENESIS_HASH),
//