Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reth-ethereum-forks crate #5621

Merged
merged 15 commits into from
Dec 1, 2023
237 changes: 160 additions & 77 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"crates/consensus/auto-seal/",
"crates/consensus/beacon/",
"crates/consensus/common/",
"crates/ethereum-forks/",
"crates/interfaces/",
"crates/metrics/",
"crates/metrics/metrics-derive/",
Expand Down Expand Up @@ -102,6 +103,7 @@ reth-dns-discovery = { path = "crates/net/dns" }
reth-downloaders = { path = "crates/net/downloaders" }
reth-ecies = { path = "crates/net/ecies" }
reth-eth-wire = { path = "crates/net/eth-wire" }
reth-ethereum-forks = { path = "crates/ethereum-forks" }
reth-interfaces = { path = "crates/interfaces" }
reth-ipc = { path = "crates/rpc/ipc" }
reth-libmdbx = { path = "crates/storage/libmdbx-rs" }
Expand Down
41 changes: 41 additions & 0 deletions crates/ethereum-forks/Cargo.toml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs a cleanup, we probably need way less dependencies

mattsse marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "reth-ethereum-forks"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
description = "Ethereum fork types used in reth."

[dependencies]
# reth
reth-codecs.workspace = true

# ethereum
alloy-primitives = { workspace = true, features = ["rand", "rlp"] }
alloy-rlp = { workspace = true, features = ["arrayvec"] }

# used for forkid
crc = "3"

# misc
serde.workspace = true
thiserror.workspace = true


# arbitrary utils
arbitrary = { workspace = true, features = ["derive"], optional = true }
proptest = { workspace = true, optional = true }
proptest-derive = { workspace = true, optional = true }

[dev-dependencies]
rand.workspace = true
arbitrary = { workspace = true, features = ["derive"] }
proptest.workspace = true
proptest-derive.workspace = true


[features]
arbitrary = ["dep:arbitrary", "dep:proptest", "dep:proptest-derive"]
optimism = ["reth-codecs/optimism"]
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
//!
//! Previously version of Apache licenced [`ethereum-forkid`](https://crates.io/crates/ethereum-forkid).

#![deny(missing_docs)]

use crate::{hex, BlockNumber, Head, B256};
use crate::Head;
use alloy_primitives::{hex, BlockNumber, B256};
use alloy_rlp::*;
use crc::*;
use reth_codecs::derive_arbitrary;
Expand Down Expand Up @@ -72,10 +71,12 @@ where
}
}

// TODO: Move
/// How to filter forks.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum ForkFilterKey {
/// By block number activation.
Block(BlockNumber),
/// By timestamp activation.
Time(u64),
}

Expand Down Expand Up @@ -379,7 +380,7 @@ impl Cache {
#[cfg(test)]
mod tests {
use super::*;
use crate::{hex_literal::hex, revm_primitives::b256};
use alloy_primitives::b256;

const GENESIS_HASH: B256 =
b256!("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use serde::{Deserialize, Serialize};

use crate::{ChainSpec, ForkCondition, ForkFilter, ForkId};
use std::{fmt::Display, str::FromStr};

/// The name of an Ethereum hardfork.
Expand Down Expand Up @@ -52,25 +51,6 @@ pub enum Hardfork {
Cancun,
}

impl Hardfork {
/// Get the [ForkId] for this hardfork in the given spec, if the fork is activated at any point.
pub fn fork_id(&self, spec: &ChainSpec) -> Option<ForkId> {
match spec.fork(*self) {
ForkCondition::Never => None,
_ => Some(spec.fork_id(&spec.satisfy(spec.fork(*self)))),
}
}

/// Get the [ForkFilter] for this hardfork in the given spec, if the fork is activated at any
/// point.
pub fn fork_filter(&self, spec: &ChainSpec) -> Option<ForkFilter> {
match spec.fork(*self) {
ForkCondition::Never => None,
_ => Some(spec.fork_filter(spec.satisfy(spec.fork(*self)))),
}
}
}

impl FromStr for Hardfork {
type Err = String;

Expand Down Expand Up @@ -115,8 +95,6 @@ impl Display for Hardfork {
#[cfg(test)]
mod tests {
use super::*;
use crate::{Chain, Genesis};
use std::collections::BTreeMap;

#[test]
fn check_hardfork_from_str() {
Expand Down Expand Up @@ -181,34 +159,4 @@ mod tests {
fn check_nonexistent_hardfork_from_str() {
assert!(Hardfork::from_str("not a hardfork").is_err());
}

#[test]
fn check_fork_id_chainspec_with_fork_condition_never() {
let spec = ChainSpec {
chain: Chain::mainnet(),
genesis: Genesis::default(),
genesis_hash: None,
hardforks: BTreeMap::from([(Hardfork::Frontier, ForkCondition::Never)]),
paris_block_and_final_difficulty: None,
deposit_contract: None,
..Default::default()
};

assert_eq!(Hardfork::Frontier.fork_id(&spec), None);
}

#[test]
fn check_fork_filter_chainspec_with_fork_condition_never() {
let spec = ChainSpec {
chain: Chain::mainnet(),
genesis: Genesis::default(),
genesis_hash: None,
hardforks: BTreeMap::from([(Hardfork::Shanghai, ForkCondition::Never)]),
paris_block_and_final_difficulty: None,
deposit_contract: None,
..Default::default()
};

assert_eq!(Hardfork::Shanghai.fork_filter(&spec), None);
}
}
24 changes: 24 additions & 0 deletions crates/ethereum-forks/src/head.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use alloy_primitives::{BlockNumber, B256, U256};
use serde::{Deserialize, Serialize};

/// Describes the current head block.
///
/// The head block is the highest fully synced block.
///
/// Note: This is a slimmed down version of Header, primarily for communicating the highest block
/// with the P2P network and the RPC.
#[derive(
Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
)]
pub struct Head {
/// The number of the head block.
pub number: BlockNumber,
/// The hash of the head block.
pub hash: B256,
/// The difficulty of the head block.
pub difficulty: U256,
/// The total difficulty at the head block.
pub total_difficulty: U256,
/// The timestamp of the head block.
pub timestamp: u64,
}
28 changes: 28 additions & 0 deletions crates/ethereum-forks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Ethereum fork types used in reth.
//!
//! This crate contains Ethereum fork types and helper functions.
//!
//! ## Feature Flags
//!
//! - `arbitrary`: Adds `proptest` and `arbitrary` support for primitive types.

#![doc(
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![warn(missing_debug_implementations, missing_docs, unreachable_pub, rustdoc::all)]
#![deny(unused_must_use, rust_2018_idioms, unused_crate_dependencies)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![allow(clippy::non_canonical_clone_impl)]

mod forkid;
mod hardfork;
mod head;

pub use forkid::{ForkFilter, ForkFilterKey, ForkHash, ForkId, ForkTransition, ValidationError};
pub use hardfork::Hardfork;
pub use head::Head;

#[cfg(any(test, feature = "arbitrary"))]
pub use arbitrary;
2 changes: 1 addition & 1 deletion crates/net/dns/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ mod tests {

let mut builder = EnrBuilder::new("v4");
let mut buf = Vec::new();
let fork_id = Hardfork::Frontier.fork_id(&MAINNET).unwrap();
let fork_id = MAINNET.hardfork_fork_id(Hardfork::Frontier).unwrap();
fork_id.encode(&mut buf);
builder.ip4(Ipv4Addr::LOCALHOST).udp4(30303).tcp4(30303).add_value(b"eth", &buf);
let enr = builder.build(&secret_key).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/net/eth-wire/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use reth_primitives::{Chain, ForkId, B256, U256};
/// .total_difficulty(U256::from(100))
/// .blockhash(B256::from(MAINNET_GENESIS_HASH))
/// .genesis(B256::from(MAINNET_GENESIS_HASH))
/// .forkid(Hardfork::Paris.fork_id(&MAINNET).unwrap())
/// .forkid(MAINNET.hardfork_fork_id(Hardfork::Paris).unwrap())
/// .build();
///
/// assert_eq!(
Expand All @@ -28,7 +28,7 @@ use reth_primitives::{Chain, ForkId, B256, U256};
/// total_difficulty: U256::from(100),
/// blockhash: B256::from(MAINNET_GENESIS_HASH),
/// genesis: B256::from(MAINNET_GENESIS_HASH),
/// forkid: Hardfork::Paris.fork_id(&MAINNET).unwrap(),
/// forkid: MAINNET.hardfork_fork_id(Hardfork::Paris).unwrap(),
/// }
/// );
/// ```
Expand Down
4 changes: 2 additions & 2 deletions crates/net/eth-wire/src/types/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ impl Default for Status {
total_difficulty: U256::from(17_179_869_184u64),
blockhash: mainnet_genesis,
genesis: mainnet_genesis,
forkid: Hardfork::Frontier
.fork_id(&MAINNET)
forkid: MAINNET
.hardfork_fork_id(Hardfork::Frontier)
.expect("The Frontier hardfork should always exist"),
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/net/network/src/session/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,8 @@ mod tests {
secret_key,
local_peer_id,
status: StatusBuilder::default().build(),
fork_filter: Hardfork::Frontier
.fork_filter(&MAINNET)
fork_filter: MAINNET
.hardfork_fork_filter(Hardfork::Frontier)
.expect("The Frontier fork filter should exist on mainnet"),
bandwidth_meter: BandwidthMeter::default(),
}
Expand Down
54 changes: 31 additions & 23 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
name = "reth-primitives"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Commonly used types in reth."

[dependencies]
# reth
reth-codecs.workspace = true
reth-ethereum-forks.workspace = true
reth-rpc-types.workspace = true
revm-primitives.workspace = true
revm.workspace = true
revm-primitives.workspace = true

# ethereum
alloy-primitives = { workspace = true, features = ["rand", "rlp"] }
Expand All @@ -33,28 +34,28 @@ crc = "3"
tracing.workspace = true

# misc
bytes.workspace = true
byteorder = "1"
bytes.workspace = true
clap = { workspace = true, features = ["derive"], optional = true }
derive_more = "0.99"
itertools = "0.11"
modular-bitfield = "0.11.2"
num_enum = "0.7"
once_cell.workspace = true
rayon.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_with = "3.3.0"
thiserror.workspace = true
sha2 = "0.10.7"
sucds = "~0.6"
modular-bitfield = "0.11.2"
derive_more = "0.99"
tempfile.workspace = true
thiserror.workspace = true
url = "2.3"
once_cell.workspace = true
zstd = { version = "0.12", features = ["experimental"] }
rayon.workspace = true
tempfile.workspace = true
sha2 = "0.10.7"
itertools = "0.11"
num_enum = "0.7"

# `test-utils` feature
plain_hasher = { version = "0.2", optional = true }
hash-db = { version = "~0.15", optional = true }
plain_hasher = { version = "0.2", optional = true }

# arbitrary utils
arbitrary = { workspace = true, features = ["derive"], optional = true }
Expand All @@ -63,32 +64,39 @@ proptest-derive = { workspace = true, optional = true }
strum = { workspace = true, features = ["derive"] }

[dev-dependencies]
serde_json.workspace = true
test-fuzz = "4"
rand.workspace = true
revm-primitives = { workspace = true, features = ["arbitrary"] }
arbitrary = { workspace = true, features = ["derive"] }
assert_matches.workspace = true
proptest.workspace = true
proptest-derive.workspace = true
assert_matches.workspace = true
rand.workspace = true
revm-primitives = { workspace = true, features = ["arbitrary"] }
serde_json.workspace = true
test-fuzz = "4"
toml.workspace = true
triehash = "0.8"

plain_hasher = "0.2"
hash-db = "~0.15"
plain_hasher = "0.2"

# necessary so we don't hit a "undeclared 'std'":
# https://github.com/paradigmxyz/reth/pull/177#discussion_r1021172198
secp256k1.workspace = true
criterion.workspace = true
pprof = { workspace = true, features = ["flamegraph", "frame-pointer", "criterion"] }
secp256k1.workspace = true

[features]
default = ["c-kzg"]
arbitrary = ["revm-primitives/arbitrary", "reth-rpc-types/arbitrary", "dep:arbitrary", "dep:proptest", "dep:proptest-derive"]
arbitrary = [
"revm-primitives/arbitrary",
"reth-rpc-types/arbitrary",
"reth-ethereum-forks/arbitrary",
"dep:arbitrary",
"dep:proptest",
"dep:proptest-derive",
]
c-kzg = ["dep:c-kzg", "revm/c-kzg", "revm-primitives/c-kzg"]
clap = ["dep:clap"]
optimism = ["reth-codecs/optimism", "revm-primitives/optimism", "revm/optimism"]
optimism = ["reth-codecs/optimism", "revm-primitives/optimism", "reth-ethereum-forks/optimism", "revm/optimism"]
test-utils = ["dep:plain_hasher", "dep:hash-db", "dep:ethers-core"]

[[bench]]
Expand Down
Loading
Loading