mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: unify all chains confs (#747)
Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4368,6 +4368,7 @@ dependencies = [
|
|||||||
"hex-literal",
|
"hex-literal",
|
||||||
"impl-serde",
|
"impl-serde",
|
||||||
"modular-bitfield",
|
"modular-bitfield",
|
||||||
|
"once_cell",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"plain_hasher",
|
"plain_hasher",
|
||||||
"proptest",
|
"proptest",
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use reth_network::{
|
|||||||
config::{mainnet_nodes, rng_secret_key},
|
config::{mainnet_nodes, rng_secret_key},
|
||||||
NetworkConfig, PeersConfig,
|
NetworkConfig, PeersConfig,
|
||||||
};
|
};
|
||||||
use reth_primitives::{NodeRecord, H256};
|
use reth_primitives::{ChainSpec, NodeRecord};
|
||||||
use reth_provider::ProviderImpl;
|
use reth_provider::ProviderImpl;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -26,8 +26,7 @@ impl Config {
|
|||||||
pub fn network_config<DB: Database>(
|
pub fn network_config<DB: Database>(
|
||||||
&self,
|
&self,
|
||||||
db: Arc<DB>,
|
db: Arc<DB>,
|
||||||
chain_id: u64,
|
chain_spec: ChainSpec,
|
||||||
genesis_hash: H256,
|
|
||||||
disable_discovery: bool,
|
disable_discovery: bool,
|
||||||
bootnodes: Option<Vec<NodeRecord>>,
|
bootnodes: Option<Vec<NodeRecord>>,
|
||||||
) -> NetworkConfig<ProviderImpl<DB>> {
|
) -> NetworkConfig<ProviderImpl<DB>> {
|
||||||
@ -37,8 +36,7 @@ impl Config {
|
|||||||
NetworkConfig::builder(Arc::new(ProviderImpl::new(db)), rng_secret_key())
|
NetworkConfig::builder(Arc::new(ProviderImpl::new(db)), rng_secret_key())
|
||||||
.boot_nodes(bootnodes.unwrap_or_else(mainnet_nodes))
|
.boot_nodes(bootnodes.unwrap_or_else(mainnet_nodes))
|
||||||
.peer_config(peer_config)
|
.peer_config(peer_config)
|
||||||
.genesis_hash(genesis_hash)
|
.chain_spec(chain_spec)
|
||||||
.chain_id(chain_id)
|
|
||||||
.set_discovery(disable_discovery)
|
.set_discovery(disable_discovery)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,11 +5,7 @@ use crate::{
|
|||||||
config::Config,
|
config::Config,
|
||||||
dirs::{ConfigPath, DbPath, PlatformPath},
|
dirs::{ConfigPath, DbPath, PlatformPath},
|
||||||
prometheus_exporter,
|
prometheus_exporter,
|
||||||
utils::{
|
utils::{chainspec::chain_spec_value_parser, init::init_db, parse_socket_address},
|
||||||
chainspec::{chain_spec_value_parser, ChainSpecification},
|
|
||||||
init::{init_db, init_genesis},
|
|
||||||
parse_socket_address,
|
|
||||||
},
|
|
||||||
NetworkOpts,
|
NetworkOpts,
|
||||||
};
|
};
|
||||||
use clap::{crate_version, Parser};
|
use clap::{crate_version, Parser};
|
||||||
@ -18,11 +14,10 @@ use fdlimit::raise_fd_limit;
|
|||||||
use futures::{stream::select as stream_select, Stream, StreamExt};
|
use futures::{stream::select as stream_select, Stream, StreamExt};
|
||||||
use reth_consensus::BeaconConsensus;
|
use reth_consensus::BeaconConsensus;
|
||||||
use reth_downloaders::{bodies, headers};
|
use reth_downloaders::{bodies, headers};
|
||||||
use reth_executor::Config as ExecutorConfig;
|
|
||||||
use reth_interfaces::consensus::ForkchoiceState;
|
use reth_interfaces::consensus::ForkchoiceState;
|
||||||
use reth_network::NetworkEvent;
|
use reth_network::NetworkEvent;
|
||||||
use reth_network_api::NetworkInfo;
|
use reth_network_api::NetworkInfo;
|
||||||
use reth_primitives::{BlockNumber, NodeRecord, H256};
|
use reth_primitives::{BlockNumber, ChainSpec, NodeRecord, H256};
|
||||||
use reth_stages::{
|
use reth_stages::{
|
||||||
metrics::HeaderMetrics,
|
metrics::HeaderMetrics,
|
||||||
stages::{
|
stages::{
|
||||||
@ -68,7 +63,7 @@ pub struct Command {
|
|||||||
default_value = "mainnet",
|
default_value = "mainnet",
|
||||||
value_parser = chain_spec_value_parser
|
value_parser = chain_spec_value_parser
|
||||||
)]
|
)]
|
||||||
chain: ChainSpecification,
|
chain: ChainSpec,
|
||||||
|
|
||||||
/// Enable Prometheus metrics.
|
/// Enable Prometheus metrics.
|
||||||
///
|
///
|
||||||
@ -119,15 +114,12 @@ impl Command {
|
|||||||
HeaderMetrics::describe();
|
HeaderMetrics::describe();
|
||||||
}
|
}
|
||||||
|
|
||||||
let chain_id = self.chain.consensus.chain_id;
|
let consensus: Arc<BeaconConsensus> = Arc::new(BeaconConsensus::new(self.chain.clone()));
|
||||||
let consensus = Arc::new(BeaconConsensus::new(self.chain.consensus.clone()));
|
|
||||||
let genesis_hash = init_genesis(db.clone(), self.chain.genesis.clone())?;
|
|
||||||
|
|
||||||
let network = config
|
let network = config
|
||||||
.network_config(
|
.network_config(
|
||||||
db.clone(),
|
db.clone(),
|
||||||
chain_id,
|
self.chain.clone(),
|
||||||
genesis_hash,
|
|
||||||
self.network.disable_discovery,
|
self.network.disable_discovery,
|
||||||
self.bootnodes.clone(),
|
self.bootnodes.clone(),
|
||||||
)
|
)
|
||||||
@ -178,7 +170,7 @@ impl Command {
|
|||||||
commit_threshold: config.stages.sender_recovery.commit_threshold,
|
commit_threshold: config.stages.sender_recovery.commit_threshold,
|
||||||
})
|
})
|
||||||
.push(ExecutionStage {
|
.push(ExecutionStage {
|
||||||
config: ExecutorConfig::new_ethereum(),
|
chain_spec: self.chain.clone(),
|
||||||
commit_threshold: config.stages.execution.commit_threshold,
|
commit_threshold: config.stages.execution.commit_threshold,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
dirs::{ConfigPath, PlatformPath},
|
dirs::{ConfigPath, PlatformPath},
|
||||||
utils::{
|
utils::{chainspec::chain_spec_value_parser, hash_or_num_value_parser},
|
||||||
chainspec::{chain_spec_value_parser, ChainSpecification},
|
|
||||||
hash_or_num_value_parser,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use backon::{ConstantBackoff, Retryable};
|
use backon::{ConstantBackoff, Retryable};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
@ -15,7 +12,7 @@ use reth_interfaces::p2p::{
|
|||||||
headers::client::{HeadersClient, HeadersRequest},
|
headers::client::{HeadersClient, HeadersRequest},
|
||||||
};
|
};
|
||||||
use reth_network::FetchClient;
|
use reth_network::FetchClient;
|
||||||
use reth_primitives::{BlockHashOrNumber, Header, NodeRecord, SealedHeader};
|
use reth_primitives::{BlockHashOrNumber, ChainSpec, NodeRecord, SealedHeader};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// `reth p2p` command
|
/// `reth p2p` command
|
||||||
@ -40,7 +37,7 @@ pub struct Command {
|
|||||||
default_value = "mainnet",
|
default_value = "mainnet",
|
||||||
value_parser = chain_spec_value_parser
|
value_parser = chain_spec_value_parser
|
||||||
)]
|
)]
|
||||||
chain: ChainSpecification,
|
chain: ChainSpec,
|
||||||
|
|
||||||
/// Disable the discovery service.
|
/// Disable the discovery service.
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
@ -86,10 +83,6 @@ impl Command {
|
|||||||
|
|
||||||
let mut config: Config = confy::load_path(&self.config).unwrap_or_default();
|
let mut config: Config = confy::load_path(&self.config).unwrap_or_default();
|
||||||
|
|
||||||
let chain_id = self.chain.consensus.chain_id;
|
|
||||||
let genesis: Header = self.chain.genesis.clone().into();
|
|
||||||
let genesis_hash = genesis.hash_slow();
|
|
||||||
|
|
||||||
if let Some(peer) = self.trusted_peer {
|
if let Some(peer) = self.trusted_peer {
|
||||||
config.peers.trusted_nodes.insert(peer);
|
config.peers.trusted_nodes.insert(peer);
|
||||||
}
|
}
|
||||||
@ -101,7 +94,7 @@ impl Command {
|
|||||||
config.peers.connect_trusted_nodes_only = self.trusted_only;
|
config.peers.connect_trusted_nodes_only = self.trusted_only;
|
||||||
|
|
||||||
let network = config
|
let network = config
|
||||||
.network_config(noop_db, chain_id, genesis_hash, self.disable_discovery, None)
|
.network_config(noop_db, self.chain.clone(), self.disable_discovery, None)
|
||||||
.start_network()
|
.start_network()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -5,15 +5,13 @@ use crate::{
|
|||||||
config::Config,
|
config::Config,
|
||||||
dirs::{ConfigPath, DbPath, PlatformPath},
|
dirs::{ConfigPath, DbPath, PlatformPath},
|
||||||
prometheus_exporter,
|
prometheus_exporter,
|
||||||
utils::{
|
utils::{chainspec::chain_spec_value_parser, init::init_db},
|
||||||
chainspec::{chain_spec_value_parser, ChainSpecification},
|
|
||||||
init::{init_db, init_genesis},
|
|
||||||
},
|
|
||||||
NetworkOpts,
|
NetworkOpts,
|
||||||
};
|
};
|
||||||
use reth_consensus::BeaconConsensus;
|
use reth_consensus::BeaconConsensus;
|
||||||
use reth_downloaders::bodies::concurrent::ConcurrentDownloader;
|
use reth_downloaders::bodies::concurrent::ConcurrentDownloader;
|
||||||
use reth_executor::Config as ExecutorConfig;
|
|
||||||
|
use reth_primitives::ChainSpec;
|
||||||
use reth_stages::{
|
use reth_stages::{
|
||||||
metrics::HeaderMetrics,
|
metrics::HeaderMetrics,
|
||||||
stages::{bodies::BodyStage, execution::ExecutionStage, sender_recovery::SenderRecoveryStage},
|
stages::{bodies::BodyStage, execution::ExecutionStage, sender_recovery::SenderRecoveryStage},
|
||||||
@ -56,7 +54,7 @@ pub struct Command {
|
|||||||
default_value = "mainnet",
|
default_value = "mainnet",
|
||||||
value_parser = chain_spec_value_parser
|
value_parser = chain_spec_value_parser
|
||||||
)]
|
)]
|
||||||
chain: ChainSpecification,
|
chain: ChainSpec,
|
||||||
|
|
||||||
/// Enable Prometheus metrics.
|
/// Enable Prometheus metrics.
|
||||||
///
|
///
|
||||||
@ -126,9 +124,8 @@ impl Command {
|
|||||||
|
|
||||||
match self.stage {
|
match self.stage {
|
||||||
StageEnum::Bodies => {
|
StageEnum::Bodies => {
|
||||||
let chain_id = self.chain.consensus.chain_id;
|
let consensus: Arc<BeaconConsensus> =
|
||||||
let consensus = Arc::new(BeaconConsensus::new(self.chain.consensus.clone()));
|
Arc::new(BeaconConsensus::new(self.chain.clone()));
|
||||||
let genesis_hash = init_genesis(db.clone(), self.chain.genesis.clone())?;
|
|
||||||
|
|
||||||
let mut config = config;
|
let mut config = config;
|
||||||
config.peers.connect_trusted_nodes_only = self.network.trusted_only;
|
config.peers.connect_trusted_nodes_only = self.network.trusted_only;
|
||||||
@ -141,8 +138,7 @@ impl Command {
|
|||||||
let network = config
|
let network = config
|
||||||
.network_config(
|
.network_config(
|
||||||
db.clone(),
|
db.clone(),
|
||||||
chain_id,
|
self.chain.clone(),
|
||||||
genesis_hash,
|
|
||||||
self.network.disable_discovery,
|
self.network.disable_discovery,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
@ -179,10 +175,8 @@ impl Command {
|
|||||||
stage.execute(&mut tx, input).await?;
|
stage.execute(&mut tx, input).await?;
|
||||||
}
|
}
|
||||||
StageEnum::Execution => {
|
StageEnum::Execution => {
|
||||||
let mut stage = ExecutionStage {
|
let mut stage =
|
||||||
config: ExecutorConfig::new_ethereum(),
|
ExecutionStage { chain_spec: self.chain.clone(), commit_threshold: num_blocks };
|
||||||
commit_threshold: num_blocks,
|
|
||||||
};
|
|
||||||
if !self.skip_unwind {
|
if !self.skip_unwind {
|
||||||
stage.unwind(&mut tx, unwind).await?;
|
stage.unwind(&mut tx, unwind).await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Address, BigEndianHash, Bloom, Bytes, Header as RethHeader, JsonU256, SealedHeader, H160, H256,
|
Address, BigEndianHash, Bloom, Bytes, ChainSpec, ChainSpecBuilder, Header as RethHeader,
|
||||||
H64,
|
JsonU256, SealedHeader, H160, H256, H64,
|
||||||
};
|
};
|
||||||
use serde::{self, Deserialize};
|
use serde::{self, Deserialize};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@ -209,28 +209,30 @@ pub enum ForkSpec {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ForkSpec> for reth_executor::SpecUpgrades {
|
impl From<ForkSpec> for ChainSpec {
|
||||||
fn from(fork_spec: ForkSpec) -> Self {
|
fn from(fork_spec: ForkSpec) -> Self {
|
||||||
|
let spec_builder = ChainSpecBuilder::mainnet();
|
||||||
|
|
||||||
match fork_spec {
|
match fork_spec {
|
||||||
ForkSpec::Frontier => Self::new_frontier_activated(),
|
ForkSpec::Frontier => spec_builder.frontier_activated(),
|
||||||
ForkSpec::Homestead | ForkSpec::FrontierToHomesteadAt5 => {
|
ForkSpec::Homestead | ForkSpec::FrontierToHomesteadAt5 => {
|
||||||
Self::new_homestead_activated()
|
spec_builder.homestead_activated()
|
||||||
}
|
}
|
||||||
ForkSpec::EIP150 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => {
|
ForkSpec::EIP150 | ForkSpec::HomesteadToDaoAt5 | ForkSpec::HomesteadToEIP150At5 => {
|
||||||
Self::new_tangerine_whistle_activated()
|
spec_builder.tangerine_whistle_activated()
|
||||||
}
|
}
|
||||||
ForkSpec::EIP158 => Self::new_spurious_dragon_activated(),
|
ForkSpec::EIP158 => spec_builder.spurious_dragon_activated(),
|
||||||
ForkSpec::Byzantium |
|
ForkSpec::Byzantium |
|
||||||
ForkSpec::EIP158ToByzantiumAt5 |
|
ForkSpec::EIP158ToByzantiumAt5 |
|
||||||
ForkSpec::ConstantinopleFix |
|
ForkSpec::ConstantinopleFix |
|
||||||
ForkSpec::ByzantiumToConstantinopleFixAt5 => Self::new_byzantium_activated(),
|
ForkSpec::ByzantiumToConstantinopleFixAt5 => spec_builder.byzantium_activated(),
|
||||||
ForkSpec::Istanbul => Self::new_istanbul_activated(),
|
ForkSpec::Istanbul => spec_builder.istanbul_activated(),
|
||||||
ForkSpec::Berlin => Self::new_berlin_activated(),
|
ForkSpec::Berlin => spec_builder.berlin_activated(),
|
||||||
ForkSpec::London | ForkSpec::BerlinToLondonAt5 => Self::new_london_activated(),
|
ForkSpec::London | ForkSpec::BerlinToLondonAt5 => spec_builder.london_activated(),
|
||||||
ForkSpec::Merge => Self::new_paris_activated(),
|
ForkSpec::Merge => spec_builder.paris_activated(),
|
||||||
ForkSpec::MergeEOF => Self::new_paris_activated(),
|
ForkSpec::MergeEOF => spec_builder.paris_activated(),
|
||||||
ForkSpec::MergeMeterInitCode => Self::new_paris_activated(),
|
ForkSpec::MergeMeterInitCode => spec_builder.paris_activated(),
|
||||||
ForkSpec::MergePush0 => Self::new_paris_activated(),
|
ForkSpec::MergePush0 => spec_builder.paris_activated(),
|
||||||
ForkSpec::Shanghai => {
|
ForkSpec::Shanghai => {
|
||||||
panic!("Not supported")
|
panic!("Not supported")
|
||||||
}
|
}
|
||||||
@ -241,6 +243,7 @@ impl From<ForkSpec> for reth_executor::SpecUpgrades {
|
|||||||
panic!("Unknown fork");
|
panic!("Unknown fork");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,10 +9,9 @@ use reth_db::{
|
|||||||
transaction::{DbTx, DbTxMut},
|
transaction::{DbTx, DbTxMut},
|
||||||
Error as DbError,
|
Error as DbError,
|
||||||
};
|
};
|
||||||
use reth_executor::SpecUpgrades;
|
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
keccak256, Account as RethAccount, Address, JsonU256, SealedBlock, SealedHeader, StorageEntry,
|
keccak256, Account as RethAccount, Address, ChainSpec, JsonU256, SealedBlock, SealedHeader,
|
||||||
H256, U256,
|
StorageEntry, H256, U256,
|
||||||
};
|
};
|
||||||
use reth_rlp::Decodable;
|
use reth_rlp::Decodable;
|
||||||
use reth_stages::{stages::execution::ExecutionStage, ExecInput, Stage, StageId, Transaction};
|
use reth_stages::{stages::execution::ExecutionStage, ExecInput, Stage, StageId, Transaction};
|
||||||
@ -124,9 +123,9 @@ pub async fn run_test(path: PathBuf) -> eyre::Result<TestOutcome> {
|
|||||||
|
|
||||||
debug!(target: "reth::cli", name, network = ?suite.network, "Running test");
|
debug!(target: "reth::cli", name, network = ?suite.network, "Running test");
|
||||||
|
|
||||||
let spec_upgrades: SpecUpgrades = suite.network.into();
|
let chain_spec: ChainSpec = suite.network.into();
|
||||||
// if paris aka merge is not activated we dont have block rewards;
|
// if paris aka merge is not activated we dont have block rewards;
|
||||||
let has_block_reward = spec_upgrades.paris != 0;
|
let has_block_reward = chain_spec.paris_status().block_number().is_some();
|
||||||
|
|
||||||
// Create db and acquire transaction
|
// Create db and acquire transaction
|
||||||
let db = create_test_rw_db::<WriteMap>();
|
let db = create_test_rw_db::<WriteMap>();
|
||||||
@ -189,10 +188,7 @@ pub async fn run_test(path: PathBuf) -> eyre::Result<TestOutcome> {
|
|||||||
|
|
||||||
// Initialize the execution stage
|
// Initialize the execution stage
|
||||||
// Hardcode the chain_id to Ethereum 1.
|
// Hardcode the chain_id to Ethereum 1.
|
||||||
let mut stage = ExecutionStage::new(
|
let mut stage = ExecutionStage::new(chain_spec, 1000);
|
||||||
reth_executor::Config { chain_id: U256::from(1), spec_upgrades },
|
|
||||||
1000,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Call execution stage
|
// Call execution stage
|
||||||
let input = ExecInput {
|
let input = ExecInput {
|
||||||
|
|||||||
@ -1,86 +1,13 @@
|
|||||||
use reth_primitives::{
|
use reth_primitives::{ChainSpec, GOERLI, MAINNET, SEPOLIA};
|
||||||
utils::serde_helpers::deserialize_stringified_u64, Address, Bytes, Header, H256, U256,
|
use std::path::PathBuf;
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
|
||||||
|
|
||||||
/// Defines a chain, including it's genesis block, chain ID and fork block numbers.
|
/// Clap value parser for [ChainSpec]s that takes either a built-in chainspec or the path
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
|
||||||
pub struct ChainSpecification {
|
|
||||||
/// Consensus configuration.
|
|
||||||
#[serde(rename = "config")]
|
|
||||||
pub consensus: reth_consensus::Config,
|
|
||||||
/// The genesis block of the chain.
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub genesis: Genesis,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The genesis block specification.
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Genesis {
|
|
||||||
/// The genesis header nonce.
|
|
||||||
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
|
||||||
pub nonce: u64,
|
|
||||||
/// The genesis header timestamp.
|
|
||||||
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
|
||||||
pub timestamp: u64,
|
|
||||||
/// The genesis header extra data.
|
|
||||||
pub extra_data: Bytes,
|
|
||||||
/// The genesis header gas limit.
|
|
||||||
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
|
||||||
pub gas_limit: u64,
|
|
||||||
/// The genesis header difficulty.
|
|
||||||
pub difficulty: U256,
|
|
||||||
/// The genesis header mix hash.
|
|
||||||
pub mix_hash: H256,
|
|
||||||
/// The genesis header coinbase address.
|
|
||||||
pub coinbase: Address,
|
|
||||||
/// The genesis state root.
|
|
||||||
pub state_root: H256,
|
|
||||||
/// The initial state of accounts in the genesis block.
|
|
||||||
pub alloc: HashMap<Address, GenesisAccount>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Genesis> for Header {
|
|
||||||
fn from(genesis: Genesis) -> Header {
|
|
||||||
Header {
|
|
||||||
gas_limit: genesis.gas_limit,
|
|
||||||
difficulty: genesis.difficulty,
|
|
||||||
nonce: genesis.nonce,
|
|
||||||
extra_data: genesis.extra_data,
|
|
||||||
state_root: genesis.state_root,
|
|
||||||
timestamp: genesis.timestamp,
|
|
||||||
mix_hash: genesis.mix_hash,
|
|
||||||
beneficiary: genesis.coinbase,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An account in the state of the genesis block.
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct GenesisAccount {
|
|
||||||
/// The nonce of the account at genesis.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub nonce: Option<u64>,
|
|
||||||
/// The balance of the account at genesis.
|
|
||||||
pub balance: U256,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clap value parser for [ChainSpecification]s that takes either a built-in chainspec or the path
|
|
||||||
/// to a custom one.
|
/// to a custom one.
|
||||||
pub fn chain_spec_value_parser(s: &str) -> Result<ChainSpecification, eyre::Error> {
|
pub fn chain_spec_value_parser(s: &str) -> Result<ChainSpec, eyre::Error> {
|
||||||
Ok(match s {
|
Ok(match s {
|
||||||
"mainnet" => {
|
"mainnet" => MAINNET.clone(),
|
||||||
serde_json::from_str(include_str!("../../../../bin/reth/res/chainspec/mainnet.json"))?
|
"goerli" => GOERLI.clone(),
|
||||||
}
|
"sepolia" => SEPOLIA.clone(),
|
||||||
"goerli" => {
|
|
||||||
serde_json::from_str(include_str!("../../../../bin/reth/res/chainspec/goerli.json"))?
|
|
||||||
}
|
|
||||||
"sepolia" => {
|
|
||||||
serde_json::from_str(include_str!("../../../../bin/reth/res/chainspec/sepolia.json"))?
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
|
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
|
||||||
serde_json::from_str(&raw)?
|
serde_json::from_str(&raw)?
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use crate::chainspec::Genesis;
|
|
||||||
use reth_db::{
|
use reth_db::{
|
||||||
cursor::DbCursorRO,
|
cursor::DbCursorRO,
|
||||||
database::Database,
|
database::Database,
|
||||||
@ -6,7 +5,7 @@ use reth_db::{
|
|||||||
tables,
|
tables,
|
||||||
transaction::{DbTx, DbTxMut},
|
transaction::{DbTx, DbTxMut},
|
||||||
};
|
};
|
||||||
use reth_primitives::{Account, Header, H256};
|
use reth_primitives::{Account, Genesis, Header, H256};
|
||||||
use std::{path::Path, sync::Arc};
|
use std::{path::Path, sync::Arc};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
|||||||
@ -1,100 +0,0 @@
|
|||||||
//! Reth block execution/validation configuration and constants
|
|
||||||
use reth_executor::{Config as ExecutorConfig, SpecUpgrades};
|
|
||||||
use reth_primitives::{BlockNumber, U256};
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// Initial base fee as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
|
||||||
pub const EIP1559_INITIAL_BASE_FEE: u64 = 1_000_000_000;
|
|
||||||
/// Base fee max change denominator as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
|
||||||
pub const EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
|
|
||||||
/// Elasticity multiplier as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
|
||||||
pub const EIP1559_ELASTICITY_MULTIPLIER: u64 = 2;
|
|
||||||
|
|
||||||
/// Common configuration for consensus algorithms.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
|
||||||
pub struct Config {
|
|
||||||
/// Blockchain identifier introduced in EIP-155: Simple replay attack protection.
|
|
||||||
pub chain_id: u64,
|
|
||||||
|
|
||||||
/// Homestead switch block.
|
|
||||||
pub homestead_block: BlockNumber,
|
|
||||||
|
|
||||||
/// TheDAO hard-fork switch block.
|
|
||||||
pub dao_fork_block: BlockNumber,
|
|
||||||
/// Whether the node supports or opposes the DAO hard-fork
|
|
||||||
pub dao_fork_support: bool,
|
|
||||||
|
|
||||||
/// EIP150 implements gas price changes.
|
|
||||||
pub eip_150_block: BlockNumber,
|
|
||||||
|
|
||||||
/// EIP155 hard-fork block (Spurious Dragon)
|
|
||||||
pub eip_155_block: BlockNumber,
|
|
||||||
/// EIP158 hard-fork block.
|
|
||||||
pub eip_158_block: BlockNumber,
|
|
||||||
/// Byzantium switch block.
|
|
||||||
pub byzantium_block: BlockNumber,
|
|
||||||
/// Constantinople switch block.
|
|
||||||
pub constantinople_block: BlockNumber,
|
|
||||||
/// Petersburg switch block.
|
|
||||||
pub petersburg_block: BlockNumber,
|
|
||||||
/// Istanbul switch block.
|
|
||||||
pub istanbul_block: BlockNumber,
|
|
||||||
/// EIP-2728 switch block.
|
|
||||||
pub berlin_block: BlockNumber,
|
|
||||||
/// EIP-1559 switch block.
|
|
||||||
pub london_block: BlockNumber,
|
|
||||||
/// The Merge/Paris hard-fork block number.
|
|
||||||
pub paris_block: BlockNumber,
|
|
||||||
/// Terminal total difficulty after the paris hard-fork to reach before The Merge is considered
|
|
||||||
/// activated.
|
|
||||||
#[cfg_attr(feature = "serde", serde(rename = "terminalTotalDifficulty"))]
|
|
||||||
pub merge_terminal_total_difficulty: u128,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
chain_id: 1,
|
|
||||||
homestead_block: 1150000,
|
|
||||||
dao_fork_block: 1920000,
|
|
||||||
dao_fork_support: true,
|
|
||||||
eip_150_block: 2463000,
|
|
||||||
eip_155_block: 2675000,
|
|
||||||
eip_158_block: 2675000,
|
|
||||||
byzantium_block: 4370000,
|
|
||||||
constantinople_block: 7280000,
|
|
||||||
petersburg_block: 7280000,
|
|
||||||
istanbul_block: 9069000,
|
|
||||||
berlin_block: 12244000,
|
|
||||||
london_block: 12965000,
|
|
||||||
paris_block: 15537394,
|
|
||||||
merge_terminal_total_difficulty: 58750000000000000000000,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Config> for ExecutorConfig {
|
|
||||||
fn from(value: &Config) -> Self {
|
|
||||||
Self {
|
|
||||||
chain_id: U256::from(value.chain_id),
|
|
||||||
spec_upgrades: SpecUpgrades {
|
|
||||||
frontier: 0,
|
|
||||||
homestead: value.homestead_block,
|
|
||||||
dao_fork: value.dao_fork_block,
|
|
||||||
tangerine_whistle: value.eip_150_block,
|
|
||||||
spurious_dragon: value.eip_158_block,
|
|
||||||
byzantium: value.byzantium_block,
|
|
||||||
petersburg: value.petersburg_block,
|
|
||||||
istanbul: value.istanbul_block,
|
|
||||||
berlin: value.berlin_block,
|
|
||||||
london: value.london_block,
|
|
||||||
paris: value.paris_block,
|
|
||||||
shanghai: u64::MAX, // TODO: change once known
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
//! Consensus for ethereum network
|
//! Consensus for ethereum network
|
||||||
use crate::{verification, Config};
|
use crate::verification;
|
||||||
use reth_interfaces::consensus::{Consensus, Error, ForkchoiceState};
|
use reth_interfaces::consensus::{Consensus, Error, ForkchoiceState};
|
||||||
use reth_primitives::{BlockNumber, SealedBlock, SealedHeader, H256};
|
use reth_primitives::{BlockNumber, ChainSpec, SealedBlock, SealedHeader, H256};
|
||||||
use tokio::sync::{watch, watch::error::SendError};
|
use tokio::sync::{watch, watch::error::SendError};
|
||||||
|
|
||||||
/// Ethereum beacon consensus
|
/// Ethereum beacon consensus
|
||||||
@ -12,19 +12,19 @@ pub struct BeaconConsensus {
|
|||||||
/// Watcher over the forkchoice state
|
/// Watcher over the forkchoice state
|
||||||
channel: (watch::Sender<ForkchoiceState>, watch::Receiver<ForkchoiceState>),
|
channel: (watch::Sender<ForkchoiceState>, watch::Receiver<ForkchoiceState>),
|
||||||
/// Configuration
|
/// Configuration
|
||||||
config: Config,
|
chain_spec: ChainSpec,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BeaconConsensus {
|
impl BeaconConsensus {
|
||||||
/// Create a new instance of [BeaconConsensus]
|
/// Create a new instance of [BeaconConsensus]
|
||||||
pub fn new(config: Config) -> Self {
|
pub fn new(chain_spec: ChainSpec) -> Self {
|
||||||
Self {
|
Self {
|
||||||
channel: watch::channel(ForkchoiceState {
|
channel: watch::channel(ForkchoiceState {
|
||||||
head_block_hash: H256::zero(),
|
head_block_hash: H256::zero(),
|
||||||
finalized_block_hash: H256::zero(),
|
finalized_block_hash: H256::zero(),
|
||||||
safe_block_hash: H256::zero(),
|
safe_block_hash: H256::zero(),
|
||||||
}),
|
}),
|
||||||
config,
|
chain_spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,10 +43,10 @@ impl Consensus for BeaconConsensus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate_header(&self, header: &SealedHeader, parent: &SealedHeader) -> Result<(), Error> {
|
fn validate_header(&self, header: &SealedHeader, parent: &SealedHeader) -> Result<(), Error> {
|
||||||
verification::validate_header_standalone(header, &self.config)?;
|
verification::validate_header_standalone(header, &self.chain_spec)?;
|
||||||
verification::validate_header_regarding_parent(parent, header, &self.config)?;
|
verification::validate_header_regarding_parent(parent, header, &self.chain_spec)?;
|
||||||
|
|
||||||
if header.number < self.config.paris_block {
|
if Some(header.number) < self.chain_spec.paris_status().block_number() {
|
||||||
// TODO Consensus checks for old blocks:
|
// TODO Consensus checks for old blocks:
|
||||||
// * difficulty, mix_hash & nonce aka PoW stuff
|
// * difficulty, mix_hash & nonce aka PoW stuff
|
||||||
// low priority as syncing is done in reverse order
|
// low priority as syncing is done in reverse order
|
||||||
@ -59,6 +59,6 @@ impl Consensus for BeaconConsensus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn has_block_reward(&self, block_num: BlockNumber) -> bool {
|
fn has_block_reward(&self, block_num: BlockNumber) -> bool {
|
||||||
block_num < self.config.paris_block
|
Some(block_num) < self.chain_spec.paris_status().block_number()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
crates/consensus/src/constants.rs
Normal file
8
crates/consensus/src/constants.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//! Reth block execution/validation configuration and constants
|
||||||
|
|
||||||
|
/// Initial base fee as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
||||||
|
pub const EIP1559_INITIAL_BASE_FEE: u64 = 1_000_000_000;
|
||||||
|
/// Base fee max change denominator as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
||||||
|
pub const EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
|
||||||
|
/// Elasticity multiplier as defined in: https://eips.ethereum.org/EIPS/eip-1559
|
||||||
|
pub const EIP1559_ELASTICITY_MULTIPLIER: u64 = 2;
|
||||||
@ -64,6 +64,9 @@ pub enum EngineApiError {
|
|||||||
/// Forkchoice zero hash head received.
|
/// Forkchoice zero hash head received.
|
||||||
#[error("Received zero hash as forkchoice head")]
|
#[error("Received zero hash as forkchoice head")]
|
||||||
ForkchoiceEmptyHead,
|
ForkchoiceEmptyHead,
|
||||||
|
/// Chain spec merge terminal total difficulty is not set
|
||||||
|
#[error("The merge terminal total difficulty is not known")]
|
||||||
|
UnknownMergeTerminalTotalDifficulty,
|
||||||
/// Encountered decoding error.
|
/// Encountered decoding error.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Decode(#[from] reth_rlp::DecodeError),
|
Decode(#[from] reth_rlp::DecodeError),
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use reth_interfaces::consensus::ForkchoiceState;
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
proofs::{self, EMPTY_LIST_HASH},
|
proofs::{self, EMPTY_LIST_HASH},
|
||||||
rpc::{BlockId, H256 as EthersH256},
|
rpc::{BlockId, H256 as EthersH256},
|
||||||
Header, SealedBlock, TransactionSigned, H64, U256,
|
ChainSpec, Header, SealedBlock, TransactionSigned, H64, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{BlockProvider, HeaderProvider, StateProvider};
|
use reth_provider::{BlockProvider, HeaderProvider, StateProvider};
|
||||||
use reth_rlp::Decodable;
|
use reth_rlp::Decodable;
|
||||||
@ -25,8 +25,6 @@ use std::{
|
|||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
use crate::Config;
|
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
pub use error::{EngineApiError, EngineApiResult};
|
pub use error::{EngineApiError, EngineApiResult};
|
||||||
|
|
||||||
@ -80,7 +78,7 @@ pub enum EngineMessage {
|
|||||||
pub struct EthConsensusEngine<Client> {
|
pub struct EthConsensusEngine<Client> {
|
||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
/// Consensus configuration
|
/// Consensus configuration
|
||||||
config: Config,
|
chain_spec: ChainSpec,
|
||||||
rx: UnboundedReceiverStream<EngineMessage>,
|
rx: UnboundedReceiverStream<EngineMessage>,
|
||||||
// TODO: Placeholder for storing future blocks. Make cache bounded.
|
// TODO: Placeholder for storing future blocks. Make cache bounded.
|
||||||
// Use [lru](https://crates.io/crates/lru) crate
|
// Use [lru](https://crates.io/crates/lru) crate
|
||||||
@ -190,7 +188,7 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(parent_td) = self.client.header_td(&block.parent_hash)? {
|
if let Some(parent_td) = self.client.header_td(&block.parent_hash)? {
|
||||||
if parent_td <= U256::from(self.config.merge_terminal_total_difficulty) {
|
if Some(parent_td) <= self.chain_spec.paris_status().terminal_total_difficulty() {
|
||||||
return Ok(PayloadStatus::from_status(PayloadStatusEnum::Invalid {
|
return Ok(PayloadStatus::from_status(PayloadStatusEnum::Invalid {
|
||||||
validation_error: EngineApiError::PayloadPreMerge.to_string(),
|
validation_error: EngineApiError::PayloadPreMerge.to_string(),
|
||||||
}))
|
}))
|
||||||
@ -216,12 +214,11 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, EngineApiError>>()?;
|
.collect::<Result<Vec<_>, EngineApiError>>()?;
|
||||||
let mut state_provider = SubState::new(State::new(&*self.client));
|
let mut state_provider = SubState::new(State::new(&*self.client));
|
||||||
let config = (&self.config).into();
|
|
||||||
match executor::execute_and_verify_receipt(
|
match executor::execute_and_verify_receipt(
|
||||||
&header,
|
&header,
|
||||||
&transactions,
|
&transactions,
|
||||||
&[],
|
&[],
|
||||||
&config,
|
&self.chain_spec,
|
||||||
&mut state_provider,
|
&mut state_provider,
|
||||||
) {
|
) {
|
||||||
Ok(_) => Ok(PayloadStatus::new(PayloadStatusEnum::Valid, header.hash())),
|
Ok(_) => Ok(PayloadStatus::new(PayloadStatusEnum::Valid, header.hash())),
|
||||||
@ -272,8 +269,13 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
|
|||||||
terminal_block_number,
|
terminal_block_number,
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
|
let merge_terminal_td = self
|
||||||
|
.chain_spec
|
||||||
|
.paris_status()
|
||||||
|
.terminal_total_difficulty()
|
||||||
|
.ok_or(EngineApiError::UnknownMergeTerminalTotalDifficulty)?;
|
||||||
|
|
||||||
// Compare total difficulty values
|
// Compare total difficulty values
|
||||||
let merge_terminal_td = U256::from(self.config.merge_terminal_total_difficulty);
|
|
||||||
if merge_terminal_td != terminal_total_difficulty {
|
if merge_terminal_td != terminal_total_difficulty {
|
||||||
return Err(EngineApiError::TerminalTD {
|
return Err(EngineApiError::TerminalTD {
|
||||||
execution: merge_terminal_td,
|
execution: merge_terminal_td,
|
||||||
@ -340,7 +342,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use reth_interfaces::test_utils::generators::random_header;
|
use reth_interfaces::test_utils::generators::random_header;
|
||||||
use reth_primitives::Block;
|
use reth_primitives::{Block, MAINNET};
|
||||||
use reth_rlp::DecodeError;
|
use reth_rlp::DecodeError;
|
||||||
|
|
||||||
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> SealedBlock {
|
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> SealedBlock {
|
||||||
@ -363,7 +365,7 @@ mod tests {
|
|||||||
let (_tx, rx) = unbounded_channel();
|
let (_tx, rx) = unbounded_channel();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: Arc::new(MockEthProvider::default()),
|
client: Arc::new(MockEthProvider::default()),
|
||||||
config: Config::default(),
|
chain_spec: MAINNET.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -452,7 +454,7 @@ mod tests {
|
|||||||
let client = Arc::new(MockEthProvider::default());
|
let client = Arc::new(MockEthProvider::default());
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
config: Config::default(),
|
chain_spec: MAINNET.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -480,7 +482,7 @@ mod tests {
|
|||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: Arc::new(MockEthProvider::default()),
|
client: Arc::new(MockEthProvider::default()),
|
||||||
config: Config::default(),
|
chain_spec: MAINNET.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -501,11 +503,11 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn payload_pre_merge() {
|
async fn payload_pre_merge() {
|
||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let config = Config::default();
|
let chain_spec = MAINNET.clone();
|
||||||
let client = Arc::new(MockEthProvider::default());
|
let client = Arc::new(MockEthProvider::default());
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
config: config.clone(),
|
chain_spec: chain_spec.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -514,7 +516,8 @@ mod tests {
|
|||||||
|
|
||||||
let (result_tx, result_rx) = oneshot::channel();
|
let (result_tx, result_rx) = oneshot::channel();
|
||||||
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
|
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
|
||||||
b.header.difficulty = U256::from(config.merge_terminal_total_difficulty);
|
b.header.difficulty =
|
||||||
|
chain_spec.paris_status().terminal_total_difficulty().unwrap();
|
||||||
b
|
b
|
||||||
});
|
});
|
||||||
let block = random_block(101, Some(parent.hash()), None, Some(0));
|
let block = random_block(101, Some(parent.hash()), None, Some(0));
|
||||||
@ -535,11 +538,11 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn invalid_payload_timestamp() {
|
async fn invalid_payload_timestamp() {
|
||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let config = Config::default();
|
let chain_spec = MAINNET.clone();
|
||||||
let client = Arc::new(MockEthProvider::default());
|
let client = Arc::new(MockEthProvider::default());
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
config: config.clone(),
|
chain_spec: chain_spec.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -551,7 +554,8 @@ mod tests {
|
|||||||
let parent_timestamp = block_timestamp + 10;
|
let parent_timestamp = block_timestamp + 10;
|
||||||
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
|
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
|
||||||
b.header.timestamp = parent_timestamp;
|
b.header.timestamp = parent_timestamp;
|
||||||
b.header.difficulty = U256::from(config.merge_terminal_total_difficulty + 1);
|
b.header.difficulty =
|
||||||
|
chain_spec.paris_status().terminal_total_difficulty().unwrap() + U256::from(1);
|
||||||
b
|
b
|
||||||
});
|
});
|
||||||
let block =
|
let block =
|
||||||
@ -583,6 +587,8 @@ mod tests {
|
|||||||
// non exhaustive tests for engine_getPayload
|
// non exhaustive tests for engine_getPayload
|
||||||
// TODO: amend when block building is implemented
|
// TODO: amend when block building is implemented
|
||||||
mod get_payload {
|
mod get_payload {
|
||||||
|
use reth_primitives::MAINNET;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@ -590,7 +596,7 @@ mod tests {
|
|||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: Arc::new(MockEthProvider::default()),
|
client: Arc::new(MockEthProvider::default()),
|
||||||
config: Config::default(),
|
chain_spec: MAINNET.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -609,15 +615,17 @@ mod tests {
|
|||||||
|
|
||||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification-3
|
// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification-3
|
||||||
mod exchange_transition_configuration {
|
mod exchange_transition_configuration {
|
||||||
|
use reth_primitives::MAINNET;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn terminal_td_mismatch() {
|
async fn terminal_td_mismatch() {
|
||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let config = Config::default();
|
let chain_spec = MAINNET.clone();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: Arc::new(MockEthProvider::default()),
|
client: Arc::new(MockEthProvider::default()),
|
||||||
config: config.clone(),
|
chain_spec: chain_spec.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -625,7 +633,11 @@ mod tests {
|
|||||||
tokio::spawn(engine);
|
tokio::spawn(engine);
|
||||||
|
|
||||||
let transition_config = TransitionConfiguration {
|
let transition_config = TransitionConfiguration {
|
||||||
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty + 1),
|
terminal_total_difficulty: chain_spec
|
||||||
|
.paris_status()
|
||||||
|
.terminal_total_difficulty()
|
||||||
|
.unwrap() +
|
||||||
|
U256::from(1),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -639,7 +651,7 @@ mod tests {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
result_rx.await,
|
result_rx.await,
|
||||||
Ok(Err(EngineApiError::TerminalTD { execution, consensus }))
|
Ok(Err(EngineApiError::TerminalTD { execution, consensus }))
|
||||||
if execution == U256::from(config.merge_terminal_total_difficulty)
|
if execution == chain_spec.paris_status().terminal_total_difficulty().unwrap()
|
||||||
&& consensus == U256::from(transition_config.terminal_total_difficulty)
|
&& consensus == U256::from(transition_config.terminal_total_difficulty)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -648,10 +660,10 @@ mod tests {
|
|||||||
async fn terminal_block_hash_mismatch() {
|
async fn terminal_block_hash_mismatch() {
|
||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let client = Arc::new(MockEthProvider::default());
|
let client = Arc::new(MockEthProvider::default());
|
||||||
let config = Config::default();
|
let chain_spec = MAINNET.clone();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
config: config.clone(),
|
chain_spec: chain_spec.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -663,7 +675,10 @@ mod tests {
|
|||||||
let execution_terminal_block = random_block(terminal_block_number, None, None, None);
|
let execution_terminal_block = random_block(terminal_block_number, None, None, None);
|
||||||
|
|
||||||
let transition_config = TransitionConfiguration {
|
let transition_config = TransitionConfiguration {
|
||||||
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty),
|
terminal_total_difficulty: chain_spec
|
||||||
|
.paris_status()
|
||||||
|
.terminal_total_difficulty()
|
||||||
|
.unwrap(),
|
||||||
terminal_block_hash: consensus_terminal_block.hash(),
|
terminal_block_hash: consensus_terminal_block.hash(),
|
||||||
terminal_block_number: terminal_block_number.into(),
|
terminal_block_number: terminal_block_number.into(),
|
||||||
};
|
};
|
||||||
@ -708,10 +723,10 @@ mod tests {
|
|||||||
async fn configurations_match() {
|
async fn configurations_match() {
|
||||||
let (tx, rx) = unbounded_channel();
|
let (tx, rx) = unbounded_channel();
|
||||||
let client = Arc::new(MockEthProvider::default());
|
let client = Arc::new(MockEthProvider::default());
|
||||||
let config = Config::default();
|
let chain_spec = MAINNET.clone();
|
||||||
let engine = EthConsensusEngine {
|
let engine = EthConsensusEngine {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
config: config.clone(),
|
chain_spec: chain_spec.clone(),
|
||||||
local_store: Default::default(),
|
local_store: Default::default(),
|
||||||
rx: UnboundedReceiverStream::new(rx),
|
rx: UnboundedReceiverStream::new(rx),
|
||||||
};
|
};
|
||||||
@ -722,7 +737,10 @@ mod tests {
|
|||||||
let terminal_block = random_block(terminal_block_number, None, None, None);
|
let terminal_block = random_block(terminal_block_number, None, None, None);
|
||||||
|
|
||||||
let transition_config = TransitionConfiguration {
|
let transition_config = TransitionConfiguration {
|
||||||
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty),
|
terminal_total_difficulty: chain_spec
|
||||||
|
.paris_status()
|
||||||
|
.terminal_total_difficulty()
|
||||||
|
.unwrap(),
|
||||||
terminal_block_hash: terminal_block.hash(),
|
terminal_block_hash: terminal_block.hash(),
|
||||||
terminal_block_number: terminal_block_number.into(),
|
terminal_block_number: terminal_block_number.into(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,13 +9,12 @@
|
|||||||
//! # Features
|
//! # Features
|
||||||
//!
|
//!
|
||||||
//! - `serde`: Enable serde support for configuration types.
|
//! - `serde`: Enable serde support for configuration types.
|
||||||
pub mod config;
|
|
||||||
pub mod consensus;
|
pub mod consensus;
|
||||||
|
pub mod constants;
|
||||||
pub mod verification;
|
pub mod verification;
|
||||||
|
|
||||||
/// Engine API module.
|
/// Engine API module.
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
|
|
||||||
pub use config::Config;
|
|
||||||
pub use consensus::BeaconConsensus;
|
pub use consensus::BeaconConsensus;
|
||||||
pub use reth_interfaces::consensus::Error;
|
pub use reth_interfaces::consensus::Error;
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
//! ALl functions for verification of block
|
//! ALl functions for verification of block
|
||||||
use crate::{config, Config};
|
|
||||||
use reth_interfaces::{consensus::Error, Result as RethResult};
|
use reth_interfaces::{consensus::Error, Result as RethResult};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
BlockNumber, Header, SealedBlock, SealedHeader, Transaction, TransactionSignedEcRecovered,
|
BlockNumber, ChainSpec, Hardfork, Header, SealedBlock, SealedHeader, Transaction,
|
||||||
TxEip1559, TxEip2930, TxLegacy, EMPTY_OMMER_ROOT, U256,
|
TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy, EMPTY_OMMER_ROOT, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{AccountProvider, HeaderProvider};
|
use reth_provider::{AccountProvider, HeaderProvider};
|
||||||
use std::{
|
use std::{
|
||||||
@ -11,10 +10,12 @@ use std::{
|
|||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::constants;
|
||||||
|
|
||||||
/// Validate header standalone
|
/// Validate header standalone
|
||||||
pub fn validate_header_standalone(
|
pub fn validate_header_standalone(
|
||||||
header: &SealedHeader,
|
header: &SealedHeader,
|
||||||
config: &config::Config,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Gas used needs to be less then gas limit. Gas used is going to be check after execution.
|
// Gas used needs to be less then gas limit. Gas used is going to be check after execution.
|
||||||
if header.gas_used > header.gas_limit {
|
if header.gas_used > header.gas_limit {
|
||||||
@ -38,13 +39,14 @@ pub fn validate_header_standalone(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if base fee is set.
|
// Check if base fee is set.
|
||||||
if header.number >= config.london_block && header.base_fee_per_gas.is_none() {
|
if chain_spec.fork_active(Hardfork::London, header.number) && header.base_fee_per_gas.is_none()
|
||||||
|
{
|
||||||
return Err(Error::BaseFeeMissing)
|
return Err(Error::BaseFeeMissing)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EIP-3675: Upgrade consensus to Proof-of-Stake:
|
// EIP-3675: Upgrade consensus to Proof-of-Stake:
|
||||||
// https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0
|
// https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0
|
||||||
if header.number >= config.paris_block {
|
if Some(header.number) >= chain_spec.paris_status().block_number() {
|
||||||
if header.difficulty != U256::ZERO {
|
if header.difficulty != U256::ZERO {
|
||||||
return Err(Error::TheMergeDifficultyIsNotZero)
|
return Err(Error::TheMergeDifficultyIsNotZero)
|
||||||
}
|
}
|
||||||
@ -69,21 +71,23 @@ pub fn validate_header_standalone(
|
|||||||
/// The only parameter from the header that affects the transaction is `base_fee`.
|
/// The only parameter from the header that affects the transaction is `base_fee`.
|
||||||
pub fn validate_transaction_regarding_header(
|
pub fn validate_transaction_regarding_header(
|
||||||
transaction: &Transaction,
|
transaction: &Transaction,
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
at_block_number: BlockNumber,
|
at_block_number: BlockNumber,
|
||||||
base_fee: Option<u64>,
|
base_fee: Option<u64>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let chain_id = match transaction {
|
let chain_id = match transaction {
|
||||||
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
|
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
|
||||||
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
|
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
|
||||||
if config.eip_155_block <= at_block_number && chain_id.is_some() {
|
if chain_spec.fork_active(Hardfork::SpuriousDragon, at_block_number) &&
|
||||||
|
chain_id.is_some()
|
||||||
|
{
|
||||||
return Err(Error::TransactionOldLegacyChainId)
|
return Err(Error::TransactionOldLegacyChainId)
|
||||||
}
|
}
|
||||||
*chain_id
|
*chain_id
|
||||||
}
|
}
|
||||||
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
|
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
|
||||||
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
|
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
|
||||||
if config.berlin_block > at_block_number {
|
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
|
||||||
return Err(Error::TransactionEip2930Disabled)
|
return Err(Error::TransactionEip2930Disabled)
|
||||||
}
|
}
|
||||||
Some(*chain_id)
|
Some(*chain_id)
|
||||||
@ -95,7 +99,7 @@ pub fn validate_transaction_regarding_header(
|
|||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
|
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
|
||||||
if config.berlin_block > at_block_number {
|
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
|
||||||
return Err(Error::TransactionEip1559Disabled)
|
return Err(Error::TransactionEip1559Disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +113,7 @@ pub fn validate_transaction_regarding_header(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(chain_id) = chain_id {
|
if let Some(chain_id) = chain_id {
|
||||||
if chain_id != config.chain_id {
|
if chain_id != chain_spec.chain().id() {
|
||||||
return Err(Error::TransactionChainId)
|
return Err(Error::TransactionChainId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,14 +137,14 @@ pub fn validate_all_transaction_regarding_block_and_nonces<
|
|||||||
transactions: impl Iterator<Item = &'a TransactionSignedEcRecovered>,
|
transactions: impl Iterator<Item = &'a TransactionSignedEcRecovered>,
|
||||||
header: &Header,
|
header: &Header,
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
) -> RethResult<()> {
|
) -> RethResult<()> {
|
||||||
let mut account_nonces = HashMap::new();
|
let mut account_nonces = HashMap::new();
|
||||||
|
|
||||||
for transaction in transactions {
|
for transaction in transactions {
|
||||||
validate_transaction_regarding_header(
|
validate_transaction_regarding_header(
|
||||||
transaction,
|
transaction,
|
||||||
config,
|
chain_spec,
|
||||||
header.number,
|
header.number,
|
||||||
header.base_fee_per_gas,
|
header.base_fee_per_gas,
|
||||||
)?;
|
)?;
|
||||||
@ -208,7 +212,7 @@ pub fn validate_block_standalone(block: &SealedBlock) -> Result<(), Error> {
|
|||||||
|
|
||||||
/// Calculate base fee for next block. EIP-1559 spec
|
/// Calculate base fee for next block. EIP-1559 spec
|
||||||
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
|
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
|
||||||
let gas_target = gas_limit / config::EIP1559_ELASTICITY_MULTIPLIER;
|
let gas_target = gas_limit / constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||||
|
|
||||||
if gas_used == gas_target {
|
if gas_used == gas_target {
|
||||||
return base_fee
|
return base_fee
|
||||||
@ -219,14 +223,14 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6
|
|||||||
1,
|
1,
|
||||||
base_fee as u128 * gas_used_delta as u128 /
|
base_fee as u128 * gas_used_delta as u128 /
|
||||||
gas_target as u128 /
|
gas_target as u128 /
|
||||||
config::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
|
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
|
||||||
);
|
);
|
||||||
base_fee + (base_fee_delta as u64)
|
base_fee + (base_fee_delta as u64)
|
||||||
} else {
|
} else {
|
||||||
let gas_used_delta = gas_target - gas_used;
|
let gas_used_delta = gas_target - gas_used;
|
||||||
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
|
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
|
||||||
gas_target as u128 /
|
gas_target as u128 /
|
||||||
config::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
|
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
|
||||||
|
|
||||||
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
|
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
|
||||||
}
|
}
|
||||||
@ -236,7 +240,7 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6
|
|||||||
pub fn validate_header_regarding_parent(
|
pub fn validate_header_regarding_parent(
|
||||||
parent: &SealedHeader,
|
parent: &SealedHeader,
|
||||||
child: &SealedHeader,
|
child: &SealedHeader,
|
||||||
config: &config::Config,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Parent number is consistent.
|
// Parent number is consistent.
|
||||||
if parent.number + 1 != child.number {
|
if parent.number + 1 != child.number {
|
||||||
@ -255,7 +259,7 @@ pub fn validate_header_regarding_parent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// difficulty check is done by consensus.
|
// difficulty check is done by consensus.
|
||||||
if config.paris_block > child.number {
|
if chain_spec.paris_status().block_number() > Some(child.number) {
|
||||||
// TODO how this needs to be checked? As ice age did increment it by some formula
|
// TODO how this needs to be checked? As ice age did increment it by some formula
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,8 +267,8 @@ pub fn validate_header_regarding_parent(
|
|||||||
|
|
||||||
// By consensus, gas_limit is multiplied by elasticity (*2) on
|
// By consensus, gas_limit is multiplied by elasticity (*2) on
|
||||||
// on exact block that hardfork happens.
|
// on exact block that hardfork happens.
|
||||||
if config.london_block == child.number {
|
if chain_spec.fork_block(Hardfork::London) == Some(child.number) {
|
||||||
parent_gas_limit = parent.gas_limit * config::EIP1559_ELASTICITY_MULTIPLIER;
|
parent_gas_limit = parent.gas_limit * constants::EIP1559_ELASTICITY_MULTIPLIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check gas limit, max diff between child/parent gas_limit should be max_diff=parent_gas/1024
|
// Check gas limit, max diff between child/parent gas_limit should be max_diff=parent_gas/1024
|
||||||
@ -283,11 +287,11 @@ pub fn validate_header_regarding_parent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EIP-1559 check base fee
|
// EIP-1559 check base fee
|
||||||
if child.number >= config.london_block {
|
if chain_spec.fork_active(Hardfork::London, child.number) {
|
||||||
let base_fee = child.base_fee_per_gas.ok_or(Error::BaseFeeMissing)?;
|
let base_fee = child.base_fee_per_gas.ok_or(Error::BaseFeeMissing)?;
|
||||||
|
|
||||||
let expected_base_fee = if config.london_block == child.number {
|
let expected_base_fee = if chain_spec.fork_block(Hardfork::London) == Some(child.number) {
|
||||||
config::EIP1559_INITIAL_BASE_FEE
|
constants::EIP1559_INITIAL_BASE_FEE
|
||||||
} else {
|
} else {
|
||||||
// This BaseFeeMissing will not happen as previous blocks are checked to have them.
|
// This BaseFeeMissing will not happen as previous blocks are checked to have them.
|
||||||
calculate_next_block_base_fee(
|
calculate_next_block_base_fee(
|
||||||
@ -335,12 +339,12 @@ pub fn validate_block_regarding_chain<PROV: HeaderProvider>(
|
|||||||
pub fn full_validation<Provider: HeaderProvider + AccountProvider>(
|
pub fn full_validation<Provider: HeaderProvider + AccountProvider>(
|
||||||
block: &SealedBlock,
|
block: &SealedBlock,
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
) -> RethResult<()> {
|
) -> RethResult<()> {
|
||||||
validate_header_standalone(&block.header, config)?;
|
validate_header_standalone(&block.header, chain_spec)?;
|
||||||
validate_block_standalone(block)?;
|
validate_block_standalone(block)?;
|
||||||
let parent = validate_block_regarding_chain(block, &provider)?;
|
let parent = validate_block_regarding_chain(block, &provider)?;
|
||||||
validate_header_regarding_parent(&parent, &block.header, config)?;
|
validate_header_regarding_parent(&parent, &block.header, chain_spec)?;
|
||||||
|
|
||||||
// NOTE: depending on the need of the stages, recovery could be done in different place.
|
// NOTE: depending on the need of the stages, recovery could be done in different place.
|
||||||
let transactions = block
|
let transactions = block
|
||||||
@ -353,7 +357,7 @@ pub fn full_validation<Provider: HeaderProvider + AccountProvider>(
|
|||||||
transactions.iter(),
|
transactions.iter(),
|
||||||
&block.header,
|
&block.header,
|
||||||
provider,
|
provider,
|
||||||
config,
|
chain_spec,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -363,7 +367,7 @@ mod tests {
|
|||||||
use reth_interfaces::Result;
|
use reth_interfaces::Result;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
hex_literal::hex, Account, Address, BlockHash, Bytes, Header, Signature, TransactionKind,
|
hex_literal::hex, Account, Address, BlockHash, Bytes, Header, Signature, TransactionKind,
|
||||||
TransactionSigned,
|
TransactionSigned, MAINNET,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -495,19 +499,17 @@ mod tests {
|
|||||||
fn sanity_check() {
|
fn sanity_check() {
|
||||||
let (block, parent) = mock_block();
|
let (block, parent) = mock_block();
|
||||||
let provider = Provider::new(Some(parent));
|
let provider = Provider::new(Some(parent));
|
||||||
let config = Config::default();
|
|
||||||
|
|
||||||
assert_eq!(full_validation(&block, provider, &config), Ok(()), "Validation should pass");
|
assert_eq!(full_validation(&block, provider, &MAINNET), Ok(()), "Validation should pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_known_block() {
|
fn validate_known_block() {
|
||||||
let (block, _) = mock_block();
|
let (block, _) = mock_block();
|
||||||
let provider = Provider::new_known();
|
let provider = Provider::new_known();
|
||||||
let config = Config::default();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
full_validation(&block, provider, &config),
|
full_validation(&block, provider, &MAINNET),
|
||||||
Err(Error::BlockKnown { hash: block.hash(), number: block.number }.into()),
|
Err(Error::BlockKnown { hash: block.hash(), number: block.number }.into()),
|
||||||
"Should fail with error"
|
"Should fail with error"
|
||||||
);
|
);
|
||||||
@ -519,14 +521,13 @@ mod tests {
|
|||||||
let tx1 = mock_tx(0);
|
let tx1 = mock_tx(0);
|
||||||
let tx2 = mock_tx(1);
|
let tx2 = mock_tx(1);
|
||||||
let provider = Provider::new_known();
|
let provider = Provider::new_known();
|
||||||
let config = Config::default();
|
|
||||||
|
|
||||||
let txs = vec![tx1, tx2];
|
let txs = vec![tx1, tx2];
|
||||||
validate_all_transaction_regarding_block_and_nonces(
|
validate_all_transaction_regarding_block_and_nonces(
|
||||||
txs.iter(),
|
txs.iter(),
|
||||||
&block.header,
|
&block.header,
|
||||||
provider,
|
provider,
|
||||||
&config,
|
&MAINNET,
|
||||||
)
|
)
|
||||||
.expect("To Pass");
|
.expect("To Pass");
|
||||||
}
|
}
|
||||||
@ -536,7 +537,6 @@ mod tests {
|
|||||||
let (block, _) = mock_block();
|
let (block, _) = mock_block();
|
||||||
let tx1 = mock_tx(1);
|
let tx1 = mock_tx(1);
|
||||||
let provider = Provider::new_known();
|
let provider = Provider::new_known();
|
||||||
let config = Config::default();
|
|
||||||
|
|
||||||
let txs = vec![tx1];
|
let txs = vec![tx1];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -544,7 +544,7 @@ mod tests {
|
|||||||
txs.iter(),
|
txs.iter(),
|
||||||
&block.header,
|
&block.header,
|
||||||
provider,
|
provider,
|
||||||
&config,
|
&MAINNET,
|
||||||
),
|
),
|
||||||
Err(Error::TransactionNonceNotConsistent.into())
|
Err(Error::TransactionNonceNotConsistent.into())
|
||||||
)
|
)
|
||||||
@ -556,7 +556,6 @@ mod tests {
|
|||||||
let tx1 = mock_tx(0);
|
let tx1 = mock_tx(0);
|
||||||
let tx2 = mock_tx(3);
|
let tx2 = mock_tx(3);
|
||||||
let provider = Provider::new_known();
|
let provider = Provider::new_known();
|
||||||
let config = Config::default();
|
|
||||||
|
|
||||||
let txs = vec![tx1, tx2];
|
let txs = vec![tx1, tx2];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -564,7 +563,7 @@ mod tests {
|
|||||||
txs.iter(),
|
txs.iter(),
|
||||||
&block.header,
|
&block.header,
|
||||||
provider,
|
provider,
|
||||||
&config,
|
&MAINNET,
|
||||||
),
|
),
|
||||||
Err(Error::TransactionNonceNotConsistent.into())
|
Err(Error::TransactionNonceNotConsistent.into())
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
//! Reth block execution/validation configuration and constants
|
//! Reth block execution/validation configuration and constants
|
||||||
|
|
||||||
use reth_primitives::{BlockNumber, U256};
|
use reth_primitives::{BlockNumber, ChainSpec, Hardfork};
|
||||||
|
|
||||||
/// Two ethereum worth of wei
|
/// Two ethereum worth of wei
|
||||||
pub const WEI_2ETH: u128 = 2000000000000000000u128;
|
pub const WEI_2ETH: u128 = 2000000000000000000u128;
|
||||||
@ -9,188 +9,83 @@ pub const WEI_3ETH: u128 = 3000000000000000000u128;
|
|||||||
/// Five ethereum worth of wei
|
/// Five ethereum worth of wei
|
||||||
pub const WEI_5ETH: u128 = 5000000000000000000u128;
|
pub const WEI_5ETH: u128 = 5000000000000000000u128;
|
||||||
|
|
||||||
/// Configuration for executor
|
/// return revm_spec from spec configuration.
|
||||||
#[derive(Debug, Clone)]
|
pub fn revm_spec(chain_spec: &ChainSpec, for_block: BlockNumber) -> revm::SpecId {
|
||||||
pub struct Config {
|
match for_block {
|
||||||
/// Chain id.
|
b if chain_spec.fork_active(Hardfork::Shanghai, b) => revm::MERGE_EOF,
|
||||||
pub chain_id: U256,
|
b if Some(b) >= chain_spec.paris_status().block_number() => revm::MERGE,
|
||||||
/// Spec upgrades.
|
b if chain_spec.fork_active(Hardfork::London, b) => revm::LONDON,
|
||||||
pub spec_upgrades: SpecUpgrades,
|
b if chain_spec.fork_active(Hardfork::Berlin, b) => revm::BERLIN,
|
||||||
}
|
b if chain_spec.fork_active(Hardfork::Istanbul, b) => revm::ISTANBUL,
|
||||||
|
b if chain_spec.fork_active(Hardfork::Petersburg, b) => revm::PETERSBURG,
|
||||||
impl Config {
|
b if chain_spec.fork_active(Hardfork::Byzantium, b) => revm::BYZANTIUM,
|
||||||
/// Create new config for ethereum.
|
b if chain_spec.fork_active(Hardfork::SpuriousDragon, b) => revm::SPURIOUS_DRAGON,
|
||||||
pub fn new_ethereum() -> Self {
|
b if chain_spec.fork_active(Hardfork::Tangerine, b) => revm::TANGERINE,
|
||||||
Self { chain_id: U256::from(1), spec_upgrades: SpecUpgrades::new_ethereum() }
|
b if chain_spec.fork_active(Hardfork::Homestead, b) => revm::HOMESTEAD,
|
||||||
}
|
b if chain_spec.fork_active(Hardfork::Frontier, b) => revm::FRONTIER,
|
||||||
}
|
_ => panic!("wrong configuration"),
|
||||||
|
|
||||||
/// Spec with there ethereum codenames.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub struct SpecUpgrades {
|
|
||||||
pub frontier: BlockNumber,
|
|
||||||
//pub frontier_thawing: BlockNumber,
|
|
||||||
pub homestead: BlockNumber,
|
|
||||||
pub dao_fork: BlockNumber,
|
|
||||||
pub tangerine_whistle: BlockNumber,
|
|
||||||
pub spurious_dragon: BlockNumber,
|
|
||||||
pub byzantium: BlockNumber,
|
|
||||||
//pub constantinople: BlockNumber,
|
|
||||||
pub petersburg: BlockNumber, //Overrider Constantinople
|
|
||||||
pub istanbul: BlockNumber,
|
|
||||||
//pub muir_glacier: BlockNumber,
|
|
||||||
pub berlin: BlockNumber,
|
|
||||||
pub london: BlockNumber,
|
|
||||||
//pub arrow_glacier: BlockNumber,
|
|
||||||
//pub gray_glacier: BlockNumber,
|
|
||||||
pub paris: BlockNumber, // Aka the merge
|
|
||||||
pub shanghai: BlockNumber,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpecUpgrades {
|
|
||||||
/// After merge/peric block reward was removed from execution layer.
|
|
||||||
pub fn has_block_reward(&self, block_num: BlockNumber) -> bool {
|
|
||||||
block_num < self.paris
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ethereum mainnet spec
|
|
||||||
pub fn new_ethereum() -> Self {
|
|
||||||
Self {
|
|
||||||
frontier: 0,
|
|
||||||
//frontier_thawing: 200000,
|
|
||||||
homestead: 1150000,
|
|
||||||
dao_fork: 1920000,
|
|
||||||
tangerine_whistle: 2463000,
|
|
||||||
spurious_dragon: 2675000,
|
|
||||||
byzantium: 4370000,
|
|
||||||
//constantinople: 7280000,
|
|
||||||
petersburg: 7280000, //Overrider Constantinople
|
|
||||||
istanbul: 9069000,
|
|
||||||
//muir_glacier: 9200000,
|
|
||||||
berlin: 12244000,
|
|
||||||
london: 12965000,
|
|
||||||
//arrow_glacier: 13773000,
|
|
||||||
//gray_glacier: 15050000,
|
|
||||||
paris: 15537394, // TheMerge,
|
|
||||||
shanghai: u64::MAX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New frontier enabled spec
|
|
||||||
pub fn new_frontier_activated() -> Self {
|
|
||||||
Self {
|
|
||||||
frontier: 0,
|
|
||||||
homestead: u64::MAX,
|
|
||||||
dao_fork: u64::MAX,
|
|
||||||
tangerine_whistle: u64::MAX,
|
|
||||||
spurious_dragon: u64::MAX,
|
|
||||||
byzantium: u64::MAX,
|
|
||||||
petersburg: u64::MAX,
|
|
||||||
istanbul: u64::MAX,
|
|
||||||
berlin: u64::MAX,
|
|
||||||
london: u64::MAX,
|
|
||||||
paris: u64::MAX,
|
|
||||||
shanghai: u64::MAX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New homestead enabled spec
|
|
||||||
pub fn new_homestead_activated() -> Self {
|
|
||||||
Self { homestead: 0, ..Self::new_frontier_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New tangerine enabled spec
|
|
||||||
pub fn new_tangerine_whistle_activated() -> Self {
|
|
||||||
Self { tangerine_whistle: 0, ..Self::new_homestead_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New spurious_dragon enabled spec
|
|
||||||
pub fn new_spurious_dragon_activated() -> Self {
|
|
||||||
Self { spurious_dragon: 0, ..Self::new_tangerine_whistle_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New byzantium enabled spec
|
|
||||||
pub fn new_byzantium_activated() -> Self {
|
|
||||||
Self { byzantium: 0, ..Self::new_spurious_dragon_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New petersburg enabled spec
|
|
||||||
pub fn new_petersburg_activated() -> Self {
|
|
||||||
Self { petersburg: 0, ..Self::new_byzantium_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New istanbul enabled spec
|
|
||||||
pub fn new_istanbul_activated() -> Self {
|
|
||||||
Self { istanbul: 0, ..Self::new_petersburg_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New berlin enabled spec
|
|
||||||
pub fn new_berlin_activated() -> Self {
|
|
||||||
Self { berlin: 0, ..Self::new_istanbul_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New london enabled spec
|
|
||||||
pub fn new_london_activated() -> Self {
|
|
||||||
Self { london: 0, ..Self::new_berlin_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New paris enabled spec
|
|
||||||
pub fn new_paris_activated() -> Self {
|
|
||||||
Self { paris: 0, ..Self::new_london_activated() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// return revm_spec from spec configuration.
|
|
||||||
pub fn revm_spec(&self, for_block: BlockNumber) -> revm::SpecId {
|
|
||||||
match for_block {
|
|
||||||
b if b >= self.shanghai => revm::MERGE_EOF,
|
|
||||||
b if b >= self.paris => revm::MERGE,
|
|
||||||
b if b >= self.london => revm::LONDON,
|
|
||||||
b if b >= self.berlin => revm::BERLIN,
|
|
||||||
b if b >= self.istanbul => revm::ISTANBUL,
|
|
||||||
b if b >= self.petersburg => revm::PETERSBURG,
|
|
||||||
b if b >= self.byzantium => revm::BYZANTIUM,
|
|
||||||
b if b >= self.spurious_dragon => revm::SPURIOUS_DRAGON,
|
|
||||||
b if b >= self.tangerine_whistle => revm::TANGERINE,
|
|
||||||
b if b >= self.homestead => revm::HOMESTEAD,
|
|
||||||
b if b >= self.frontier => revm::FRONTIER,
|
|
||||||
_ => panic!("wrong configuration"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::SpecUpgrades;
|
use crate::config::revm_spec;
|
||||||
|
use reth_primitives::{ChainSpecBuilder, MAINNET};
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_revm_spec() {
|
fn test_to_revm_spec() {
|
||||||
assert_eq!(SpecUpgrades::new_paris_activated().revm_spec(1), revm::MERGE);
|
|
||||||
assert_eq!(SpecUpgrades::new_london_activated().revm_spec(1), revm::LONDON);
|
|
||||||
assert_eq!(SpecUpgrades::new_berlin_activated().revm_spec(1), revm::BERLIN);
|
|
||||||
assert_eq!(SpecUpgrades::new_istanbul_activated().revm_spec(1), revm::ISTANBUL);
|
|
||||||
assert_eq!(SpecUpgrades::new_petersburg_activated().revm_spec(1), revm::PETERSBURG);
|
|
||||||
assert_eq!(SpecUpgrades::new_byzantium_activated().revm_spec(1), revm::BYZANTIUM);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
SpecUpgrades::new_spurious_dragon_activated().revm_spec(1),
|
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), 1),
|
||||||
|
revm::MERGE
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), 1),
|
||||||
|
revm::LONDON
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), 1),
|
||||||
|
revm::BERLIN
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), 1),
|
||||||
|
revm::ISTANBUL
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), 1),
|
||||||
|
revm::PETERSBURG
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), 1),
|
||||||
|
revm::BYZANTIUM
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(), 1),
|
||||||
revm::SPURIOUS_DRAGON
|
revm::SPURIOUS_DRAGON
|
||||||
);
|
);
|
||||||
assert_eq!(SpecUpgrades::new_tangerine_whistle_activated().revm_spec(1), revm::TANGERINE);
|
assert_eq!(
|
||||||
assert_eq!(SpecUpgrades::new_homestead_activated().revm_spec(1), revm::HOMESTEAD);
|
revm_spec(&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(), 1),
|
||||||
assert_eq!(SpecUpgrades::new_frontier_activated().revm_spec(1), revm::FRONTIER);
|
revm::TANGERINE
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), 1),
|
||||||
|
revm::HOMESTEAD
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), 1),
|
||||||
|
revm::FRONTIER
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eth_spec() {
|
fn test_eth_spec() {
|
||||||
let spec = SpecUpgrades::new_ethereum();
|
assert_eq!(revm_spec(&MAINNET, 15537394 + 10), revm::MERGE);
|
||||||
assert_eq!(spec.revm_spec(15537394 + 10), revm::MERGE);
|
assert_eq!(revm_spec(&MAINNET, 15537394 - 10), revm::LONDON);
|
||||||
assert_eq!(spec.revm_spec(15537394 - 10), revm::LONDON);
|
assert_eq!(revm_spec(&MAINNET, 12244000 + 10), revm::BERLIN);
|
||||||
assert_eq!(spec.revm_spec(12244000 + 10), revm::BERLIN);
|
assert_eq!(revm_spec(&MAINNET, 12244000 - 10), revm::ISTANBUL);
|
||||||
assert_eq!(spec.revm_spec(12244000 - 10), revm::ISTANBUL);
|
assert_eq!(revm_spec(&MAINNET, 7280000 + 10), revm::PETERSBURG);
|
||||||
assert_eq!(spec.revm_spec(7280000 + 10), revm::PETERSBURG);
|
assert_eq!(revm_spec(&MAINNET, 7280000 - 10), revm::BYZANTIUM);
|
||||||
assert_eq!(spec.revm_spec(7280000 - 10), revm::BYZANTIUM);
|
assert_eq!(revm_spec(&MAINNET, 2675000 + 10), revm::SPURIOUS_DRAGON);
|
||||||
assert_eq!(spec.revm_spec(2675000 + 10), revm::SPURIOUS_DRAGON);
|
assert_eq!(revm_spec(&MAINNET, 2675000 - 10), revm::TANGERINE);
|
||||||
assert_eq!(spec.revm_spec(2675000 - 10), revm::TANGERINE);
|
assert_eq!(revm_spec(&MAINNET, 1150000 + 10), revm::HOMESTEAD);
|
||||||
assert_eq!(spec.revm_spec(1150000 + 10), revm::HOMESTEAD);
|
assert_eq!(revm_spec(&MAINNET, 1150000 - 10), revm::FRONTIER);
|
||||||
assert_eq!(spec.revm_spec(1150000 - 10), revm::FRONTIER);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{WEI_2ETH, WEI_3ETH, WEI_5ETH},
|
config::{revm_spec, WEI_2ETH, WEI_3ETH, WEI_5ETH},
|
||||||
revm_wrap::{self, to_reth_acc, SubState},
|
revm_wrap::{self, to_reth_acc, SubState},
|
||||||
Config,
|
|
||||||
};
|
};
|
||||||
use hashbrown::hash_map::Entry;
|
use hashbrown::hash_map::Entry;
|
||||||
use reth_db::{models::AccountBeforeTx, tables, transaction::DbTxMut, Error as DbError};
|
use reth_db::{models::AccountBeforeTx, tables, transaction::DbTxMut, Error as DbError};
|
||||||
use reth_interfaces::executor::Error;
|
use reth_interfaces::executor::Error;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
bloom::logs_bloom, Account, Address, Bloom, Header, Log, Receipt, TransactionSignedEcRecovered,
|
bloom::logs_bloom, Account, Address, Bloom, ChainSpec, Hardfork, Header, Log, Receipt,
|
||||||
H160, H256, U256,
|
TransactionSignedEcRecovered, H160, H256, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::StateProvider;
|
use reth_provider::StateProvider;
|
||||||
use revm::{
|
use revm::{
|
||||||
@ -18,10 +17,7 @@ use revm::{
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
/// Main block executor
|
/// Main block executor
|
||||||
pub struct Executor {
|
pub struct Executor {}
|
||||||
/// Configuration, Spec and optional flags.
|
|
||||||
pub config: Config,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Contains old/new account changes
|
/// Contains old/new account changes
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
@ -250,15 +246,15 @@ pub fn execute_and_verify_receipt<DB: StateProvider>(
|
|||||||
header: &Header,
|
header: &Header,
|
||||||
transactions: &[TransactionSignedEcRecovered],
|
transactions: &[TransactionSignedEcRecovered],
|
||||||
ommers: &[Header],
|
ommers: &[Header],
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
db: &mut SubState<DB>,
|
db: &mut SubState<DB>,
|
||||||
) -> Result<ExecutionResult, Error> {
|
) -> Result<ExecutionResult, Error> {
|
||||||
let transaction_change_set = execute(header, transactions, ommers, config, db)?;
|
let transaction_change_set = execute(header, transactions, ommers, chain_spec, db)?;
|
||||||
|
|
||||||
let receipts_iter =
|
let receipts_iter =
|
||||||
transaction_change_set.changesets.iter().map(|changeset| &changeset.receipt);
|
transaction_change_set.changesets.iter().map(|changeset| &changeset.receipt);
|
||||||
|
|
||||||
if header.number >= config.spec_upgrades.byzantium {
|
if Some(header.number) >= chain_spec.fork_block(Hardfork::Byzantium) {
|
||||||
verify_receipt(header.receipts_root, header.logs_bloom, receipts_iter)?;
|
verify_receipt(header.receipts_root, header.logs_bloom, receipts_iter)?;
|
||||||
}
|
}
|
||||||
// TODO Before Byzantium, receipts contained state root that would mean that expensive operation
|
// TODO Before Byzantium, receipts contained state root that would mean that expensive operation
|
||||||
@ -300,15 +296,15 @@ pub fn execute<DB: StateProvider>(
|
|||||||
header: &Header,
|
header: &Header,
|
||||||
transactions: &[TransactionSignedEcRecovered],
|
transactions: &[TransactionSignedEcRecovered],
|
||||||
ommers: &[Header],
|
ommers: &[Header],
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
db: &mut SubState<DB>,
|
db: &mut SubState<DB>,
|
||||||
) -> Result<ExecutionResult, Error> {
|
) -> Result<ExecutionResult, Error> {
|
||||||
let mut evm = EVM::new();
|
let mut evm = EVM::new();
|
||||||
evm.database(db);
|
evm.database(db);
|
||||||
|
|
||||||
let spec_id = config.spec_upgrades.revm_spec(header.number);
|
let spec_id = revm_spec(chain_spec, header.number);
|
||||||
evm.env.cfg.chain_id = config.chain_id;
|
evm.env.cfg.chain_id = U256::from(chain_spec.chain().id());
|
||||||
evm.env.cfg.spec_id = config.spec_upgrades.revm_spec(header.number);
|
evm.env.cfg.spec_id = spec_id;
|
||||||
evm.env.cfg.perf_all_precompiles_have_balance = false;
|
evm.env.cfg.perf_all_precompiles_have_balance = false;
|
||||||
evm.env.cfg.perf_analyse_created_bytecodes = AnalysisKind::Raw;
|
evm.env.cfg.perf_analyse_created_bytecodes = AnalysisKind::Raw;
|
||||||
|
|
||||||
@ -393,9 +389,9 @@ pub fn execute<DB: StateProvider>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let db = evm.db.expect("Db is set at the start of the function");
|
let db = evm.db.expect("Db is set at the start of the function");
|
||||||
let mut block_reward = block_reward_changeset(header, ommers, db, config)?;
|
let mut block_reward = block_reward_changeset(header, ommers, db, chain_spec)?;
|
||||||
|
|
||||||
if config.spec_upgrades.dao_fork == header.number {
|
if chain_spec.fork_block(Hardfork::Dao) == Some(header.number) {
|
||||||
let mut irregular_state_changeset = dao_fork_changeset(db)?;
|
let mut irregular_state_changeset = dao_fork_changeset(db)?;
|
||||||
irregular_state_changeset.extend(block_reward.take().unwrap_or_default().into_iter());
|
irregular_state_changeset.extend(block_reward.take().unwrap_or_default().into_iter());
|
||||||
block_reward = Some(irregular_state_changeset);
|
block_reward = Some(irregular_state_changeset);
|
||||||
@ -444,7 +440,7 @@ pub fn block_reward_changeset<DB: StateProvider>(
|
|||||||
header: &Header,
|
header: &Header,
|
||||||
ommers: &[Header],
|
ommers: &[Header],
|
||||||
db: &mut SubState<DB>,
|
db: &mut SubState<DB>,
|
||||||
config: &Config,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<Option<BTreeMap<H160, AccountInfoChangeSet>>, Error> {
|
) -> Result<Option<BTreeMap<H160, AccountInfoChangeSet>>, Error> {
|
||||||
// NOTE: Related to Ethereum reward change, for other network this is probably going to be moved
|
// NOTE: Related to Ethereum reward change, for other network this is probably going to be moved
|
||||||
// to config.
|
// to config.
|
||||||
@ -456,9 +452,9 @@ pub fn block_reward_changeset<DB: StateProvider>(
|
|||||||
// block’s beneficiary by an additional 1/32 of the block reward and the beneficiary of the
|
// block’s beneficiary by an additional 1/32 of the block reward and the beneficiary of the
|
||||||
// ommer gets rewarded depending on the blocknumber. Formally we define the function Ω:
|
// ommer gets rewarded depending on the blocknumber. Formally we define the function Ω:
|
||||||
match header.number {
|
match header.number {
|
||||||
n if n >= config.spec_upgrades.paris => None,
|
n if Some(n) >= chain_spec.paris_status().block_number() => None,
|
||||||
n if n >= config.spec_upgrades.petersburg => Some(WEI_2ETH),
|
n if Some(n) >= chain_spec.fork_block(Hardfork::Petersburg) => Some(WEI_2ETH),
|
||||||
n if n >= config.spec_upgrades.byzantium => Some(WEI_3ETH),
|
n if Some(n) >= chain_spec.fork_block(Hardfork::Byzantium) => Some(WEI_3ETH),
|
||||||
_ => Some(WEI_5ETH),
|
_ => Some(WEI_5ETH),
|
||||||
}
|
}
|
||||||
.map(|reward| -> Result<_, _> {
|
.map(|reward| -> Result<_, _> {
|
||||||
@ -535,15 +531,15 @@ mod tests {
|
|||||||
|
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::{config::SpecUpgrades, revm_wrap::State};
|
use crate::revm_wrap::State;
|
||||||
use reth_db::{
|
use reth_db::{
|
||||||
database::Database,
|
database::Database,
|
||||||
mdbx::{test_utils, Env, EnvKind, WriteMap},
|
mdbx::{test_utils, Env, EnvKind, WriteMap},
|
||||||
transaction::DbTx,
|
transaction::DbTx,
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
hex_literal::hex, keccak256, Account, Address, Bytes, SealedBlock, StorageKey, H160, H256,
|
hex_literal::hex, keccak256, Account, Address, Bytes, ChainSpecBuilder, SealedBlock,
|
||||||
U256,
|
StorageKey, H160, H256, MAINNET, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{AccountProvider, BlockHashProvider, StateProvider};
|
use reth_provider::{AccountProvider, BlockHashProvider, StateProvider};
|
||||||
use reth_rlp::Decodable;
|
use reth_rlp::Decodable;
|
||||||
@ -648,9 +644,8 @@ mod tests {
|
|||||||
HashMap::new(),
|
HashMap::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut config = Config::new_ethereum();
|
// spec at berlin fork
|
||||||
// make it berlin fork
|
let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build();
|
||||||
config.spec_upgrades = SpecUpgrades::new_berlin_activated();
|
|
||||||
|
|
||||||
let mut db = SubState::new(State::new(db));
|
let mut db = SubState::new(State::new(db));
|
||||||
let transactions: Vec<TransactionSignedEcRecovered> =
|
let transactions: Vec<TransactionSignedEcRecovered> =
|
||||||
@ -658,7 +653,7 @@ mod tests {
|
|||||||
|
|
||||||
// execute chain and verify receipts
|
// execute chain and verify receipts
|
||||||
let out =
|
let out =
|
||||||
execute_and_verify_receipt(&block.header, &transactions, &ommers, &config, &mut db)
|
execute_and_verify_receipt(&block.header, &transactions, &ommers, &chain_spec, &mut db)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(out.changesets.len(), 1, "Should executed one transaction");
|
assert_eq!(out.changesets.len(), 1, "Should executed one transaction");
|
||||||
@ -779,14 +774,14 @@ mod tests {
|
|||||||
beneficiary_balance += i;
|
beneficiary_balance += i;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut config = Config::new_ethereum();
|
let chain_spec = ChainSpecBuilder::from(&*MAINNET)
|
||||||
config.spec_upgrades = SpecUpgrades::new_homestead_activated();
|
.homestead_activated()
|
||||||
// hardcode it to first block to match our mock data.
|
.with_fork(Hardfork::Dao, 1)
|
||||||
config.spec_upgrades.dao_fork = 1;
|
.build();
|
||||||
|
|
||||||
let mut db = SubState::new(State::new(db));
|
let mut db = SubState::new(State::new(db));
|
||||||
// execute chain and verify receipts
|
// execute chain and verify receipts
|
||||||
let out = execute_and_verify_receipt(&header, &[], &[], &config, &mut db).unwrap();
|
let out = execute_and_verify_receipt(&header, &[], &[], &chain_spec, &mut db).unwrap();
|
||||||
assert_eq!(out.changesets.len(), 0, "No tx");
|
assert_eq!(out.changesets.len(), 0, "No tx");
|
||||||
|
|
||||||
// Check if cache is set
|
// Check if cache is set
|
||||||
|
|||||||
@ -8,9 +8,8 @@
|
|||||||
//! Reth executor executes transaction in block of data.
|
//! Reth executor executes transaction in block of data.
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod eth_dao_fork;
|
||||||
/// Executor
|
/// Executor
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
/// Wrapper around revm database and types
|
/// Wrapper around revm database and types
|
||||||
pub mod revm_wrap;
|
pub mod revm_wrap;
|
||||||
pub use config::{Config, SpecUpgrades};
|
|
||||||
pub mod eth_dao_fork;
|
|
||||||
|
|||||||
@ -402,7 +402,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::tree::TreeRootEntry;
|
use crate::tree::TreeRootEntry;
|
||||||
use enr::{EnrBuilder, EnrKey};
|
use enr::{EnrBuilder, EnrKey};
|
||||||
use reth_primitives::{Chain, Hardfork};
|
use reth_primitives::{Chain, Hardfork, MAINNET};
|
||||||
use reth_rlp::Encodable;
|
use reth_rlp::Encodable;
|
||||||
use secp256k1::rand::thread_rng;
|
use secp256k1::rand::thread_rng;
|
||||||
use std::{future::poll_fn, net::Ipv4Addr};
|
use std::{future::poll_fn, net::Ipv4Addr};
|
||||||
@ -452,7 +452,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut builder = EnrBuilder::new("v4");
|
let mut builder = EnrBuilder::new("v4");
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let fork_id = Hardfork::Frontier.fork_id();
|
let fork_id = Hardfork::Frontier.fork_id(&MAINNET).unwrap();
|
||||||
fork_id.encode(&mut buf);
|
fork_id.encode(&mut buf);
|
||||||
builder.ip4(Ipv4Addr::LOCALHOST).udp4(30303).tcp4(30303).add_value(b"eth", &buf);
|
builder.ip4(Ipv4Addr::LOCALHOST).udp4(30303).tcp4(30303).add_value(b"eth", &buf);
|
||||||
let enr = builder.build(&secret_key).unwrap();
|
let enr = builder.build(&secret_key).unwrap();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{EthVersion, StatusBuilder};
|
use crate::{EthVersion, StatusBuilder};
|
||||||
|
|
||||||
use reth_codecs::derive_arbitrary;
|
use reth_codecs::derive_arbitrary;
|
||||||
use reth_primitives::{Chain, ForkId, Hardfork, H256, MAINNET_GENESIS, U256};
|
use reth_primitives::{Chain, ForkId, Hardfork, H256, MAINNET, U256};
|
||||||
use reth_rlp::{RlpDecodable, RlpEncodable};
|
use reth_rlp::{RlpDecodable, RlpEncodable};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
@ -100,9 +100,11 @@ impl Default for Status {
|
|||||||
version: EthVersion::Eth67 as u8,
|
version: EthVersion::Eth67 as u8,
|
||||||
chain: Chain::Named(ethers_core::types::Chain::Mainnet),
|
chain: Chain::Named(ethers_core::types::Chain::Mainnet),
|
||||||
total_difficulty: U256::from(17_179_869_184u64),
|
total_difficulty: U256::from(17_179_869_184u64),
|
||||||
blockhash: MAINNET_GENESIS,
|
blockhash: MAINNET.genesis_hash(),
|
||||||
genesis: MAINNET_GENESIS,
|
genesis: MAINNET.genesis_hash(),
|
||||||
forkid: Hardfork::Frontier.fork_id(),
|
forkid: Hardfork::Frontier
|
||||||
|
.fork_id(&MAINNET)
|
||||||
|
.expect("The Frontier hardfork should always exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use crate::{
|
|||||||
NetworkHandle, NetworkManager,
|
NetworkHandle, NetworkManager,
|
||||||
};
|
};
|
||||||
use reth_discv4::{Discv4Config, Discv4ConfigBuilder, DEFAULT_DISCOVERY_PORT};
|
use reth_discv4::{Discv4Config, Discv4ConfigBuilder, DEFAULT_DISCOVERY_PORT};
|
||||||
use reth_primitives::{Chain, ForkFilter, Hardfork, NodeRecord, PeerId, H256, MAINNET_GENESIS};
|
use reth_primitives::{ChainSpec, ForkFilter, NodeRecord, PeerId, MAINNET};
|
||||||
use reth_provider::{BlockProvider, HeaderProvider};
|
use reth_provider::{BlockProvider, HeaderProvider};
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use secp256k1::{SecretKey, SECP256K1};
|
use secp256k1::{SecretKey, SECP256K1};
|
||||||
@ -54,10 +54,8 @@ pub struct NetworkConfig<C> {
|
|||||||
pub peers_config: PeersConfig,
|
pub peers_config: PeersConfig,
|
||||||
/// How to configure the [SessionManager](crate::session::SessionManager).
|
/// How to configure the [SessionManager](crate::session::SessionManager).
|
||||||
pub sessions_config: SessionsConfig,
|
pub sessions_config: SessionsConfig,
|
||||||
/// The id of the network
|
/// The chain spec
|
||||||
pub chain: Chain,
|
pub chain_spec: ChainSpec,
|
||||||
/// Genesis hash of the network
|
|
||||||
pub genesis_hash: H256,
|
|
||||||
/// The [`ForkFilter`] to use at launch for authenticating sessions.
|
/// The [`ForkFilter`] to use at launch for authenticating sessions.
|
||||||
///
|
///
|
||||||
/// See also <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2124.md#stale-software-examples>
|
/// See also <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2124.md#stale-software-examples>
|
||||||
@ -141,10 +139,8 @@ pub struct NetworkConfigBuilder<C> {
|
|||||||
peers_config: Option<PeersConfig>,
|
peers_config: Option<PeersConfig>,
|
||||||
/// How to configure the sessions manager
|
/// How to configure the sessions manager
|
||||||
sessions_config: Option<SessionsConfig>,
|
sessions_config: Option<SessionsConfig>,
|
||||||
/// The network's chain id
|
/// The network's chain spec
|
||||||
chain: Chain,
|
chain_spec: ChainSpec,
|
||||||
/// Network genesis hash
|
|
||||||
genesis_hash: H256,
|
|
||||||
/// The block importer type.
|
/// The block importer type.
|
||||||
block_import: Box<dyn BlockImport>,
|
block_import: Box<dyn BlockImport>,
|
||||||
/// The default mode of the network.
|
/// The default mode of the network.
|
||||||
@ -176,8 +172,7 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
listener_addr: None,
|
listener_addr: None,
|
||||||
peers_config: None,
|
peers_config: None,
|
||||||
sessions_config: None,
|
sessions_config: None,
|
||||||
chain: Chain::Named(reth_primitives::rpc::Chain::Mainnet),
|
chain_spec: MAINNET.clone(),
|
||||||
genesis_hash: MAINNET_GENESIS,
|
|
||||||
block_import: Box::<ProofOfStakeBlockImport>::default(),
|
block_import: Box::<ProofOfStakeBlockImport>::default(),
|
||||||
network_mode: Default::default(),
|
network_mode: Default::default(),
|
||||||
executor: None,
|
executor: None,
|
||||||
@ -209,9 +204,9 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the chain ID.
|
/// Sets the chain spec.
|
||||||
pub fn chain_id<Id: Into<Chain>>(mut self, chain_id: Id) -> Self {
|
pub fn chain_spec(mut self, chain_spec: ChainSpec) -> Self {
|
||||||
self.chain = chain_id.into();
|
self.chain_spec = chain_spec;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,12 +245,6 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the genesis hash for the network.
|
|
||||||
pub fn genesis_hash(mut self, genesis_hash: H256) -> Self {
|
|
||||||
self.genesis_hash = genesis_hash;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the [`BlockImport`] type to configure.
|
/// Sets the [`BlockImport`] type to configure.
|
||||||
pub fn block_import<T: BlockImport + 'static>(mut self, block_import: T) -> Self {
|
pub fn block_import<T: BlockImport + 'static>(mut self, block_import: T) -> Self {
|
||||||
self.block_import = Box::new(block_import);
|
self.block_import = Box::new(block_import);
|
||||||
@ -318,8 +307,7 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
listener_addr,
|
listener_addr,
|
||||||
peers_config,
|
peers_config,
|
||||||
sessions_config,
|
sessions_config,
|
||||||
chain,
|
chain_spec,
|
||||||
genesis_hash,
|
|
||||||
block_import,
|
block_import,
|
||||||
network_mode,
|
network_mode,
|
||||||
executor,
|
executor,
|
||||||
@ -340,8 +328,7 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
// get the fork filter
|
// get the fork filter
|
||||||
let fork_filter = fork_filter.unwrap_or_else(|| {
|
let fork_filter = fork_filter.unwrap_or_else(|| {
|
||||||
let head = head.unwrap_or_default();
|
let head = head.unwrap_or_default();
|
||||||
// TODO(mattsse): this should be chain agnostic: <https://github.com/paradigmxyz/reth/issues/485>
|
chain_spec.fork_filter(head)
|
||||||
ForkFilter::new(head, genesis_hash, Hardfork::all_forks())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// If default DNS config is used then we add the known dns network to bootstrap from
|
// If default DNS config is used then we add the known dns network to bootstrap from
|
||||||
@ -349,7 +336,7 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
dns_discovery_config.as_mut().and_then(|c| c.bootstrap_dns_networks.as_mut())
|
dns_discovery_config.as_mut().and_then(|c| c.bootstrap_dns_networks.as_mut())
|
||||||
{
|
{
|
||||||
if dns_networks.is_empty() {
|
if dns_networks.is_empty() {
|
||||||
if let Some(link) = chain.public_dns_network_protocol() {
|
if let Some(link) = chain_spec.chain().public_dns_network_protocol() {
|
||||||
dns_networks.insert(link.parse().expect("is valid DNS link entry"));
|
dns_networks.insert(link.parse().expect("is valid DNS link entry"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,8 +354,7 @@ impl<C> NetworkConfigBuilder<C> {
|
|||||||
listener_addr,
|
listener_addr,
|
||||||
peers_config: peers_config.unwrap_or_default(),
|
peers_config: peers_config.unwrap_or_default(),
|
||||||
sessions_config: sessions_config.unwrap_or_default(),
|
sessions_config: sessions_config.unwrap_or_default(),
|
||||||
chain,
|
chain_spec,
|
||||||
genesis_hash,
|
|
||||||
block_import,
|
block_import,
|
||||||
network_mode,
|
network_mode,
|
||||||
executor,
|
executor,
|
||||||
@ -407,6 +393,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use reth_dns_discovery::tree::LinkEntry;
|
use reth_dns_discovery::tree::LinkEntry;
|
||||||
|
use reth_primitives::Chain;
|
||||||
use reth_provider::test_utils::NoopProvider;
|
use reth_provider::test_utils::NoopProvider;
|
||||||
|
|
||||||
fn builder() -> NetworkConfigBuilder<NoopProvider> {
|
fn builder() -> NetworkConfigBuilder<NoopProvider> {
|
||||||
|
|||||||
@ -153,7 +153,7 @@ where
|
|||||||
listener_addr,
|
listener_addr,
|
||||||
peers_config,
|
peers_config,
|
||||||
sessions_config,
|
sessions_config,
|
||||||
genesis_hash,
|
chain_spec,
|
||||||
block_import,
|
block_import,
|
||||||
network_mode,
|
network_mode,
|
||||||
boot_nodes,
|
boot_nodes,
|
||||||
@ -196,11 +196,12 @@ where
|
|||||||
fork_filter,
|
fork_filter,
|
||||||
bandwidth_meter.clone(),
|
bandwidth_meter.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let state = NetworkState::new(
|
let state = NetworkState::new(
|
||||||
client,
|
client,
|
||||||
discovery,
|
discovery,
|
||||||
peers_manager,
|
peers_manager,
|
||||||
genesis_hash,
|
chain_spec.genesis_hash(),
|
||||||
Arc::clone(&num_active_peers),
|
Arc::clone(&num_active_peers),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -568,7 +568,7 @@ mod tests {
|
|||||||
StatusBuilder, UnauthedEthStream, UnauthedP2PStream,
|
StatusBuilder, UnauthedEthStream, UnauthedP2PStream,
|
||||||
};
|
};
|
||||||
use reth_net_common::bandwidth_meter::BandwidthMeter;
|
use reth_net_common::bandwidth_meter::BandwidthMeter;
|
||||||
use reth_primitives::{ForkFilter, Hardfork};
|
use reth_primitives::{ForkFilter, Hardfork, MAINNET};
|
||||||
use secp256k1::{SecretKey, SECP256K1};
|
use secp256k1::{SecretKey, SECP256K1};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
@ -714,7 +714,9 @@ mod tests {
|
|||||||
secret_key,
|
secret_key,
|
||||||
local_peer_id,
|
local_peer_id,
|
||||||
status: StatusBuilder::default().build(),
|
status: StatusBuilder::default().build(),
|
||||||
fork_filter: Hardfork::Frontier.fork_filter(),
|
fork_filter: Hardfork::Frontier
|
||||||
|
.fork_filter(&MAINNET)
|
||||||
|
.expect("The Frontier fork filter should exist on mainnet"),
|
||||||
bandwidth_meter: BandwidthMeter::default(),
|
bandwidth_meter: BandwidthMeter::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,9 @@ reth-rlp = { path = "../common/rlp", features = [
|
|||||||
reth-rlp-derive = { path = "../common/rlp-derive" }
|
reth-rlp-derive = { path = "../common/rlp-derive" }
|
||||||
reth-codecs = { version = "0.1.0", path = "../storage/codecs" }
|
reth-codecs = { version = "0.1.0", path = "../storage/codecs" }
|
||||||
|
|
||||||
revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "a05fb262d87c78ee52d400e6c0f4708d4c527f32", features = ["serde"] }
|
revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "a05fb262d87c78ee52d400e6c0f4708d4c527f32", features = [
|
||||||
|
"serde",
|
||||||
|
] }
|
||||||
|
|
||||||
# ethereum
|
# ethereum
|
||||||
ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = false }
|
ethers-core = { git = "https://github.com/gakonst/ethers-rs", default-features = false }
|
||||||
@ -42,6 +44,7 @@ crc = "1"
|
|||||||
# misc
|
# misc
|
||||||
bytes = "1.2"
|
bytes = "1.2"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
serde_with = "2.1.0"
|
serde_with = "2.1.0"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
sucds = "0.5.0"
|
sucds = "0.5.0"
|
||||||
@ -51,6 +54,7 @@ modular-bitfield = "0.11.2"
|
|||||||
derive_more = "0.99"
|
derive_more = "0.99"
|
||||||
url = "2.3"
|
url = "2.3"
|
||||||
impl-serde = "0.4.0"
|
impl-serde = "0.4.0"
|
||||||
|
once_cell = "1.17.0"
|
||||||
|
|
||||||
# proof related
|
# proof related
|
||||||
triehash = "0.8"
|
triehash = "0.8"
|
||||||
@ -69,7 +73,10 @@ serde_json = "1.0"
|
|||||||
hex-literal = "0.3"
|
hex-literal = "0.3"
|
||||||
test-fuzz = "3.0.4"
|
test-fuzz = "3.0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "a05fb262d87c78ee52d400e6c0f4708d4c527f32", features = ["serde", "arbitrary"] }
|
revm-interpreter = { git = "https://github.com/bluealloy/revm", rev = "a05fb262d87c78ee52d400e6c0f4708d4c527f32", features = [
|
||||||
|
"serde",
|
||||||
|
"arbitrary",
|
||||||
|
] }
|
||||||
|
|
||||||
arbitrary = { version = "1.1.7", features = ["derive"] }
|
arbitrary = { version = "1.1.7", features = ["derive"] }
|
||||||
proptest = { version = "1.0" }
|
proptest = { version = "1.0" }
|
||||||
@ -82,7 +89,12 @@ criterion = "0.4.0"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
arbitrary = ["revm-interpreter/arbitrary", "dep:arbitrary", "dep:proptest", "dep:proptest-derive"]
|
arbitrary = [
|
||||||
|
"revm-interpreter/arbitrary",
|
||||||
|
"dep:arbitrary",
|
||||||
|
"dep:proptest",
|
||||||
|
"dep:proptest-derive",
|
||||||
|
]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "recover_ecdsa_crit"
|
name = "recover_ecdsa_crit"
|
||||||
|
|||||||
795
crates/primitives/res/genesis/goerli.json
Normal file
795
crates/primitives/res/genesis/goerli.json
Normal file
@ -0,0 +1,795 @@
|
|||||||
|
{
|
||||||
|
"nonce": "0x0",
|
||||||
|
"timestamp": "0x5c51a607",
|
||||||
|
"extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"gasLimit": "0xa00000",
|
||||||
|
"difficulty": "0x1",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"coinbase": "0x0000000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0x5d6cded585e73c4e322c30c2f782a336316f17dd85a4863b9d838d2d4b8b3008",
|
||||||
|
"alloc": {
|
||||||
|
"0000000000000000000000000000000000000000": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000001": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000002": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000003": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000004": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000005": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000006": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000007": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000008": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000009": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000000f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000010": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000011": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000012": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000013": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000014": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000015": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000016": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000017": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000018": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000019": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000001f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000020": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000021": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000022": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000023": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000024": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000025": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000026": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000027": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000028": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000029": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000002f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000030": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000031": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000032": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000033": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000034": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000035": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000036": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000037": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000038": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000039": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000003f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000040": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000041": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000042": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000043": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000044": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000045": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000046": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000047": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000048": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000049": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000004f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000050": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000051": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000052": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000053": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000054": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000055": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000056": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000057": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000058": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000059": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000005f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000060": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000061": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000062": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000063": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000064": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000065": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000066": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000067": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000068": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000069": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000006f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000070": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000071": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000072": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000073": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000074": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000075": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000076": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000077": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000078": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000079": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000007f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000080": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000081": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000082": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000083": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000084": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000085": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000086": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000087": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000088": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000089": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000008f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000090": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000091": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000092": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000093": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000094": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000095": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000096": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000097": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000098": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"0000000000000000000000000000000000000099": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009a": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009b": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009c": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009d": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009e": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"000000000000000000000000000000000000009f": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000a9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000aa": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ab": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ac": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ad": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ae": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000af": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000b9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ba": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000bb": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000bc": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000bd": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000be": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000bf": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000c9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ca": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000cb": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000cc": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000cd": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ce": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000cf": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000d9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000da": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000db": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000dc": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000dd": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000de": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000df": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000e9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ea": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000eb": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ec": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ed": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ee": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ef": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f0": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f1": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f2": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f3": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f4": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f5": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f6": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f7": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f8": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000f9": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000fa": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000fb": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000fc": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000fd": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000fe": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"00000000000000000000000000000000000000ff": {
|
||||||
|
"balance": "0x1"
|
||||||
|
},
|
||||||
|
"4c2ae482593505f0163cdefc073e81c63cda4107": {
|
||||||
|
"balance": "0x152d02c7e14af6800000"
|
||||||
|
},
|
||||||
|
"a8e8f14732658e4b51e8711931053a8a69baf2b1": {
|
||||||
|
"balance": "0x152d02c7e14af6800000"
|
||||||
|
},
|
||||||
|
"d9a5179f091d85051d3c982785efd1455cec8699": {
|
||||||
|
"balance": "0x84595161401484a000000"
|
||||||
|
},
|
||||||
|
"e0a2bd4258d2768837baa26a28fe71dc079f84c7": {
|
||||||
|
"balance": "0x4a47e3c12448f4ad000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": "0x0",
|
||||||
|
"gasUsed": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
26694
crates/primitives/res/genesis/mainnet.json
Normal file
26694
crates/primitives/res/genesis/mainnet.json
Normal file
File diff suppressed because it is too large
Load Diff
60
crates/primitives/res/genesis/sepolia.json
Normal file
60
crates/primitives/res/genesis/sepolia.json
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"nonce": "0x00",
|
||||||
|
"timestamp": "0x6159af19",
|
||||||
|
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521",
|
||||||
|
"gasLimit": "0x1c9c380",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"coinbase": "0x0000000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494",
|
||||||
|
"alloc": {
|
||||||
|
"0xa2A6d93439144FFE4D27c9E088dCD8b783946263": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xBc11295936Aa79d594139de1B2e12629414F3BDB": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xaaec86394441f915bce3e6ab399977e9906f3b69": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xe2e2659028143784d557bcec6ff3a0721048880a": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xd9a5179f091d85051d3c982785efd1455cec8699": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": {
|
||||||
|
"balance": "0xD3C21BCECCEDA1000000"
|
||||||
|
},
|
||||||
|
"0x0000006916a87b82333f4245046623b23794c65c": {
|
||||||
|
"balance": "0x84595161401484A000000"
|
||||||
|
},
|
||||||
|
"0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": {
|
||||||
|
"balance": "0x52B7D2DCC80CD2E4000000"
|
||||||
|
},
|
||||||
|
"0x10F5d45854e038071485AC9e402308cF80D2d2fE": {
|
||||||
|
"balance": "0x52B7D2DCC80CD2E4000000"
|
||||||
|
},
|
||||||
|
"0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": {
|
||||||
|
"balance": "0x52B7D2DCC80CD2E4000000"
|
||||||
|
},
|
||||||
|
"0x799D329e5f583419167cD722962485926E338F4a": {
|
||||||
|
"balance": "0xDE0B6B3A7640000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": "0x0",
|
||||||
|
"gasUsed": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
353
crates/primitives/src/chain_spec.rs
Normal file
353
crates/primitives/src/chain_spec.rs
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
use hex_literal::hex;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{BlockNumber, Chain, ForkFilter, ForkHash, ForkId, Genesis, Hardfork, H256, U256};
|
||||||
|
|
||||||
|
/// The Etereum mainnet spec
|
||||||
|
pub static MAINNET: Lazy<ChainSpec> = 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: H256(hex!("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")),
|
||||||
|
hardforks: BTreeMap::from([
|
||||||
|
(Hardfork::Frontier, 0),
|
||||||
|
(Hardfork::Homestead, 1150000),
|
||||||
|
(Hardfork::Dao, 1920000),
|
||||||
|
(Hardfork::Tangerine, 2463000),
|
||||||
|
(Hardfork::SpuriousDragon, 2675000),
|
||||||
|
(Hardfork::Byzantium, 4370000),
|
||||||
|
(Hardfork::Constantinople, 7280000),
|
||||||
|
(Hardfork::Petersburg, 7280000),
|
||||||
|
(Hardfork::Istanbul, 9069000),
|
||||||
|
(Hardfork::Muirglacier, 9200000),
|
||||||
|
(Hardfork::Berlin, 12244000),
|
||||||
|
(Hardfork::London, 12965000),
|
||||||
|
(Hardfork::ArrowGlacier, 13773000),
|
||||||
|
(Hardfork::GrayGlacier, 15050000),
|
||||||
|
(Hardfork::Latest, 15050000),
|
||||||
|
]),
|
||||||
|
dao_fork_support: true,
|
||||||
|
paris_block: Some(15537394),
|
||||||
|
paris_ttd: Some(U256::from(58750000000000000000000_u128)),
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The Goerli spec
|
||||||
|
pub static GOERLI: Lazy<ChainSpec> = Lazy::new(|| ChainSpec {
|
||||||
|
chain: Chain::goerli(),
|
||||||
|
genesis: serde_json::from_str(include_str!("../res/genesis/goerli.json"))
|
||||||
|
.expect("Can't deserialize Goerli genesis json"),
|
||||||
|
genesis_hash: H256(hex!("bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")),
|
||||||
|
hardforks: BTreeMap::from([
|
||||||
|
(Hardfork::Frontier, 0),
|
||||||
|
(Hardfork::Istanbul, 1561651),
|
||||||
|
(Hardfork::Berlin, 4460644),
|
||||||
|
(Hardfork::London, 5062605),
|
||||||
|
]),
|
||||||
|
dao_fork_support: true,
|
||||||
|
paris_block: Some(7382818),
|
||||||
|
paris_ttd: Some(U256::from(10790000)),
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The Sepolia spec
|
||||||
|
pub static SEPOLIA: Lazy<ChainSpec> = Lazy::new(|| ChainSpec {
|
||||||
|
chain: Chain::sepolia(),
|
||||||
|
genesis: serde_json::from_str(include_str!("../res/genesis/sepolia.json"))
|
||||||
|
.expect("Can't deserialize Sepolia genesis json"),
|
||||||
|
genesis_hash: H256(hex!("25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9")),
|
||||||
|
hardforks: BTreeMap::new(),
|
||||||
|
dao_fork_support: true,
|
||||||
|
paris_block: Some(1450408),
|
||||||
|
paris_ttd: Some(U256::from(17000000000000000_u64)),
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The Ethereum chain spec
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct ChainSpec {
|
||||||
|
chain: Chain,
|
||||||
|
genesis: Genesis,
|
||||||
|
genesis_hash: H256,
|
||||||
|
hardforks: BTreeMap<Hardfork, BlockNumber>,
|
||||||
|
dao_fork_support: bool,
|
||||||
|
paris_block: Option<u64>,
|
||||||
|
paris_ttd: Option<U256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChainSpec {
|
||||||
|
/// Returns the chain id
|
||||||
|
pub fn chain(&self) -> Chain {
|
||||||
|
self.chain
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the chain genesis hash
|
||||||
|
pub fn genesis_hash(&self) -> H256 {
|
||||||
|
self.genesis_hash
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the first block number of the hardfork.
|
||||||
|
pub fn fork_block(&self, fork: Hardfork) -> Option<BlockNumber> {
|
||||||
|
self.hardforks.get(&fork).copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the given fork is active on the given block
|
||||||
|
pub fn fork_active(&self, fork: Hardfork, current_block: BlockNumber) -> bool {
|
||||||
|
self.fork_block(fork).map(|target| target <= current_block).unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the DAO fork is supported
|
||||||
|
pub fn dao_fork_support(&self) -> bool {
|
||||||
|
self.dao_fork_support
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the Paris status
|
||||||
|
pub fn paris_status(&self) -> ParisStatus {
|
||||||
|
match self.paris_ttd {
|
||||||
|
Some(terminal_total_difficulty) => {
|
||||||
|
ParisStatus::Supported { terminal_total_difficulty, block: self.paris_block }
|
||||||
|
}
|
||||||
|
None => ParisStatus::NotSupported,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get an iterator of all harforks with theirs respectives block number
|
||||||
|
pub fn forks_iter(&self) -> impl Iterator<Item = (Hardfork, BlockNumber)> + '_ {
|
||||||
|
self.hardforks.iter().map(|(f, b)| (*f, *b))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a [`ForkFilter`](crate::ForkFilter) for the given [BlockNumber].
|
||||||
|
|
||||||
|
pub fn fork_filter(&self, block: BlockNumber) -> ForkFilter {
|
||||||
|
let future_forks =
|
||||||
|
self.forks_iter().map(|(_, b)| b).filter(|b| *b > block).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
ForkFilter::new(block, self.genesis_hash(), future_forks)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute the forkid for the given [BlockNumber]
|
||||||
|
pub fn fork_id(&self, block: BlockNumber) -> ForkId {
|
||||||
|
let mut curr_forkhash = ForkHash::from(self.genesis_hash());
|
||||||
|
let mut curr_block_number = 0;
|
||||||
|
|
||||||
|
for (_, b) in self.forks_iter() {
|
||||||
|
if block >= b {
|
||||||
|
if b != curr_block_number {
|
||||||
|
curr_forkhash += b;
|
||||||
|
curr_block_number = b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ForkId { hash: curr_forkhash, next: b }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ForkId { hash: curr_forkhash, next: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a [ChainSpecBuilder] to help build custom specs
|
||||||
|
pub fn builder() -> ChainSpecBuilder {
|
||||||
|
ChainSpecBuilder::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A helper to build custom chain specs
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ChainSpecBuilder {
|
||||||
|
chain: Option<Chain>,
|
||||||
|
genesis: Option<Genesis>,
|
||||||
|
genesis_hash: Option<H256>,
|
||||||
|
hardforks: BTreeMap<Hardfork, BlockNumber>,
|
||||||
|
dao_fork_support: bool,
|
||||||
|
paris_block: Option<u64>,
|
||||||
|
paris_ttd: Option<U256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChainSpecBuilder {
|
||||||
|
/// Returns a [ChainSpec] builder initialized with Ethereum mainnet config
|
||||||
|
pub fn mainnet() -> Self {
|
||||||
|
Self {
|
||||||
|
chain: Some(MAINNET.chain),
|
||||||
|
genesis: Some(MAINNET.genesis.clone()),
|
||||||
|
genesis_hash: Some(MAINNET.genesis_hash),
|
||||||
|
hardforks: MAINNET.hardforks.clone(),
|
||||||
|
dao_fork_support: MAINNET.dao_fork_support,
|
||||||
|
paris_block: MAINNET.paris_block,
|
||||||
|
paris_ttd: MAINNET.paris_ttd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the chain id
|
||||||
|
pub fn chain(mut self, chain: Chain) -> Self {
|
||||||
|
self.chain = Some(chain);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the genesis
|
||||||
|
pub fn genesis(mut self, genesis: Genesis) -> Self {
|
||||||
|
self.genesis = Some(genesis);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Insert the given fork at the given block number
|
||||||
|
pub fn with_fork(mut self, fork: Hardfork, block: BlockNumber) -> Self {
|
||||||
|
self.hardforks.insert(fork, block);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Frontier
|
||||||
|
pub fn frontier_activated(mut self) -> Self {
|
||||||
|
self.hardforks.insert(Hardfork::Frontier, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Homestead
|
||||||
|
pub fn homestead_activated(mut self) -> Self {
|
||||||
|
self = self.frontier_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Homestead, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Tangerine
|
||||||
|
pub fn tangerine_whistle_activated(mut self) -> Self {
|
||||||
|
self = self.homestead_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Tangerine, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables SpuriousDragon
|
||||||
|
pub fn spurious_dragon_activated(mut self) -> Self {
|
||||||
|
self = self.tangerine_whistle_activated();
|
||||||
|
self.hardforks.insert(Hardfork::SpuriousDragon, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Byzantium
|
||||||
|
pub fn byzantium_activated(mut self) -> Self {
|
||||||
|
self = self.spurious_dragon_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Byzantium, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Petersburg
|
||||||
|
pub fn petersburg_activated(mut self) -> Self {
|
||||||
|
self = self.byzantium_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Petersburg, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Istanbul
|
||||||
|
pub fn istanbul_activated(mut self) -> Self {
|
||||||
|
self = self.petersburg_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Istanbul, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Berlin
|
||||||
|
pub fn berlin_activated(mut self) -> Self {
|
||||||
|
self = self.istanbul_activated();
|
||||||
|
self.hardforks.insert(Hardfork::Berlin, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables London
|
||||||
|
pub fn london_activated(mut self) -> Self {
|
||||||
|
self = self.berlin_activated();
|
||||||
|
self.hardforks.insert(Hardfork::London, 0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the DAO fork as supported
|
||||||
|
pub fn dao_fork_supported(mut self) -> Self {
|
||||||
|
self.dao_fork_support = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables Paris
|
||||||
|
pub fn paris_activated(mut self) -> Self {
|
||||||
|
self = self.berlin_activated();
|
||||||
|
self.paris_block = Some(0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build a [ChainSpec]
|
||||||
|
pub fn build(self) -> ChainSpec {
|
||||||
|
ChainSpec {
|
||||||
|
chain: self.chain.expect("The chain is required"),
|
||||||
|
genesis: self.genesis.expect("The genesis is required"),
|
||||||
|
genesis_hash: self.genesis_hash.expect("The genesis hash is required"),
|
||||||
|
hardforks: self.hardforks,
|
||||||
|
dao_fork_support: self.dao_fork_support,
|
||||||
|
paris_block: self.paris_block,
|
||||||
|
paris_ttd: self.paris_ttd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ChainSpec> for ChainSpecBuilder {
|
||||||
|
fn from(value: &ChainSpec) -> Self {
|
||||||
|
Self {
|
||||||
|
chain: Some(value.chain),
|
||||||
|
genesis: Some(value.genesis.clone()),
|
||||||
|
genesis_hash: Some(value.genesis_hash),
|
||||||
|
hardforks: value.hardforks.clone(),
|
||||||
|
dao_fork_support: value.dao_fork_support,
|
||||||
|
paris_block: value.paris_block,
|
||||||
|
paris_ttd: value.paris_ttd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merge Status
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ParisStatus {
|
||||||
|
/// Paris is not supported
|
||||||
|
NotSupported,
|
||||||
|
/// Paris settings has been set in the chain spec
|
||||||
|
Supported {
|
||||||
|
/// The merge terminal total difficulty
|
||||||
|
terminal_total_difficulty: U256,
|
||||||
|
/// The Paris block number
|
||||||
|
block: Option<BlockNumber>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParisStatus {
|
||||||
|
/// Returns the Paris block number if it is known ahead of time.
|
||||||
|
///
|
||||||
|
/// This is only the case for chains that have already activated the merge.
|
||||||
|
pub fn block_number(&self) -> Option<BlockNumber> {
|
||||||
|
match &self {
|
||||||
|
ParisStatus::NotSupported => None,
|
||||||
|
ParisStatus::Supported { block, .. } => *block,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the merge terminal total difficulty
|
||||||
|
pub fn terminal_total_difficulty(&self) -> Option<U256> {
|
||||||
|
match &self {
|
||||||
|
ParisStatus::NotSupported => None,
|
||||||
|
ParisStatus::Supported { terminal_total_difficulty, .. } => {
|
||||||
|
Some(*terminal_total_difficulty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::MAINNET;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
// this test checks that the forkid computation is accurate
|
||||||
|
fn test_forkid_from_hardfork() {
|
||||||
|
let frontier_forkid = MAINNET.fork_id(0);
|
||||||
|
assert_eq!([0xfc, 0x64, 0xec, 0x04], frontier_forkid.hash.0);
|
||||||
|
assert_eq!(1150000, frontier_forkid.next);
|
||||||
|
|
||||||
|
let berlin_forkid = MAINNET.fork_id(12244000);
|
||||||
|
assert_eq!([0x0e, 0xb4, 0x40, 0xf6], berlin_forkid.hash.0);
|
||||||
|
assert_eq!(12965000, berlin_forkid.next);
|
||||||
|
|
||||||
|
let latest_forkid = MAINNET.fork_id(15050000);
|
||||||
|
assert_eq!(0, latest_forkid.next);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
crates/primitives/src/genesis.rs
Normal file
60
crates/primitives/src/genesis.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
utils::serde_helpers::deserialize_stringified_u64, Address, Bytes, Header, H256, U256,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The genesis block specification.
|
||||||
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Genesis {
|
||||||
|
/// The genesis header nonce.
|
||||||
|
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
||||||
|
pub nonce: u64,
|
||||||
|
/// The genesis header timestamp.
|
||||||
|
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
||||||
|
pub timestamp: u64,
|
||||||
|
/// The genesis header extra data.
|
||||||
|
pub extra_data: Bytes,
|
||||||
|
/// The genesis header gas limit.
|
||||||
|
#[serde(deserialize_with = "deserialize_stringified_u64")]
|
||||||
|
pub gas_limit: u64,
|
||||||
|
/// The genesis header difficulty.
|
||||||
|
pub difficulty: U256,
|
||||||
|
/// The genesis header mix hash.
|
||||||
|
pub mix_hash: H256,
|
||||||
|
/// The genesis header coinbase address.
|
||||||
|
pub coinbase: Address,
|
||||||
|
/// The genesis state root.
|
||||||
|
pub state_root: H256,
|
||||||
|
/// The initial state of accounts in the genesis block.
|
||||||
|
pub alloc: HashMap<Address, GenesisAccount>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Genesis> for Header {
|
||||||
|
fn from(genesis: Genesis) -> Header {
|
||||||
|
Header {
|
||||||
|
gas_limit: genesis.gas_limit,
|
||||||
|
difficulty: genesis.difficulty,
|
||||||
|
nonce: genesis.nonce,
|
||||||
|
extra_data: genesis.extra_data,
|
||||||
|
state_root: genesis.state_root,
|
||||||
|
timestamp: genesis.timestamp,
|
||||||
|
mix_hash: genesis.mix_hash,
|
||||||
|
beneficiary: genesis.coinbase,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An account in the state of the genesis block.
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct GenesisAccount {
|
||||||
|
/// The nonce of the account at genesis.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub nonce: Option<u64>,
|
||||||
|
/// The balance of the account at genesis.
|
||||||
|
pub balance: U256,
|
||||||
|
}
|
||||||
@ -1,9 +1,13 @@
|
|||||||
use crate::{BlockNumber, ForkFilter, ForkHash, ForkId, MAINNET_GENESIS};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
|
||||||
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
|
use crate::{BlockNumber, ChainSpec, ForkFilter, ForkHash, ForkId};
|
||||||
|
|
||||||
/// Ethereum mainnet hardforks
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
|
#[derive(
|
||||||
|
Debug, Default, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize,
|
||||||
|
)]
|
||||||
pub enum Hardfork {
|
pub enum Hardfork {
|
||||||
Frontier,
|
Frontier,
|
||||||
Homestead,
|
Homestead,
|
||||||
@ -19,74 +23,12 @@ pub enum Hardfork {
|
|||||||
London,
|
London,
|
||||||
ArrowGlacier,
|
ArrowGlacier,
|
||||||
GrayGlacier,
|
GrayGlacier,
|
||||||
|
Shanghai,
|
||||||
#[default]
|
#[default]
|
||||||
Latest,
|
Latest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hardfork {
|
impl Hardfork {
|
||||||
/// Get the first block number of the hardfork.
|
|
||||||
pub fn fork_block(&self) -> u64 {
|
|
||||||
match *self {
|
|
||||||
Hardfork::Frontier => 0,
|
|
||||||
Hardfork::Homestead => 1150000,
|
|
||||||
Hardfork::Dao => 1920000,
|
|
||||||
Hardfork::Tangerine => 2463000,
|
|
||||||
Hardfork::SpuriousDragon => 2675000,
|
|
||||||
Hardfork::Byzantium => 4370000,
|
|
||||||
Hardfork::Constantinople | Hardfork::Petersburg => 7280000,
|
|
||||||
Hardfork::Istanbul => 9069000,
|
|
||||||
Hardfork::Muirglacier => 9200000,
|
|
||||||
Hardfork::Berlin => 12244000,
|
|
||||||
Hardfork::London => 12965000,
|
|
||||||
Hardfork::ArrowGlacier => 13773000,
|
|
||||||
Hardfork::GrayGlacier | Hardfork::Latest => 15050000,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the EIP-2124 fork id for a given hardfork
|
|
||||||
///
|
|
||||||
/// The [`ForkId`](ethereum_forkid::ForkId) includes a CRC32 checksum of the all fork block
|
|
||||||
/// numbers from genesis, and the next upcoming fork block number.
|
|
||||||
/// If the next fork block number is not yet known, it is set to 0.
|
|
||||||
pub fn fork_id(&self) -> ForkId {
|
|
||||||
match *self {
|
|
||||||
Hardfork::Frontier => {
|
|
||||||
ForkId { hash: ForkHash([0xfc, 0x64, 0xec, 0x04]), next: 1150000 }
|
|
||||||
}
|
|
||||||
Hardfork::Homestead => {
|
|
||||||
ForkId { hash: ForkHash([0x97, 0xc2, 0xc3, 0x4c]), next: 1920000 }
|
|
||||||
}
|
|
||||||
Hardfork::Dao => ForkId { hash: ForkHash([0x91, 0xd1, 0xf9, 0x48]), next: 2463000 },
|
|
||||||
Hardfork::Tangerine => {
|
|
||||||
ForkId { hash: ForkHash([0x7a, 0x64, 0xda, 0x13]), next: 2675000 }
|
|
||||||
}
|
|
||||||
Hardfork::SpuriousDragon => {
|
|
||||||
ForkId { hash: ForkHash([0x3e, 0xdd, 0x5b, 0x10]), next: 4370000 }
|
|
||||||
}
|
|
||||||
Hardfork::Byzantium => {
|
|
||||||
ForkId { hash: ForkHash([0xa0, 0x0b, 0xc3, 0x24]), next: 7280000 }
|
|
||||||
}
|
|
||||||
Hardfork::Constantinople | Hardfork::Petersburg => {
|
|
||||||
ForkId { hash: ForkHash([0x66, 0x8d, 0xb0, 0xaf]), next: 9069000 }
|
|
||||||
}
|
|
||||||
Hardfork::Istanbul => {
|
|
||||||
ForkId { hash: ForkHash([0x87, 0x9d, 0x6e, 0x30]), next: 9200000 }
|
|
||||||
}
|
|
||||||
Hardfork::Muirglacier => {
|
|
||||||
ForkId { hash: ForkHash([0xe0, 0x29, 0xe9, 0x91]), next: 12244000 }
|
|
||||||
}
|
|
||||||
Hardfork::Berlin => ForkId { hash: ForkHash([0x0e, 0xb4, 0x40, 0xf6]), next: 12965000 },
|
|
||||||
Hardfork::London => ForkId { hash: ForkHash([0xb7, 0x15, 0x07, 0x7d]), next: 13773000 },
|
|
||||||
Hardfork::ArrowGlacier => {
|
|
||||||
ForkId { hash: ForkHash([0x20, 0xc3, 0x27, 0xfc]), next: 15050000 }
|
|
||||||
}
|
|
||||||
Hardfork::Latest | Hardfork::GrayGlacier => {
|
|
||||||
// update `next` when another fork block num is known
|
|
||||||
ForkId { hash: ForkHash([0xf0, 0xaf, 0xd0, 0xe3]), next: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This returns all known hardforks in order.
|
/// This returns all known hardforks in order.
|
||||||
pub fn all_forks() -> Vec<Self> {
|
pub fn all_forks() -> Vec<Self> {
|
||||||
vec![
|
vec![
|
||||||
@ -106,26 +48,43 @@ impl Hardfork {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This returns all known hardfork block numbers as a vector.
|
/// Compute the forkid for the given [ChainSpec]
|
||||||
pub fn all_fork_blocks() -> Vec<BlockNumber> {
|
pub fn fork_id(&self, chain_spec: &ChainSpec) -> Option<ForkId> {
|
||||||
Hardfork::all_forks().iter().map(|f| f.fork_block()).collect()
|
if let Some(fork_block) = chain_spec.fork_block(*self) {
|
||||||
|
let mut curr_forkhash = ForkHash::from(chain_spec.genesis_hash());
|
||||||
|
let mut curr_block_number = 0;
|
||||||
|
|
||||||
|
for (_, b) in chain_spec.forks_iter() {
|
||||||
|
if fork_block >= b {
|
||||||
|
if b != curr_block_number {
|
||||||
|
curr_forkhash += b;
|
||||||
|
curr_block_number = b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Some(ForkId { hash: curr_forkhash, next: b })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(ForkId { hash: curr_forkhash, next: 0 })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`ForkFilter`](crate::ForkFilter) for the given hardfork.
|
/// Creates a [`ForkFilter`](crate::ForkFilter) for the given hardfork.
|
||||||
///
|
///
|
||||||
/// **CAUTION**: This assumes the current hardfork's block number is the current head and uses
|
/// **CAUTION**: This assumes the current hardfork's block number is the current head and uses
|
||||||
/// all known future hardforks to initialize the filter.
|
/// all known future hardforks to initialize the filter.
|
||||||
pub fn fork_filter(&self) -> ForkFilter {
|
pub fn fork_filter(&self, chain_spec: &ChainSpec) -> Option<ForkFilter> {
|
||||||
let all_forks = Hardfork::all_forks();
|
if let Some(fork_block) = chain_spec.fork_block(*self) {
|
||||||
let future_forks: Vec<BlockNumber> = all_forks
|
let future_forks: Vec<BlockNumber> =
|
||||||
.iter()
|
chain_spec.forks_iter().filter(|(_, b)| b > &fork_block).map(|(_, b)| b).collect();
|
||||||
.filter(|f| f.fork_block() > self.fork_block())
|
|
||||||
.map(|f| f.fork_block())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// this data structure is not chain-agnostic, so we can pass in the constant mainnet
|
// this data structure is not chain-agnostic, so we can pass in the constant mainnet
|
||||||
// genesis
|
// genesis
|
||||||
ForkFilter::new(self.fork_block(), MAINNET_GENESIS, future_forks)
|
Some(ForkFilter::new(fork_block, chain_spec.genesis_hash(), future_forks))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,72 +115,8 @@ impl FromStr for Hardfork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BlockNumber> for Hardfork {
|
impl Display for Hardfork {
|
||||||
fn from(num: BlockNumber) -> Hardfork {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match num {
|
write!(f, "{self:?}")
|
||||||
_i if num < 1_150_000 => Hardfork::Frontier,
|
|
||||||
_i if num < 1_920_000 => Hardfork::Dao,
|
|
||||||
_i if num < 2_463_000 => Hardfork::Homestead,
|
|
||||||
_i if num < 2_675_000 => Hardfork::Tangerine,
|
|
||||||
_i if num < 4_370_000 => Hardfork::SpuriousDragon,
|
|
||||||
_i if num < 7_280_000 => Hardfork::Byzantium,
|
|
||||||
_i if num < 9_069_000 => Hardfork::Constantinople,
|
|
||||||
_i if num < 9_200_000 => Hardfork::Istanbul,
|
|
||||||
_i if num < 12_244_000 => Hardfork::Muirglacier,
|
|
||||||
_i if num < 12_965_000 => Hardfork::Berlin,
|
|
||||||
_i if num < 13_773_000 => Hardfork::London,
|
|
||||||
_i if num < 15_050_000 => Hardfork::ArrowGlacier,
|
|
||||||
|
|
||||||
_ => Hardfork::Latest,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Hardfork> for BlockNumber {
|
|
||||||
fn from(value: Hardfork) -> Self {
|
|
||||||
value.fork_block()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::{forkid::ForkHash, hardfork::Hardfork};
|
|
||||||
use crc::crc32;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_hardfork_blocks() {
|
|
||||||
let hf: Hardfork = 12_965_000u64.into();
|
|
||||||
assert_eq!(hf, Hardfork::London);
|
|
||||||
|
|
||||||
let hf: Hardfork = 4370000u64.into();
|
|
||||||
assert_eq!(hf, Hardfork::Byzantium);
|
|
||||||
|
|
||||||
let hf: Hardfork = 12244000u64.into();
|
|
||||||
assert_eq!(hf, Hardfork::Berlin);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
// this test checks that the fork hash assigned to forks accurately map to the fork_id method
|
|
||||||
fn test_forkhash_from_fork_blocks() {
|
|
||||||
// set the genesis hash
|
|
||||||
let genesis =
|
|
||||||
hex::decode("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// set the frontier forkhash
|
|
||||||
let mut curr_forkhash = ForkHash(crc32::checksum_ieee(&genesis[..]).to_be_bytes());
|
|
||||||
|
|
||||||
// now we go through enum members
|
|
||||||
let frontier_forkid = Hardfork::Frontier.fork_id();
|
|
||||||
assert_eq!(curr_forkhash, frontier_forkid.hash);
|
|
||||||
|
|
||||||
// list of the above hardforks
|
|
||||||
let hardforks = Hardfork::all_forks();
|
|
||||||
|
|
||||||
// check that the curr_forkhash we compute matches the output of each fork_id returned
|
|
||||||
for hardfork in hardforks {
|
|
||||||
curr_forkhash += hardfork.fork_block();
|
|
||||||
assert_eq!(curr_forkhash, hardfork.fork_id().hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,11 @@ mod bits;
|
|||||||
mod block;
|
mod block;
|
||||||
pub mod bloom;
|
pub mod bloom;
|
||||||
mod chain;
|
mod chain;
|
||||||
|
mod chain_spec;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod error;
|
mod error;
|
||||||
mod forkid;
|
mod forkid;
|
||||||
|
mod genesis;
|
||||||
mod hardfork;
|
mod hardfork;
|
||||||
mod header;
|
mod header;
|
||||||
mod hex_bytes;
|
mod hex_bytes;
|
||||||
@ -37,8 +39,10 @@ pub use bits::H512;
|
|||||||
pub use block::{Block, BlockHashOrNumber, SealedBlock};
|
pub use block::{Block, BlockHashOrNumber, SealedBlock};
|
||||||
pub use bloom::Bloom;
|
pub use bloom::Bloom;
|
||||||
pub use chain::Chain;
|
pub use chain::Chain;
|
||||||
|
pub use chain_spec::{ChainSpec, ChainSpecBuilder, ParisStatus, GOERLI, MAINNET, SEPOLIA};
|
||||||
pub use constants::{EMPTY_OMMER_ROOT, KECCAK_EMPTY, MAINNET_GENESIS};
|
pub use constants::{EMPTY_OMMER_ROOT, KECCAK_EMPTY, MAINNET_GENESIS};
|
||||||
pub use forkid::{ForkFilter, ForkHash, ForkId, ForkTransition, ValidationError};
|
pub use forkid::{ForkFilter, ForkHash, ForkId, ForkTransition, ValidationError};
|
||||||
|
pub use genesis::{Genesis, GenesisAccount};
|
||||||
pub use hardfork::Hardfork;
|
pub use hardfork::Hardfork;
|
||||||
pub use header::{Header, HeadersDirection, SealedHeader};
|
pub use header::{Header, HeadersDirection, SealedHeader};
|
||||||
pub use hex_bytes::Bytes;
|
pub use hex_bytes::Bytes;
|
||||||
|
|||||||
@ -10,12 +10,12 @@ use reth_db::{
|
|||||||
transaction::{DbTx, DbTxMut},
|
transaction::{DbTx, DbTxMut},
|
||||||
};
|
};
|
||||||
use reth_executor::{
|
use reth_executor::{
|
||||||
config::SpecUpgrades,
|
|
||||||
executor::AccountChangeSet,
|
executor::AccountChangeSet,
|
||||||
revm_wrap::{State, SubState},
|
revm_wrap::{State, SubState},
|
||||||
Config,
|
|
||||||
};
|
};
|
||||||
use reth_primitives::{Address, Header, StorageEntry, TransactionSignedEcRecovered, H256, U256};
|
use reth_primitives::{
|
||||||
|
Address, ChainSpec, Header, StorageEntry, TransactionSignedEcRecovered, H256, MAINNET, U256,
|
||||||
|
};
|
||||||
use reth_provider::LatestStateProviderRef;
|
use reth_provider::LatestStateProviderRef;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
@ -52,24 +52,21 @@ const EXECUTION: StageId = StageId("Execution");
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExecutionStage {
|
pub struct ExecutionStage {
|
||||||
/// Executor configuration.
|
/// Executor configuration.
|
||||||
pub config: Config,
|
pub chain_spec: ChainSpec,
|
||||||
/// Commit threshold
|
/// Commit threshold
|
||||||
pub commit_threshold: u64,
|
pub commit_threshold: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ExecutionStage {
|
impl Default for ExecutionStage {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self { chain_spec: MAINNET.clone(), commit_threshold: 1000 }
|
||||||
config: Config { chain_id: U256::from(1), spec_upgrades: SpecUpgrades::new_ethereum() },
|
|
||||||
commit_threshold: 1000,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExecutionStage {
|
impl ExecutionStage {
|
||||||
/// Create new execution stage with specified config.
|
/// Create new execution stage with specified config.
|
||||||
pub fn new(config: Config, commit_threshold: u64) -> Self {
|
pub fn new(chain_spec: ChainSpec, commit_threshold: u64) -> Self {
|
||||||
Self { config, commit_threshold }
|
Self { chain_spec, commit_threshold }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +190,7 @@ impl<DB: Database> Stage<DB> for ExecutionStage {
|
|||||||
header,
|
header,
|
||||||
&recovered_transactions,
|
&recovered_transactions,
|
||||||
ommers,
|
ommers,
|
||||||
&self.config,
|
&self.chain_spec,
|
||||||
&mut state_provider,
|
&mut state_provider,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -381,7 +378,9 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use reth_db::mdbx::{test_utils::create_test_db, EnvKind, WriteMap};
|
use reth_db::mdbx::{test_utils::create_test_db, EnvKind, WriteMap};
|
||||||
use reth_primitives::{hex_literal::hex, keccak256, Account, SealedBlock, H160, U256};
|
use reth_primitives::{
|
||||||
|
hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, H160, U256,
|
||||||
|
};
|
||||||
use reth_provider::insert_canonical_block;
|
use reth_provider::insert_canonical_block;
|
||||||
use reth_rlp::Decodable;
|
use reth_rlp::Decodable;
|
||||||
|
|
||||||
@ -427,8 +426,10 @@ mod tests {
|
|||||||
tx.commit().unwrap();
|
tx.commit().unwrap();
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
let mut execution_stage = ExecutionStage::default();
|
let mut execution_stage = ExecutionStage {
|
||||||
execution_stage.config.spec_upgrades = SpecUpgrades::new_berlin_activated();
|
chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
let output = execution_stage.execute(&mut tx, input).await.unwrap();
|
let output = execution_stage.execute(&mut tx, input).await.unwrap();
|
||||||
tx.commit().unwrap();
|
tx.commit().unwrap();
|
||||||
assert_eq!(output, ExecOutput { stage_progress: 1, done: true });
|
assert_eq!(output, ExecOutput { stage_progress: 1, done: true });
|
||||||
@ -513,8 +514,10 @@ mod tests {
|
|||||||
|
|
||||||
// execute
|
// execute
|
||||||
|
|
||||||
let mut execution_stage = ExecutionStage::default();
|
let mut execution_stage = ExecutionStage {
|
||||||
execution_stage.config.spec_upgrades = SpecUpgrades::new_berlin_activated();
|
chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
let _ = execution_stage.execute(&mut tx, input).await.unwrap();
|
let _ = execution_stage.execute(&mut tx, input).await.unwrap();
|
||||||
tx.commit().unwrap();
|
tx.commit().unwrap();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user