diff --git a/.github/scripts/check_no_std.sh b/.github/scripts/check_no_std.sh new file mode 100755 index 0000000000000..8d64ad172b3b1 --- /dev/null +++ b/.github/scripts/check_no_std.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -eo pipefail + +# List of no_std packages +no_std_packages=( + reth-db + reth-network-peers +) + +# Loop through each package and check it for no_std compliance +for package in "${no_std_packages[@]}"; do + cmd="cargo +stable check -p $package --no-default-features" + + if [ -n "$CI" ]; then + echo "::group::$cmd" + else + printf "\n%s:\n %s\n" "$package" "$cmd" + fi + + $cmd + + if [ -n "$CI" ]; then + echo "::endgroup::" + fi +done diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index 6151c9569df1d..e34470e4dedd9 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and export reth image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . tags: ghcr.io/paradigmxyz/reth:latest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ffcb7f239a57d..c07cee38830b8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -45,6 +45,21 @@ jobs: env: RUSTFLAGS: -D warnings + no-std: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + target: riscv32imac-unknown-none-elf + - uses: taiki-e/install-action@cargo-hack + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - name: Run no_std checks + run: .github/scripts/check_no_std.sh + crate-checks: runs-on: ubuntu-latest timeout-minutes: 30 @@ -149,7 +164,15 @@ jobs: name: lint success runs-on: ubuntu-latest if: always() - needs: [clippy-binaries, clippy, crate-checks, docs, fmt, book, codespell, grafana] + needs: + - clippy-binaries + - clippy + - crate-checks + - docs + - fmt + - book + - codespell + - grafana timeout-minutes: 30 steps: - name: Decide whether the needed jobs succeeded or failed diff --git a/Cargo.lock b/Cargo.lock index 7bd86c79d6a9d..b5caa687f7283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2740,7 +2740,7 @@ dependencies = [ [[package]] name = "ef-tests" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "rayon", @@ -6425,7 +6425,7 @@ dependencies = [ [[package]] name = "reth" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "ahash", "alloy-rlp", @@ -6511,7 +6511,7 @@ dependencies = [ [[package]] name = "reth-auto-seal-consensus" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "futures-util", "reth-beacon-consensus", @@ -6536,7 +6536,7 @@ dependencies = [ [[package]] name = "reth-basic-payload-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "futures-core", @@ -6558,7 +6558,7 @@ dependencies = [ [[package]] name = "reth-beacon-consensus" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "assert_matches", "futures", @@ -6608,7 +6608,7 @@ dependencies = [ [[package]] name = "reth-bench" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6649,7 +6649,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "aquamarine", "assert_matches", @@ -6681,7 +6681,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-consensus", "reth-execution-errors", @@ -6692,7 +6692,7 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-chains", "alloy-eips", @@ -6715,7 +6715,7 @@ dependencies = [ [[package]] name = "reth-cli-runner" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-tasks", "tokio", @@ -6724,7 +6724,7 @@ dependencies = [ [[package]] name = "reth-codecs" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6743,7 +6743,7 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "convert_case 0.6.0", "proc-macro2", @@ -6754,7 +6754,7 @@ dependencies = [ [[package]] name = "reth-config" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "confy", "humantime-serde", @@ -6767,7 +6767,7 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "auto_impl", "reth-primitives", @@ -6776,7 +6776,7 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "mockall", "rand 0.8.5", @@ -6788,7 +6788,7 @@ dependencies = [ [[package]] name = "reth-consensus-debug-client" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6810,7 +6810,7 @@ dependencies = [ [[package]] name = "reth-db" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "arbitrary", "assert_matches", @@ -6848,7 +6848,7 @@ dependencies = [ [[package]] name = "reth-db-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "arbitrary", "assert_matches", @@ -6877,7 +6877,7 @@ dependencies = [ [[package]] name = "reth-db-common" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "eyre", "reth-chainspec", @@ -6898,7 +6898,7 @@ dependencies = [ [[package]] name = "reth-discv4" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -6913,7 +6913,6 @@ dependencies = [ "reth-net-common", "reth-net-nat", "reth-network-peers", - "reth-primitives", "reth-tracing", "schnellru", "secp256k1", @@ -6926,8 +6925,9 @@ dependencies = [ [[package]] name = "reth-discv5" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ + "alloy-primitives", "alloy-rlp", "derive_more", "discv5", @@ -6939,9 +6939,9 @@ dependencies = [ "multiaddr", "rand 0.8.5", "reth-chainspec", + "reth-ethereum-forks", "reth-metrics", "reth-network-peers", - "reth-primitives", "reth-tracing", "secp256k1", "thiserror", @@ -6951,7 +6951,7 @@ dependencies = [ [[package]] name = "reth-dns-discovery" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-chains", "alloy-primitives", @@ -6979,7 +6979,7 @@ dependencies = [ [[package]] name = "reth-downloaders" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "assert_matches", @@ -7013,7 +7013,7 @@ dependencies = [ [[package]] name = "reth-e2e-test-utils" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-network", @@ -7043,7 +7043,7 @@ dependencies = [ [[package]] name = "reth-ecies" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "aes 0.8.4", "alloy-primitives", @@ -7073,7 +7073,7 @@ dependencies = [ [[package]] name = "reth-engine-primitives" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-payload-primitives", @@ -7082,7 +7082,7 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-blockchain-tree-api", "reth-consensus", @@ -7094,7 +7094,7 @@ dependencies = [ [[package]] name = "reth-eth-wire" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "arbitrary", @@ -7129,7 +7129,7 @@ dependencies = [ [[package]] name = "reth-eth-wire-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "arbitrary", @@ -7152,7 +7152,7 @@ dependencies = [ [[package]] name = "reth-ethereum-consensus" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-consensus", @@ -7163,7 +7163,7 @@ dependencies = [ [[package]] name = "reth-ethereum-engine-primitives" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "reth-chainspec", @@ -7180,7 +7180,7 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-chains", "alloy-primitives", @@ -7195,7 +7195,7 @@ dependencies = [ [[package]] name = "reth-ethereum-payload-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-basic-payload-builder", "reth-errors", @@ -7212,17 +7212,17 @@ dependencies = [ [[package]] name = "reth-etl" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ + "alloy-primitives", "rayon", "reth-db-api", - "reth-primitives", "tempfile", ] [[package]] name = "reth-evm" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "auto_impl", "futures-util", @@ -7240,7 +7240,7 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-eips", "alloy-sol-types", @@ -7259,7 +7259,7 @@ dependencies = [ [[package]] name = "reth-evm-optimism" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-consensus-common", @@ -7278,7 +7278,7 @@ dependencies = [ [[package]] name = "reth-execution-errors" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7291,7 +7291,7 @@ dependencies = [ [[package]] name = "reth-execution-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7305,7 +7305,7 @@ dependencies = [ [[package]] name = "reth-exex" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "eyre", "metrics", @@ -7327,7 +7327,7 @@ dependencies = [ [[package]] name = "reth-exex-test-utils" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "eyre", "futures-util", @@ -7356,14 +7356,14 @@ dependencies = [ [[package]] name = "reth-exex-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", ] [[package]] name = "reth-fs-util" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "serde_json", "thiserror", @@ -7371,7 +7371,7 @@ dependencies = [ [[package]] name = "reth-ipc" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "async-trait", "bytes", @@ -7393,7 +7393,7 @@ dependencies = [ [[package]] name = "reth-libmdbx" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "bitflags 2.5.0", "byteorder", @@ -7413,7 +7413,7 @@ dependencies = [ [[package]] name = "reth-mdbx-sys" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "bindgen", "cc", @@ -7421,7 +7421,7 @@ dependencies = [ [[package]] name = "reth-metrics" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "futures", "metrics", @@ -7432,7 +7432,7 @@ dependencies = [ [[package]] name = "reth-metrics-derive" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "metrics", "once_cell", @@ -7446,7 +7446,7 @@ dependencies = [ [[package]] name = "reth-net-common" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "tokio", @@ -7454,7 +7454,7 @@ dependencies = [ [[package]] name = "reth-net-nat" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "futures-util", "reqwest", @@ -7466,7 +7466,7 @@ dependencies = [ [[package]] name = "reth-network" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-node-bindings", "alloy-provider", @@ -7522,7 +7522,7 @@ dependencies = [ [[package]] name = "reth-network-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "enr", @@ -7536,7 +7536,7 @@ dependencies = [ [[package]] name = "reth-network-p2p" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "auto_impl", "futures", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "reth-network-peers" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7570,7 +7570,7 @@ dependencies = [ [[package]] name = "reth-nippy-jar" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "anyhow", "bincode", @@ -7591,7 +7591,7 @@ dependencies = [ [[package]] name = "reth-node-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-db-api", "reth-engine-primitives", @@ -7606,7 +7606,7 @@ dependencies = [ [[package]] name = "reth-node-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "aquamarine", "backon", @@ -7656,7 +7656,7 @@ dependencies = [ [[package]] name = "reth-node-core" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rpc-types-engine", "clap", @@ -7720,8 +7720,10 @@ dependencies = [ [[package]] name = "reth-node-ethereum" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ + "alloy-genesis", + "alloy-primitives", "eyre", "futures", "futures-util", @@ -7742,7 +7744,6 @@ dependencies = [ "reth-node-builder", "reth-node-core", "reth-payload-builder", - "reth-primitives", "reth-provider", "reth-tracing", "reth-transaction-pool", @@ -7752,7 +7753,7 @@ dependencies = [ [[package]] name = "reth-node-events" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rpc-types-engine", "futures", @@ -7773,7 +7774,7 @@ dependencies = [ [[package]] name = "reth-node-optimism" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "async-trait", @@ -7815,7 +7816,7 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-consensus", @@ -7826,7 +7827,7 @@ dependencies = [ [[package]] name = "reth-optimism-payload-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "reth-basic-payload-builder", @@ -7849,15 +7850,14 @@ dependencies = [ [[package]] name = "reth-optimism-primitives" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" [[package]] name = "reth-payload-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "futures-util", "metrics", - "reth-engine-primitives", "reth-errors", "reth-ethereum-engine-primitives", "reth-metrics", @@ -7876,7 +7876,7 @@ dependencies = [ [[package]] name = "reth-payload-primitives" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-errors", @@ -7890,7 +7890,7 @@ dependencies = [ [[package]] name = "reth-payload-validator" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-chainspec", "reth-primitives", @@ -7900,7 +7900,7 @@ dependencies = [ [[package]] name = "reth-primitives" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7947,7 +7947,7 @@ dependencies = [ [[package]] name = "reth-primitives-traits" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7970,7 +7970,7 @@ dependencies = [ [[package]] name = "reth-provider" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "alloy-rpc-types-engine", @@ -8012,7 +8012,7 @@ dependencies = [ [[package]] name = "reth-prune" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "assert_matches", @@ -8025,10 +8025,10 @@ dependencies = [ "reth-errors", "reth-exex-types", "reth-metrics", - "reth-primitives", "reth-provider", "reth-prune-types", "reth-stages", + "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", "reth-tracing", @@ -8039,7 +8039,7 @@ dependencies = [ [[package]] name = "reth-prune-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "arbitrary", @@ -8059,7 +8059,7 @@ dependencies = [ [[package]] name = "reth-revm" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-eips", "alloy-rlp", @@ -8077,7 +8077,7 @@ dependencies = [ [[package]] name = "reth-rpc" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-dyn-abi", "alloy-primitives", @@ -8134,7 +8134,7 @@ dependencies = [ [[package]] name = "reth-rpc-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-dyn-abi", "jsonrpsee", @@ -8148,7 +8148,7 @@ dependencies = [ [[package]] name = "reth-rpc-api-testing-util" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "futures", "jsonrpsee", @@ -8162,7 +8162,7 @@ dependencies = [ [[package]] name = "reth-rpc-builder" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "clap", "http 1.1.0", @@ -8203,7 +8203,7 @@ dependencies = [ [[package]] name = "reth-rpc-engine-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "assert_matches", @@ -8235,7 +8235,7 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rpc-types-engine", "assert_matches", @@ -8252,7 +8252,7 @@ dependencies = [ [[package]] name = "reth-rpc-server-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "serde", @@ -8261,7 +8261,7 @@ dependencies = [ [[package]] name = "reth-rpc-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -8285,7 +8285,7 @@ dependencies = [ [[package]] name = "reth-rpc-types-compat" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "alloy-rpc-types", @@ -8297,7 +8297,7 @@ dependencies = [ [[package]] name = "reth-stages" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "assert_matches", @@ -8341,8 +8341,9 @@ dependencies = [ [[package]] name = "reth-stages-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ + "alloy-primitives", "aquamarine", "assert_matches", "auto_impl", @@ -8353,11 +8354,12 @@ dependencies = [ "reth-errors", "reth-metrics", "reth-network-p2p", - "reth-primitives", + "reth-primitives-traits", "reth-provider", "reth-prune", "reth-stages-types", "reth-static-file", + "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", "thiserror", @@ -8368,7 +8370,7 @@ dependencies = [ [[package]] name = "reth-stages-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "arbitrary", @@ -8385,18 +8387,19 @@ dependencies = [ [[package]] name = "reth-static-file" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ + "alloy-primitives", "assert_matches", "parking_lot 0.12.3", "rayon", "reth-db", "reth-db-api", "reth-nippy-jar", - "reth-primitives", "reth-provider", "reth-prune-types", "reth-stages", + "reth-static-file-types", "reth-storage-errors", "reth-testing-utils", "reth-tokio-util", @@ -8406,7 +8409,7 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-primitives", "clap", @@ -8417,7 +8420,7 @@ dependencies = [ [[package]] name = "reth-storage-api" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "auto_impl", "reth-chainspec", @@ -8433,7 +8436,7 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "reth-fs-util", "reth-primitives", @@ -8442,7 +8445,7 @@ dependencies = [ [[package]] name = "reth-tasks" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "dyn-clone", "futures-util", @@ -8458,7 +8461,7 @@ dependencies = [ [[package]] name = "reth-testing-utils" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-genesis", "rand 0.8.5", @@ -8468,7 +8471,7 @@ dependencies = [ [[package]] name = "reth-tokio-util" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "tokio", "tokio-stream", @@ -8477,7 +8480,7 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "clap", "eyre", @@ -8491,7 +8494,7 @@ dependencies = [ [[package]] name = "reth-transaction-pool" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "aquamarine", @@ -8528,7 +8531,7 @@ dependencies = [ [[package]] name = "reth-trie" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "auto_impl", @@ -8560,7 +8563,7 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -8588,7 +8591,7 @@ dependencies = [ [[package]] name = "reth-trie-parallel" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" dependencies = [ "alloy-rlp", "criterion", @@ -9580,6 +9583,23 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stateful-precompile" +version = "0.0.0" +dependencies = [ + "eyre", + "parking_lot 0.12.3", + "reth", + "reth-chainspec", + "reth-node-api", + "reth-node-core", + "reth-node-ethereum", + "reth-primitives", + "reth-tracing", + "schnellru", + "tokio", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7a8183eb855ae..65a33445da553 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" edition = "2021" rust-version = "1.79" license = "MIT OR Apache-2.0" @@ -109,6 +109,7 @@ members = [ "examples/custom-dev-node/", "examples/custom-engine-types/", "examples/custom-evm/", + "examples/stateful-precompile/", "examples/custom-inspector/", "examples/custom-node-components/", "examples/custom-payload-builder/", @@ -473,9 +474,7 @@ secp256k1 = { version = "0.29", default-features = false, features = [ "global-context", "recovery", ] } -# TODO: Remove `k256` feature: https://github.com/sigp/enr/pull/74 -enr = { version = "0.12.0", default-features = false, features = [ - "k256", +enr = { version = "0.12.1", default-features = false, features = [ "rust-secp256k1", ] } diff --git a/README.md b/README.md index 00b575a798e24..bfb1c6c65f1b9 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Reth is production ready, and suitable for usage in mission-critical environment More historical context below: * We released 1.0 "production-ready" stable Reth in June 2024. - * Reth completed an audit with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](./Sigma_Prime_Paradigm_Reth_Security_Assessment_Report_v1_0.pdf). + * Reth completed an audit with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](./audit/sigma_prime_audit_v1.pdf). * Revm (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)). We will publish the results soon. * We released multiple iterative beta versions, up to [beta.9](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.9) on Monday June 3rd 2024 the last beta release. * We released [beta](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) on Monday March 4th 2024, our first breaking change to the database model, providing faster query speed, smaller database footprint, and allowing "history" to be mounted on separate drives. diff --git a/Sigma_Prime_Paradigm_Reth_Security_Assessment_Report_v1_0.pdf b/audit/sigma_prime_audit_v1.pdf similarity index 100% rename from Sigma_Prime_Paradigm_Reth_Security_Assessment_Report_v1_0.pdf rename to audit/sigma_prime_audit_v1.pdf diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index f6ec9bd7d4409..5e0e7d2de0910 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -14,6 +14,7 @@ workspace = true [dependencies] # reth +reth-chainspec.workspace = true reth-config.workspace = true reth-primitives.workspace = true reth-fs-util.workspace = true diff --git a/bin/reth/src/cli/mod.rs b/bin/reth/src/cli/mod.rs index 60792cb76b144..8750b84f543a1 100644 --- a/bin/reth/src/cli/mod.rs +++ b/bin/reth/src/cli/mod.rs @@ -13,10 +13,10 @@ use crate::{ version::{LONG_VERSION, SHORT_VERSION}, }; use clap::{value_parser, Parser, Subcommand}; +use reth_chainspec::ChainSpec; use reth_cli_runner::CliRunner; use reth_db::DatabaseEnv; use reth_node_builder::{NodeBuilder, WithLaunchContext}; -use reth_primitives::ChainSpec; use reth_tracing::FileWorkerGuard; use std::{ffi::OsString, fmt, future::Future, sync::Arc}; use tracing::info; diff --git a/bin/reth/src/commands/common.rs b/bin/reth/src/commands/common.rs index ed6a92cdbc682..329047cdddaef 100644 --- a/bin/reth/src/commands/common.rs +++ b/bin/reth/src/commands/common.rs @@ -2,6 +2,7 @@ use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; +use reth_chainspec::ChainSpec; use reth_config::{config::EtlConfig, Config}; use reth_db::{init_db, open_db_read_only, DatabaseEnv}; use reth_db_common::init::init_genesis; @@ -14,7 +15,7 @@ use reth_node_core::{ }, dirs::{ChainPath, DataDirPath}, }; -use reth_primitives::{ChainSpec, B256}; +use reth_primitives::B256; use reth_provider::{providers::StaticFileProvider, ProviderFactory, StaticFileProviderFactory}; use reth_stages::{sets::DefaultStages, Pipeline, PipelineTarget}; use reth_static_file::StaticFileProducer; diff --git a/bin/reth/src/commands/dump_genesis.rs b/bin/reth/src/commands/dump_genesis.rs index 843d3d18a64b0..f4208584fbda1 100644 --- a/bin/reth/src/commands/dump_genesis.rs +++ b/bin/reth/src/commands/dump_genesis.rs @@ -1,7 +1,7 @@ //! Command that dumps genesis block JSON configuration to stdout use crate::args::utils::{chain_help, genesis_value_parser, SUPPORTED_CHAINS}; use clap::Parser; -use reth_primitives::ChainSpec; +use reth_chainspec::ChainSpec; use std::sync::Arc; /// Dumps genesis block JSON configuration to stdout @@ -39,7 +39,7 @@ mod tests { DumpGenesisCommand::parse_from(["reth", "--chain", chain]); assert_eq!( Ok(args.chain.chain), - chain.parse::(), + chain.parse::(), "failed to parse chain {chain}" ); } diff --git a/bin/reth/src/commands/import.rs b/bin/reth/src/commands/import.rs index baf194714573e..25d1864a2434e 100644 --- a/bin/reth/src/commands/import.rs +++ b/bin/reth/src/commands/import.rs @@ -237,7 +237,7 @@ mod tests { let args: ImportCommand = ImportCommand::parse_from(["reth", "--chain", chain, "."]); assert_eq!( Ok(args.env.chain.chain), - chain.parse::(), + chain.parse::(), "failed to parse chain {chain}" ); } diff --git a/bin/reth/src/commands/node/mod.rs b/bin/reth/src/commands/node/mod.rs index f11cb24ce682e..606e0de42bb25 100644 --- a/bin/reth/src/commands/node/mod.rs +++ b/bin/reth/src/commands/node/mod.rs @@ -6,11 +6,11 @@ use crate::args::{ RpcServerArgs, TxPoolArgs, }; use clap::{value_parser, Args, Parser}; +use reth_chainspec::ChainSpec; use reth_cli_runner::CliContext; use reth_db::{init_db, DatabaseEnv}; use reth_node_builder::{NodeBuilder, WithLaunchContext}; use reth_node_core::{node_config::NodeConfig, version}; -use reth_primitives::ChainSpec; use std::{ffi::OsString, fmt, future::Future, net::SocketAddr, path::PathBuf, sync::Arc}; /// Start the node @@ -213,7 +213,7 @@ mod tests { fn parse_common_node_command_chain_args() { for chain in SUPPORTED_CHAINS { let args: NodeCommand = NodeCommand::::parse_from(["reth", "--chain", chain]); - assert_eq!(args.chain.chain, chain.parse::().unwrap()); + assert_eq!(args.chain.chain, chain.parse::().unwrap()); } } @@ -305,7 +305,7 @@ mod tests { #[cfg(not(feature = "optimism"))] // dev mode not yet supported in op-reth fn parse_dev() { let cmd = NodeCommand::::parse_from(["reth", "--dev"]); - let chain = reth_primitives::DEV.clone(); + let chain = reth_chainspec::DEV.clone(); assert_eq!(cmd.chain.chain, chain.chain); assert_eq!(cmd.chain.genesis_hash, chain.genesis_hash); assert_eq!( diff --git a/bin/reth/src/commands/p2p/mod.rs b/bin/reth/src/commands/p2p/mod.rs index b57a2f07aaba3..2de5a9aa5cfff 100644 --- a/bin/reth/src/commands/p2p/mod.rs +++ b/bin/reth/src/commands/p2p/mod.rs @@ -11,12 +11,13 @@ use crate::{ use backon::{ConstantBuilder, Retryable}; use clap::{Parser, Subcommand}; use discv5::ListenConfig; +use reth_chainspec::ChainSpec; use reth_config::Config; use reth_db::create_db; use reth_network::NetworkConfigBuilder; use reth_network_p2p::bodies::client::BodiesClient; use reth_node_core::args::DatadirArgs; -use reth_primitives::{BlockHashOrNumber, ChainSpec}; +use reth_primitives::BlockHashOrNumber; use reth_provider::{providers::StaticFileProvider, ProviderFactory}; use std::{ net::{IpAddr, SocketAddrV4, SocketAddrV6}, diff --git a/bin/reth/src/utils.rs b/bin/reth/src/utils.rs index ca25506a91246..1dd4f6893c1f6 100644 --- a/bin/reth/src/utils.rs +++ b/bin/reth/src/utils.rs @@ -2,6 +2,7 @@ use boyer_moore_magiclen::BMByte; use eyre::Result; +use reth_chainspec::ChainSpec; use reth_db::{RawTable, TableRawRow}; use reth_db_api::{ cursor::{DbCursorRO, DbDupCursorRO}, @@ -11,7 +12,6 @@ use reth_db_api::{ DatabaseError, }; use reth_fs_util as fs; -use reth_primitives::ChainSpec; use reth_provider::{ChainSpecProvider, ProviderFactory}; use std::{path::Path, rc::Rc, sync::Arc}; use tracing::info; diff --git a/book/run/transactions.md b/book/run/transactions.md index 65aa979e238e3..61327b57300a3 100644 --- a/book/run/transactions.md +++ b/book/run/transactions.md @@ -1,6 +1,6 @@ # Transaction types -Over time, the Ethereum network has undergone various upgrades and improvements to enhance transaction efficiency, security, and user experience. Three significant transaction types that have evolved are: +Over time, the Ethereum network has undergone various upgrades and improvements to enhance transaction efficiency, security, and user experience. Four significant transaction types that have evolved are: - Legacy Transactions, - EIP-2930 Transactions, @@ -46,4 +46,4 @@ Alongside the legacy parameters & parameters from EIP-1559, the EIP-4844 transac - `max_fee_per_blob_gas`, The maximum total fee per gas the sender is willing to pay for blob gas in wei - `blob_versioned_hashes`, List of versioned blob hashes associated with the transaction's EIP-4844 data blobs. -The actual blob fee is deducted from the sender balance before transaction execution and burned, and is not refunded in case of transaction failure. \ No newline at end of file +The actual blob fee is deducted from the sender balance before transaction execution and burned, and is not refunded in case of transaction failure. diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 5bd75590b5044..0000000000000 --- a/codecov.yml +++ /dev/null @@ -1,68 +0,0 @@ -coverage: - status: - patch: off - project: - default: - threshold: null - informational: true -github_checks: - annotations: false -comment: - layout: "reach, files, flags, components" - require_changes: true -component_management: - individual_components: - - component_id: reth_binary - name: reth binary - paths: - - bin/** - - crates/config/** - - crates/metrics/** - - crates/tracing/** - - component_id: blockchain_tree - name: blockchain tree - paths: - - crates/blockchain-tree/** - - component_id: staged_sync - name: pipeline - paths: - - crates/stages/** - - component_id: storage - name: storage (db) - paths: - - crates/storage/** - - component_id: trie - name: trie - paths: - - crates/trie/** - - component_id: txpool - name: txpool - paths: - - crates/transaction-pool/** - - component_id: networking - name: networking - paths: - - crates/net/** - - component_id: rpc - name: rpc - paths: - - crates/rpc/** - - component_id: consensus - name: consensus - paths: - - crates/consensus/** - - component_id: revm - name: revm - paths: - - crates/revm/** - - component_id: builder - name: payload builder - paths: - - crates/payload/** - - component_id: primitives - name: primitives - paths: - - crates/primitives/** - - crates/tasks/** - - crates/rlp/** - - crates/interfaces/** \ No newline at end of file diff --git a/crates/chainspec/src/lib.rs b/crates/chainspec/src/lib.rs index 6da5ab470c3ac..892cfa1814b75 100644 --- a/crates/chainspec/src/lib.rs +++ b/crates/chainspec/src/lib.rs @@ -12,8 +12,7 @@ pub use alloy_chains::{Chain, ChainKind, NamedChain}; pub use info::ChainInfo; pub use spec::{ AllGenesisFormats, BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, - DepositContract, DisplayHardforks, ForkBaseFeeParams, ForkCondition, DEV, GOERLI, HOLESKY, - MAINNET, SEPOLIA, + DepositContract, ForkBaseFeeParams, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA, }; #[cfg(feature = "optimism")] pub use spec::{BASE_MAINNET, BASE_SEPOLIA, OP_MAINNET, OP_SEPOLIA}; diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 2462da93a12c4..b28c75778022d 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -11,13 +11,11 @@ use alloy_chains::{Chain, ChainKind, NamedChain}; use alloy_genesis::Genesis; use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; use alloy_trie::EMPTY_ROOT_HASH; -use core::{ - fmt, - fmt::{Display, Formatter}, -}; use derive_more::From; use once_cell::sync::Lazy; -use reth_ethereum_forks::{ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Head}; +use reth_ethereum_forks::{ + DisplayHardforks, ForkCondition, ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Head, +}; use reth_network_peers::NodeRecord; use reth_primitives_traits::{ constants::{ @@ -853,6 +851,13 @@ impl ChainSpec { self.fork(Hardfork::Homestead).active_at_block(block_number) } + /// The Paris hardfork (merge) is activated via ttd. If we have knowledge of the block, this + /// function will return true if the block number is greater than or equal to the Paris + /// (merge) block. + pub fn is_paris_active_at_block(&self, block_number: u64) -> Option { + self.paris_block_and_final_difficulty.map(|(paris_block, _)| block_number >= paris_block) + } + /// Convenience method to check if [`Hardfork::Bedrock`] is active at a given block number. #[cfg(feature = "optimism")] #[inline] @@ -1360,275 +1365,6 @@ impl From<&Arc> for ChainSpecBuilder { } } -/// The condition at which a fork is activated. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] -pub enum ForkCondition { - /// The fork is activated after a certain block. - Block(BlockNumber), - /// The fork is activated after a total difficulty has been reached. - TTD { - /// The block number at which TTD is reached, if it is known. - /// - /// This should **NOT** be set unless you want this block advertised as [EIP-2124][eip2124] - /// `FORK_NEXT`. This is currently only the case for Sepolia and Holesky. - /// - /// [eip2124]: https://eips.ethereum.org/EIPS/eip-2124 - fork_block: Option, - /// The total difficulty after which the fork is activated. - total_difficulty: U256, - }, - /// The fork is activated after a specific timestamp. - Timestamp(u64), - /// The fork is never activated - #[default] - Never, -} - -impl ForkCondition { - /// Returns true if the fork condition is timestamp based. - pub const fn is_timestamp(&self) -> bool { - matches!(self, Self::Timestamp(_)) - } - - /// Checks whether the fork condition is satisfied at the given block. - /// - /// For TTD conditions, this will only return true if the activation block is already known. - /// - /// For timestamp conditions, this will always return false. - pub const fn active_at_block(&self, current_block: BlockNumber) -> bool { - matches!(self, Self::Block(block) - | Self::TTD { fork_block: Some(block), .. } if current_block >= *block) - } - - /// Checks if the given block is the first block that satisfies the fork condition. - /// - /// This will return false for any condition that is not block based. - pub const fn transitions_at_block(&self, current_block: BlockNumber) -> bool { - matches!(self, Self::Block(block) if current_block == *block) - } - - /// Checks whether the fork condition is satisfied at the given total difficulty and difficulty - /// of a current block. - /// - /// The fork is considered active if the _previous_ total difficulty is above the threshold. - /// To achieve that, we subtract the passed `difficulty` from the current block's total - /// difficulty, and check if it's above the Fork Condition's total difficulty (here: - /// `58_750_000_000_000_000_000_000`) - /// - /// This will return false for any condition that is not TTD-based. - pub fn active_at_ttd(&self, ttd: U256, difficulty: U256) -> bool { - matches!(self, Self::TTD { total_difficulty, .. } - if ttd.saturating_sub(difficulty) >= *total_difficulty) - } - - /// Checks whether the fork condition is satisfied at the given timestamp. - /// - /// This will return false for any condition that is not timestamp-based. - pub const fn active_at_timestamp(&self, timestamp: u64) -> bool { - matches!(self, Self::Timestamp(time) if timestamp >= *time) - } - - /// Checks whether the fork condition is satisfied at the given head block. - /// - /// This will return true if: - /// - /// - The condition is satisfied by the block number; - /// - The condition is satisfied by the timestamp; - /// - or the condition is satisfied by the total difficulty - pub fn active_at_head(&self, head: &Head) -> bool { - self.active_at_block(head.number) || - self.active_at_timestamp(head.timestamp) || - self.active_at_ttd(head.total_difficulty, head.difficulty) - } - - /// Get the total terminal difficulty for this fork condition. - /// - /// Returns `None` for fork conditions that are not TTD based. - pub const fn ttd(&self) -> Option { - match self { - Self::TTD { total_difficulty, .. } => Some(*total_difficulty), - _ => None, - } - } - - /// Returns the timestamp of the fork condition, if it is timestamp based. - pub const fn as_timestamp(&self) -> Option { - match self { - Self::Timestamp(timestamp) => Some(*timestamp), - _ => None, - } - } -} - -/// A container to pretty-print a hardfork. -/// -/// The fork is formatted depending on its fork condition: -/// -/// - Block and timestamp based forks are formatted in the same manner (`{name} <({eip})> -/// @{condition}`) -/// - TTD based forks are formatted separately as `{name} <({eip})> @{ttd} (network is known -/// to be merged)` -/// -/// An optional EIP can be attached to the fork to display as well. This should generally be in the -/// form of just `EIP-x`, e.g. `EIP-1559`. -#[derive(Debug)] -struct DisplayFork { - /// The name of the hardfork (e.g. Frontier) - name: String, - /// The fork condition - activated_at: ForkCondition, - /// An optional EIP (e.g. `EIP-1559`). - eip: Option, -} - -impl Display for DisplayFork { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let name_with_eip = if let Some(eip) = &self.eip { - format!("{} ({})", self.name, eip) - } else { - self.name.clone() - }; - - match self.activated_at { - ForkCondition::Block(at) | ForkCondition::Timestamp(at) => { - write!(f, "{name_with_eip:32} @{at}")?; - } - ForkCondition::TTD { fork_block, total_difficulty } => { - write!( - f, - "{:32} @{} ({})", - name_with_eip, - total_difficulty, - if fork_block.is_some() { - "network is known to be merged" - } else { - "network is not known to be merged" - } - )?; - } - ForkCondition::Never => unreachable!(), - } - - Ok(()) - } -} - -/// A container for pretty-printing a list of hardforks. -/// -/// # Examples -/// -/// ``` -/// # use reth_chainspec::MAINNET; -/// println!("{}", MAINNET.display_hardforks()); -/// ``` -/// -/// An example of the output: -/// -/// ```text -/// Pre-merge hard forks (block based): -// - Frontier @0 -// - Homestead @1150000 -// - Dao @1920000 -// - Tangerine @2463000 -// - SpuriousDragon @2675000 -// - Byzantium @4370000 -// - Constantinople @7280000 -// - Petersburg @7280000 -// - Istanbul @9069000 -// - MuirGlacier @9200000 -// - Berlin @12244000 -// - London @12965000 -// - ArrowGlacier @13773000 -// - GrayGlacier @15050000 -// Merge hard forks: -// - Paris @58750000000000000000000 (network is known to be merged) -// Post-merge hard forks (timestamp based): -// - Shanghai @1681338455 -/// ``` -#[derive(Debug)] -pub struct DisplayHardforks { - /// A list of pre-merge (block based) hardforks - pre_merge: Vec, - /// A list of merge (TTD based) hardforks - with_merge: Vec, - /// A list of post-merge (timestamp based) hardforks - post_merge: Vec, -} - -impl Display for DisplayHardforks { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - fn format( - header: &str, - forks: &[DisplayFork], - next_is_empty: bool, - f: &mut Formatter<'_>, - ) -> fmt::Result { - writeln!(f, "{header}:")?; - let mut iter = forks.iter().peekable(); - while let Some(fork) = iter.next() { - write!(f, "- {fork}")?; - if !next_is_empty || iter.peek().is_some() { - writeln!(f)?; - } - } - Ok(()) - } - - format( - "Pre-merge hard forks (block based)", - &self.pre_merge, - self.with_merge.is_empty(), - f, - )?; - - if !self.with_merge.is_empty() { - format("Merge hard forks", &self.with_merge, self.post_merge.is_empty(), f)?; - } - - if !self.post_merge.is_empty() { - format("Post-merge hard forks (timestamp based)", &self.post_merge, true, f)?; - } - - Ok(()) - } -} - -impl DisplayHardforks { - /// Creates a new [`DisplayHardforks`] from an iterator of hardforks. - pub fn new( - hardforks: &BTreeMap, - known_paris_block: Option, - ) -> Self { - let mut pre_merge = Vec::new(); - let mut with_merge = Vec::new(); - let mut post_merge = Vec::new(); - - for (fork, condition) in hardforks { - let mut display_fork = - DisplayFork { name: fork.to_string(), activated_at: *condition, eip: None }; - - match condition { - ForkCondition::Block(_) => { - pre_merge.push(display_fork); - } - ForkCondition::TTD { total_difficulty, .. } => { - display_fork.activated_at = ForkCondition::TTD { - fork_block: known_paris_block, - total_difficulty: *total_difficulty, - }; - with_merge.push(display_fork); - } - ForkCondition::Timestamp(_) => { - post_merge.push(display_fork); - } - ForkCondition::Never => continue, - } - } - - Self { pre_merge, with_merge, post_merge } - } -} - /// `PoS` deposit contract details. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DepositContract { @@ -1734,7 +1470,7 @@ impl OptimismGenesisInfo { mod tests { use alloy_chains::Chain; use alloy_genesis::{ChainConfig, GenesisAccount}; - use reth_ethereum_forks::{ForkHash, ForkId, Head}; + use reth_ethereum_forks::{ForkCondition, ForkHash, ForkId, Head}; use reth_trie_common::TrieAccount; use super::*; diff --git a/crates/consensus/common/src/calc.rs b/crates/consensus/common/src/calc.rs index 52206bbfd0caa..27320700b33ec 100644 --- a/crates/consensus/common/src/calc.rs +++ b/crates/consensus/common/src/calc.rs @@ -1,5 +1,6 @@ use reth_chainspec::{Chain, ChainSpec, Hardfork}; use reth_primitives::{constants::ETH_TO_WEI, BlockNumber, U256}; + /// Calculates the base block reward. /// /// The base block reward is defined as: @@ -25,16 +26,25 @@ pub fn base_block_reward( block_difficulty: U256, total_difficulty: U256, ) -> Option { - if chain_spec.chain == Chain::goerli() || - chain_spec.fork(Hardfork::Paris).active_at_ttd(total_difficulty, block_difficulty) + if chain_spec.fork(Hardfork::Paris).active_at_ttd(total_difficulty, block_difficulty) || + chain_spec.chain == Chain::goerli() { None - } else if chain_spec.fork(Hardfork::Constantinople).active_at_block(block_number) { - Some(ETH_TO_WEI * 2) + } else { + Some(base_block_reward_pre_merge(chain_spec, block_number)) + } +} + +/// Calculates the base block reward __before__ the merge (Paris hardfork). +/// +/// Caution: The caller must ensure that the block number is before the merge. +pub fn base_block_reward_pre_merge(chain_spec: &ChainSpec, block_number: BlockNumber) -> u128 { + if chain_spec.fork(Hardfork::Constantinople).active_at_block(block_number) { + ETH_TO_WEI * 2 } else if chain_spec.fork(Hardfork::Byzantium).active_at_block(block_number) { - Some(ETH_TO_WEI * 3) + ETH_TO_WEI * 3 } else { - Some(ETH_TO_WEI * 5) + ETH_TO_WEI * 5 } } diff --git a/crates/ethereum-forks/src/lib.rs b/crates/ethereum-forks/src/lib.rs index 8457a5f6206bc..c7831026905fb 100644 --- a/crates/ethereum-forks/src/lib.rs +++ b/crates/ethereum-forks/src/lib.rs @@ -20,6 +20,8 @@ #[cfg(not(feature = "std"))] extern crate alloc; +mod display; +mod forkcondition; mod forkid; mod hardfork; mod head; @@ -30,5 +32,8 @@ pub use forkid::{ pub use hardfork::Hardfork; pub use head::Head; +pub use display::DisplayHardforks; +pub use forkcondition::ForkCondition; + #[cfg(any(test, feature = "arbitrary"))] pub use arbitrary; diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index f9a5b752d20c0..8bc6a9e8507c6 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -467,11 +467,10 @@ mod tests { keccak256, public_key_to_address, Account, Block, Transaction, TxKind, TxLegacy, B256, }; use reth_revm::{ - database::StateProviderDatabase, state_change::HISTORY_SERVE_WINDOW, - test_utils::StateProviderTest, TransitionState, + database::StateProviderDatabase, test_utils::StateProviderTest, TransitionState, }; use reth_testing_utils::generators::{self, sign_tx_with_key_pair}; - use revm_primitives::{b256, fixed_bytes, Bytes}; + use revm_primitives::{b256, fixed_bytes, Bytes, BLOCKHASH_SERVE_WINDOW}; use secp256k1::{Keypair, Secp256k1}; use std::collections::HashMap; @@ -976,7 +975,7 @@ mod tests { #[test] fn eip_2935_fork_activation_within_window_bounds() { - let fork_activation_block = HISTORY_SERVE_WINDOW - 10; + let fork_activation_block = (BLOCKHASH_SERVE_WINDOW - 10) as u64; let db = create_state_provider_with_block_hashes(fork_activation_block); let chain_spec = Arc::new( @@ -1039,7 +1038,7 @@ mod tests { #[test] fn eip_2935_fork_activation_outside_window_bounds() { - let fork_activation_block = HISTORY_SERVE_WINDOW + 256; + let fork_activation_block = (BLOCKHASH_SERVE_WINDOW + 256) as u64; let db = create_state_provider_with_block_hashes(fork_activation_block); let chain_spec = Arc::new( @@ -1090,7 +1089,7 @@ mod tests { .state_mut() .storage( HISTORY_STORAGE_ADDRESS, - U256::from(fork_activation_block % HISTORY_SERVE_WINDOW - 1) + U256::from(fork_activation_block % BLOCKHASH_SERVE_WINDOW as u64 - 1) ) .unwrap(), U256::ZERO diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index a8880de1b6e93..54e54a0ebb761 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -36,8 +36,9 @@ reth-db.workspace = true reth-exex.workspace = true reth-node-api.workspace = true reth-node-core.workspace = true -reth-primitives.workspace = true reth-e2e-test-utils.workspace = true +alloy-primitives.workspace = true +alloy-genesis.workspace = true futures.workspace = true tokio.workspace = true futures-util.workspace = true diff --git a/crates/ethereum/node/tests/e2e/blobs.rs b/crates/ethereum/node/tests/e2e/blobs.rs index 60785f3226adc..9390b34f444a3 100644 --- a/crates/ethereum/node/tests/e2e/blobs.rs +++ b/crates/ethereum/node/tests/e2e/blobs.rs @@ -1,5 +1,7 @@ use std::sync::Arc; +use alloy_genesis::Genesis; +use alloy_primitives::b256; use reth::{ args::RpcServerArgs, builder::{NodeBuilder, NodeConfig, NodeHandle}, @@ -11,7 +13,6 @@ use reth_e2e_test_utils::{ node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, }; use reth_node_ethereum::EthereumNode; -use reth_primitives::{b256, Genesis}; use reth_transaction_pool::TransactionPool; use crate::utils::eth_payload_attributes; diff --git a/crates/ethereum/node/tests/e2e/dev.rs b/crates/ethereum/node/tests/e2e/dev.rs index 0c3b3bc725605..990c6f0bf2b01 100644 --- a/crates/ethereum/node/tests/e2e/dev.rs +++ b/crates/ethereum/node/tests/e2e/dev.rs @@ -1,9 +1,10 @@ use crate::utils::EthNode; +use alloy_genesis::Genesis; +use alloy_primitives::{b256, hex}; use futures::StreamExt; use reth::rpc::eth::EthTransactions; use reth_chainspec::ChainSpec; use reth_e2e_test_utils::setup; -use reth_primitives::{b256, hex, Genesis}; use reth_provider::CanonStateSubscriptions; use std::sync::Arc; diff --git a/crates/ethereum/node/tests/e2e/eth.rs b/crates/ethereum/node/tests/e2e/eth.rs index ecbbe8f5d6968..8e6938b47fe42 100644 --- a/crates/ethereum/node/tests/e2e/eth.rs +++ b/crates/ethereum/node/tests/e2e/eth.rs @@ -1,4 +1,5 @@ use crate::utils::eth_payload_attributes; +use alloy_genesis::Genesis; use reth::{ args::RpcServerArgs, builder::{NodeBuilder, NodeConfig, NodeHandle}, @@ -9,7 +10,6 @@ use reth_e2e_test_utils::{ node::NodeTestContext, setup, transaction::TransactionTestContext, wallet::Wallet, }; use reth_node_ethereum::EthereumNode; -use reth_primitives::Genesis; use std::sync::Arc; #[tokio::test] diff --git a/crates/ethereum/node/tests/e2e/utils.rs b/crates/ethereum/node/tests/e2e/utils.rs index 2c1dc373b82e1..001cf02ce017d 100644 --- a/crates/ethereum/node/tests/e2e/utils.rs +++ b/crates/ethereum/node/tests/e2e/utils.rs @@ -1,8 +1,8 @@ +use alloy_primitives::{Address, B256}; use reth::rpc::types::engine::PayloadAttributes; use reth_e2e_test_utils::NodeHelperType; use reth_node_ethereum::EthereumNode; use reth_payload_builder::EthPayloadBuilderAttributes; -use reth_primitives::{Address, B256}; /// Ethereum Node Helper type pub(crate) type EthNode = NodeHelperType; diff --git a/crates/etl/Cargo.toml b/crates/etl/Cargo.toml index e05524306d6f3..1ca10d620d04b 100644 --- a/crates/etl/Cargo.toml +++ b/crates/etl/Cargo.toml @@ -13,4 +13,4 @@ reth-db-api.workspace = true rayon.workspace = true [dev-dependencies] -reth-primitives.workspace = true +alloy-primitives.workspace = true diff --git a/crates/etl/src/lib.rs b/crates/etl/src/lib.rs index 2dbf4cada4fa7..137a96fff1c49 100644 --- a/crates/etl/src/lib.rs +++ b/crates/etl/src/lib.rs @@ -271,7 +271,7 @@ impl EtlFile { #[cfg(test)] mod tests { - use reth_primitives::{TxHash, TxNumber}; + use alloy_primitives::{TxHash, TxNumber}; use super::*; diff --git a/crates/net/discv4/Cargo.toml b/crates/net/discv4/Cargo.toml index 5e6a9e4115599..8c823d5209ecb 100644 --- a/crates/net/discv4/Cargo.toml +++ b/crates/net/discv4/Cargo.toml @@ -45,7 +45,6 @@ serde = { workspace = true, optional = true } [dev-dependencies] reth-chainspec.workspace = true -reth-primitives.workspace = true assert_matches.workspace = true rand.workspace = true tokio = { workspace = true, features = ["macros"] } diff --git a/crates/net/discv4/src/lib.rs b/crates/net/discv4/src/lib.rs index 47f810d963372..50311fd3c00fc 100644 --- a/crates/net/discv4/src/lib.rs +++ b/crates/net/discv4/src/lib.rs @@ -2285,10 +2285,11 @@ pub enum DiscoveryUpdate { mod tests { use super::*; use crate::test_utils::{create_discv4, create_discv4_with_config, rng_endpoint, rng_record}; + use alloy_primitives::hex; use alloy_rlp::{Decodable, Encodable}; use rand::{thread_rng, Rng}; use reth_chainspec::net::mainnet_nodes; - use reth_primitives::{hex, EnrForkIdEntry, ForkHash}; + use reth_ethereum_forks::{EnrForkIdEntry, ForkHash}; use std::future::poll_fn; #[tokio::test] diff --git a/crates/net/discv4/src/proto.rs b/crates/net/discv4/src/proto.rs index 610628d56b4f7..6d2639f2d6f99 100644 --- a/crates/net/discv4/src/proto.rs +++ b/crates/net/discv4/src/proto.rs @@ -542,10 +542,11 @@ mod tests { test_utils::{rng_endpoint, rng_ipv4_record, rng_ipv6_record, rng_message}, DEFAULT_DISCOVERY_PORT, SAFE_MAX_DATAGRAM_NEIGHBOUR_RECORDS, }; + use alloy_primitives::hex; use assert_matches::assert_matches; use enr::EnrPublicKey; use rand::{thread_rng, Rng, RngCore}; - use reth_primitives::{hex, ForkHash}; + use reth_ethereum_forks::ForkHash; #[test] fn test_endpoint_ipv_v4() { diff --git a/crates/net/discv5/Cargo.toml b/crates/net/discv5/Cargo.toml index 1ba0fa47f0b53..e92618466ff3b 100644 --- a/crates/net/discv5/Cargo.toml +++ b/crates/net/discv5/Cargo.toml @@ -14,11 +14,12 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true -reth-primitives.workspace = true +reth-ethereum-forks.workspace = true reth-metrics.workspace = true reth-network-peers = { workspace = true, features = ["secp256k1"] } # ethereum +alloy-primitives.workspace = true alloy-rlp.workspace = true discv5 = { workspace = true, features = ["libp2p"] } enr.workspace = true diff --git a/crates/net/discv5/src/config.rs b/crates/net/discv5/src/config.rs index e2808a03c6737..da36d8f1c81fb 100644 --- a/crates/net/discv5/src/config.rs +++ b/crates/net/discv5/src/config.rs @@ -6,11 +6,12 @@ use std::{ net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, }; +use alloy_primitives::Bytes; use derive_more::Display; use discv5::ListenConfig; use multiaddr::{Multiaddr, Protocol}; +use reth_ethereum_forks::{EnrForkIdEntry, ForkId}; use reth_network_peers::NodeRecord; -use reth_primitives::{Bytes, EnrForkIdEntry, ForkId}; use tracing::warn; use crate::{enr::discv4_id_to_multiaddr_id, filter::MustNotIncludeKeys, NetworkStackId}; @@ -189,7 +190,7 @@ impl ConfigBuilder { self } - /// Sets the the number of times at which to run boost lookup queries to bootstrap the node. + /// Sets the number of times at which to run boost lookup queries to bootstrap the node. pub const fn bootstrap_lookup_countdown(mut self, counts: u64) -> Self { self.bootstrap_lookup_countdown = Some(counts); self @@ -448,7 +449,7 @@ impl BootNode { mod test { use std::net::SocketAddrV4; - use reth_primitives::hex; + use alloy_primitives::hex; use super::*; diff --git a/crates/net/discv5/src/error.rs b/crates/net/discv5/src/error.rs index 27763146481c2..73b05ee81b2aa 100644 --- a/crates/net/discv5/src/error.rs +++ b/crates/net/discv5/src/error.rs @@ -17,7 +17,7 @@ pub enum Error { /// Missing key used to identify rlpx network. #[error("fork missing on enr, key missing")] ForkMissing(&'static [u8]), - /// Failed to decode [`ForkId`](reth_primitives::ForkId) rlp value. + /// Failed to decode [`ForkId`](reth_ethereum_forks::ForkId) rlp value. #[error("failed to decode fork id, 'eth': {0:?}")] ForkIdDecodeError(#[from] alloy_rlp::Error), /// Peer is unreachable over discovery. diff --git a/crates/net/discv5/src/lib.rs b/crates/net/discv5/src/lib.rs index 728c44791d164..5b0044a721f5c 100644 --- a/crates/net/discv5/src/lib.rs +++ b/crates/net/discv5/src/lib.rs @@ -17,13 +17,14 @@ use std::{ }; use ::enr::Enr; +use alloy_primitives::bytes::Bytes; use discv5::ListenConfig; use enr::{discv4_id_to_discv5_id, EnrCombinedKeyWrapper}; use futures::future::join_all; use itertools::Itertools; use rand::{Rng, RngCore}; +use reth_ethereum_forks::{EnrForkIdEntry, ForkId}; use reth_network_peers::{NodeRecord, PeerId}; -use reth_primitives::{bytes::Bytes, EnrForkIdEntry, ForkId}; use secp256k1::SecretKey; use tokio::{sync::mpsc, task}; use tracing::{debug, error, trace}; @@ -66,7 +67,7 @@ pub const DEFAULT_MIN_TARGET_KBUCKET_INDEX: usize = 0; pub struct Discv5 { /// sigp/discv5 node. discv5: Arc, - /// [`IpMode`] of the the `RLPx` network. + /// [`IpMode`] of the `RLPx` network. rlpx_ip_mode: IpMode, /// Key used in kv-pair to ID chain, e.g. 'opstack' or 'eth'. fork_key: Option<&'static [u8]>, @@ -777,11 +778,11 @@ mod test { #[allow(unused)] #[allow(clippy::assign_op_pattern)] mod sigp { + use alloy_primitives::U256; use enr::{ k256::sha2::digest::generic_array::{typenum::U32, GenericArray}, NodeId, }; - use reth_primitives::U256; /// A `Key` is a cryptographic hash, identifying both the nodes participating in /// the Kademlia DHT, as well as records stored in the DHT. diff --git a/crates/net/discv5/src/network_stack_id.rs b/crates/net/discv5/src/network_stack_id.rs index 5fcb1ae41b55f..e41284c316988 100644 --- a/crates/net/discv5/src/network_stack_id.rs +++ b/crates/net/discv5/src/network_stack_id.rs @@ -1,5 +1,5 @@ -//! Keys of ENR [`ForkId`](reth_primitives::ForkId) kv-pair. Identifies which network stack a node -//! belongs to. +//! Keys of ENR [`ForkId`](reth_ethereum_forks::ForkId) kv-pair. Identifies which network stack a +//! node belongs to. use reth_chainspec::ChainSpec; diff --git a/crates/net/peers/Cargo.toml b/crates/net/peers/Cargo.toml index 854ca3fbd5c8c..6b107432632e0 100644 --- a/crates/net/peers/Cargo.toml +++ b/crates/net/peers/Cargo.toml @@ -34,4 +34,4 @@ secp256k1 = { workspace = true, features = ["rand"] } serde_json.workspace = true [features] -secp256k1 = ["dep:secp256k1"] +secp256k1 = ["dep:secp256k1", "enr/secp256k1"] diff --git a/crates/payload/builder/Cargo.toml b/crates/payload/builder/Cargo.toml index ce82ae7ff8a79..735831e41ca15 100644 --- a/crates/payload/builder/Cargo.toml +++ b/crates/payload/builder/Cargo.toml @@ -18,7 +18,6 @@ reth-rpc-types.workspace = true reth-transaction-pool.workspace = true reth-errors.workspace = true reth-provider.workspace = true -reth-engine-primitives.workspace = true reth-payload-primitives.workspace = true reth-ethereum-engine-primitives.workspace = true diff --git a/crates/payload/builder/src/events.rs b/crates/payload/builder/src/events.rs index 4df81030fca89..271eb2267ec4f 100644 --- a/crates/payload/builder/src/events.rs +++ b/crates/payload/builder/src/events.rs @@ -1,4 +1,4 @@ -use reth_engine_primitives::EngineTypes; +use reth_payload_primitives::PayloadTypes; use tokio::sync::broadcast; use tokio_stream::{ wrappers::{errors::BroadcastStreamRecvError, BroadcastStream}, @@ -7,7 +7,7 @@ use tokio_stream::{ /// Payload builder events. #[derive(Clone, Debug)] -pub enum Events { +pub enum Events { /// The payload attributes as /// they are received from the CL through the engine api. Attributes(Engine::PayloadBuilderAttributes), @@ -19,11 +19,11 @@ pub enum Events { /// Represents a receiver for various payload events. #[derive(Debug)] -pub struct PayloadEvents { +pub struct PayloadEvents { pub receiver: broadcast::Receiver>, } -impl PayloadEvents { +impl PayloadEvents { // Convert this receiver into a stream of PayloadEvents. pub fn into_stream(self) -> BroadcastStream> { BroadcastStream::new(self.receiver) diff --git a/crates/payload/builder/src/noop.rs b/crates/payload/builder/src/noop.rs index ef919ecf76e8b..91ab90732166c 100644 --- a/crates/payload/builder/src/noop.rs +++ b/crates/payload/builder/src/noop.rs @@ -2,8 +2,7 @@ use crate::{service::PayloadServiceCommand, PayloadBuilderHandle}; use futures_util::{ready, StreamExt}; -use reth_engine_primitives::EngineTypes; -use reth_payload_primitives::PayloadBuilderAttributes; +use reth_payload_primitives::{PayloadBuilderAttributes, PayloadTypes}; use std::{ future::Future, pin::Pin, @@ -14,14 +13,14 @@ use tokio_stream::wrappers::UnboundedReceiverStream; /// A service task that does not build any payloads. #[derive(Debug)] -pub struct NoopPayloadBuilderService { +pub struct NoopPayloadBuilderService { /// Receiver half of the command channel. command_rx: UnboundedReceiverStream>, } impl NoopPayloadBuilderService where - Engine: EngineTypes + 'static, + Engine: PayloadTypes + 'static, { /// Creates a new [`NoopPayloadBuilderService`]. pub fn new() -> (Self, PayloadBuilderHandle) { @@ -35,7 +34,7 @@ where impl Future for NoopPayloadBuilderService where - Engine: EngineTypes, + Engine: PayloadTypes, { type Output = (); diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 98790ef7d8b78..8946cd587506b 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -11,8 +11,7 @@ use crate::{ KeepPayloadJobAlive, PayloadJob, }; use futures_util::{future::FutureExt, Stream, StreamExt}; -use reth_engine_primitives::EngineTypes; -use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; +use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes, PayloadTypes}; use reth_provider::CanonStateNotification; use reth_rpc_types::engine::PayloadId; use std::{ @@ -32,7 +31,7 @@ type PayloadFuture

= Pin { +pub struct PayloadStore { inner: PayloadBuilderHandle, } @@ -40,7 +39,7 @@ pub struct PayloadStore { impl PayloadStore where - Engine: EngineTypes + 'static, + Engine: PayloadTypes + 'static, { /// Resolves the payload job and returns the best payload that has been built so far. /// @@ -76,7 +75,7 @@ where impl Clone for PayloadStore where - Engine: EngineTypes, + Engine: PayloadTypes, { fn clone(&self) -> Self { Self { inner: self.inner.clone() } @@ -85,7 +84,7 @@ where impl From> for PayloadStore where - Engine: EngineTypes, + Engine: PayloadTypes, { fn from(inner: PayloadBuilderHandle) -> Self { Self { inner } @@ -96,7 +95,7 @@ where /// /// This is the API used to create new payloads and to get the current state of existing ones. #[derive(Debug)] -pub struct PayloadBuilderHandle { +pub struct PayloadBuilderHandle { /// Sender half of the message channel to the [`PayloadBuilderService`]. to_service: mpsc::UnboundedSender>, } @@ -105,7 +104,7 @@ pub struct PayloadBuilderHandle { impl PayloadBuilderHandle where - Engine: EngineTypes + 'static, + Engine: PayloadTypes + 'static, { /// Creates a new payload builder handle for the given channel. /// @@ -191,7 +190,7 @@ where impl Clone for PayloadBuilderHandle where - Engine: EngineTypes, + Engine: PayloadTypes, { fn clone(&self) -> Self { Self { to_service: self.to_service.clone() } @@ -210,7 +209,7 @@ where #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PayloadBuilderService where - Engine: EngineTypes, + Engine: PayloadTypes, Gen: PayloadJobGenerator, Gen::Job: PayloadJob, { @@ -236,7 +235,7 @@ const PAYLOAD_EVENTS_BUFFER_SIZE: usize = 20; impl PayloadBuilderService where - Engine: EngineTypes + 'static, + Engine: PayloadTypes + 'static, Gen: PayloadJobGenerator, Gen::Job: PayloadJob, ::BuiltPayload: Into, @@ -327,7 +326,7 @@ where impl PayloadBuilderService where - Engine: EngineTypes, + Engine: PayloadTypes, Gen: PayloadJobGenerator, Gen::Job: PayloadJob, ::BuiltPayload: Into, @@ -353,7 +352,7 @@ where impl Future for PayloadBuilderService where - Engine: EngineTypes + 'static, + Engine: PayloadTypes + 'static, Gen: PayloadJobGenerator + Unpin + 'static, ::Job: Unpin + 'static, St: Stream + Send + Unpin + 'static, @@ -453,7 +452,7 @@ where } /// Message type for the [`PayloadBuilderService`]. -pub enum PayloadServiceCommand { +pub enum PayloadServiceCommand { /// Start building a new payload. BuildNewPayload( Engine::PayloadBuilderAttributes, @@ -477,7 +476,7 @@ pub enum PayloadServiceCommand { impl fmt::Debug for PayloadServiceCommand where - Engine: EngineTypes, + Engine: PayloadTypes, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 26a3fab3fc2c4..62f697ddd6cbc 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -5,7 +5,7 @@ use crate::{ EthPayloadBuilderAttributes, PayloadBuilderHandle, PayloadBuilderService, PayloadJob, PayloadJobGenerator, }; -use reth_engine_primitives::EngineTypes; +use reth_payload_primitives::PayloadTypes; use reth_primitives::{Block, U256}; use reth_provider::CanonStateNotification; use std::{ @@ -24,7 +24,7 @@ pub fn test_payload_service() -> ( PayloadBuilderHandle, ) where - Engine: EngineTypes< + Engine: PayloadTypes< PayloadBuilderAttributes = EthPayloadBuilderAttributes, BuiltPayload = EthBuiltPayload, > + 'static, @@ -35,7 +35,7 @@ where /// Creates a new [`PayloadBuilderService`] for testing purposes and spawns it in the background. pub fn spawn_test_payload_service() -> PayloadBuilderHandle where - Engine: EngineTypes< + Engine: PayloadTypes< PayloadBuilderAttributes = EthPayloadBuilderAttributes, BuiltPayload = EthBuiltPayload, > + 'static, diff --git a/crates/primitives-traits/Cargo.toml b/crates/primitives-traits/Cargo.toml index 11f714779fbe6..97ed1a34433ce 100644 --- a/crates/primitives-traits/Cargo.toml +++ b/crates/primitives-traits/Cargo.toml @@ -42,6 +42,8 @@ test-fuzz.workspace = true rand.workspace = true [features] +default = ["std"] +std = [] test-utils = ["arbitrary"] arbitrary = [ "dep:arbitrary", diff --git a/crates/primitives-traits/src/constants.rs b/crates/primitives-traits/src/constants.rs index bda693976305f..f8b427389b22e 100644 --- a/crates/primitives-traits/src/constants.rs +++ b/crates/primitives-traits/src/constants.rs @@ -1,7 +1,7 @@ //! Ethereum protocol-related constants -use alloy_primitives::{b256, B256, U256}; -use std::time::Duration; +use alloy_primitives::{address, b256, Address, B256, U256}; +use core::time::Duration; /// The client version: `reth/v{major}.{minor}.{patch}` pub const RETH_CLIENT_VERSION: &str = concat!("reth/v", env!("CARGO_PKG_VERSION")); @@ -131,6 +131,9 @@ pub const EMPTY_OMMER_ROOT_HASH: B256 = pub const EMPTY_ROOT_HASH: B256 = b256!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); +/// From address from Optimism system txs: `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` +pub const OP_SYSTEM_TX_FROM_ADDR: Address = address!("deaddeaddeaddeaddeaddeaddeaddeaddead0001"); + /// Transactions root of empty receipts set. pub const EMPTY_RECEIPTS: B256 = EMPTY_ROOT_HASH; diff --git a/crates/primitives-traits/src/header/mod.rs b/crates/primitives-traits/src/header/mod.rs index 5ec41d41450ca..2b112954c267d 100644 --- a/crates/primitives-traits/src/header/mod.rs +++ b/crates/primitives-traits/src/header/mod.rs @@ -15,9 +15,9 @@ use alloy_eips::{ use alloy_primitives::{keccak256, Address, BlockNumber, Bloom, Bytes, B256, B64, U256}; use alloy_rlp::{length_of_length, Decodable, Encodable}; use bytes::BufMut; +use core::mem; use reth_codecs::{main_codec, Compact}; use revm_primitives::{calc_blob_gasprice, calc_excess_blob_gas}; -use std::mem; /// Block header #[main_codec] diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 91918b6877dc2..894bd28aedae7 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -5,11 +5,11 @@ use alloy_primitives::{keccak256, BlockHash}; use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::{Decodable, Encodable}; use bytes::BufMut; +use core::mem; use derive_more::{AsRef, Deref}; #[cfg(any(test, feature = "arbitrary"))] use proptest::prelude::*; use reth_codecs::{add_arbitrary_tests, main_codec, Compact}; -use std::mem; /// A [`Header`] that is sealed at a precalculated hash, use [`SealedHeader::unseal()`] if you want /// to modify header. diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 68161709cd3b6..0051f6c7df320 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -9,6 +9,7 @@ // TODO: remove when https://github.com/proptest-rs/proptest/pull/427 is merged #![allow(unknown_lints, non_local_definitions)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "alloy-compat")] mod alloy_compat; diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index ff3cf016956ab..1b2dfab727f59 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -59,10 +59,12 @@ proptest-derive = { workspace = true, optional = true } [dev-dependencies] # eth +reth-primitives-traits = { workspace = true, features = ["arbitrary"] } revm-primitives = { workspace = true, features = ["arbitrary"] } nybbles = { workspace = true, features = ["arbitrary"] } alloy-trie = { workspace = true, features = ["arbitrary"] } alloy-eips = { workspace = true, features = ["arbitrary"] } +alloy-consensus = { workspace = true, features = ["arbitrary"] } assert_matches.workspace = true arbitrary = { workspace = true, features = ["derive"] } diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index d193b787fd529..8b61796a735db 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -182,7 +182,30 @@ impl TryFrom for Transaction { })) } #[cfg(feature = "optimism")] - Some(TxType::Deposit) => todo!(), + Some(TxType::Deposit) => Ok(Self::Deposit(crate::transaction::TxDeposit { + source_hash: tx + .other + .get_deserialized::("sourceHash") + .ok_or_else(|| ConversionError::Custom("MissingSourceHash".to_string()))? + .map_err(|_| ConversionError::Custom("MissingSourceHash".to_string()))? + .parse() + .map_err(|_| ConversionError::Custom("InvalidSourceHash".to_string()))?, + from: tx.from, + to: TxKind::from(tx.to), + mint: Option::transpose( + tx.other.get_deserialized::("mint"), + ) + .map_err(|_| ConversionError::Custom("MissingMintValue".to_string()))? + .map(|num| num.to::()) + .filter(|num| *num > 0), + value: tx.value, + gas_limit: tx + .gas + .try_into() + .map_err(|_| ConversionError::Eip2718Error(RlpError::Overflow.into()))?, + is_system_transaction: tx.from == crate::constants::OP_SYSTEM_TX_FROM_ADDR, + input: tx.input, + })), } } } @@ -247,3 +270,114 @@ impl TryFrom for Signature { Ok(Self { r: signature.r, s: signature.s, odd_y_parity }) } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{B256, U256}; + use alloy_rpc_types::Transaction as AlloyTransaction; + use revm_primitives::{address, Address}; + + #[test] + #[cfg(feature = "optimism")] + fn optimism_deposit_tx_conversion_no_mint() { + let input = r#"{ + "blockHash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", + "blockNumber": "0x73a78fd", + "depositReceiptVersion": "0x1", + "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", + "gas": "0xc27a8", + "gasPrice": "0x0", + "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", + "input": "0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5400000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e40166a07a0000000000000000000000000994206dfe8de6ec6920ff4d779b0d950605fb53000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000ca74f404e0c7bfa35b13b511097df966d5a65597000000000000000000000000000000000000000000000216614199391dbba2ba00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "mint": "0x0", + "nonce": "0x74060", + "r": "0x0", + "s": "0x0", + "sourceHash": "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3", + "to": "0x4200000000000000000000000000000000000007", + "transactionIndex": "0x1", + "type": "0x7e", + "v": "0x0", + "value": "0x0" + }"#; + let alloy_tx: AlloyTransaction = + serde_json::from_str(input).expect("failed to deserialize"); + + let reth_tx: Transaction = alloy_tx.try_into().expect("failed to convert"); + if let Transaction::Deposit(deposit_tx) = reth_tx { + assert_eq!( + deposit_tx.source_hash, + "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3" + .parse::() + .unwrap() + ); + assert_eq!( + deposit_tx.from, + "0x36bde71c97b33cc4729cf772ae268934f7ab70b2".parse::

().unwrap() + ); + assert_eq!( + deposit_tx.to, + TxKind::from(address!("4200000000000000000000000000000000000007")) + ); + assert_eq!(deposit_tx.mint, None); + assert_eq!(deposit_tx.value, U256::ZERO); + assert_eq!(deposit_tx.gas_limit, 796584); + assert!(!deposit_tx.is_system_transaction); + } else { + panic!("Expected Deposit transaction"); + } + } + + #[test] + #[cfg(feature = "optimism")] + fn optimism_deposit_tx_conversion_mint() { + let input = r#"{ + "blockHash": "0x7194f63b105e93fb1a27c50d23d62e422d4185a68536c55c96284911415699b2", + "blockNumber": "0x73a82cc", + "depositReceiptVersion": "0x1", + "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", + "gas": "0x7812e", + "gasPrice": "0x0", + "hash": "0xf7e83886d3c6864f78e01c453ebcd57020c5795d96089e8f0e0b90a467246ddb", + "input": "0xd764ad0b000100000000000000000000000000000000000000000000000000000001cf5f00000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be100000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000239c2e16a5ca5900000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e41635f5fd0000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000002ce910fbba65b454bbaf6a18c952a70f3bcd82990000000000000000000000000000000000000000000000239c2e16a5ca590000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "mint": "0x239c2e16a5ca590000", + "nonce": "0x7406b", + "r": "0x0", + "s": "0x0", + "sourceHash": "0xe0358cd2b2686d297c5c859646a613124a874fb9d9c4a2c88636a46a65c06e48", + "to": "0x4200000000000000000000000000000000000007", + "transactionIndex": "0x1", + "type": "0x7e", + "v": "0x0", + "value": "0x239c2e16a5ca590000" + }"#; + let alloy_tx: AlloyTransaction = + serde_json::from_str(input).expect("failed to deserialize"); + + let reth_tx: Transaction = alloy_tx.try_into().expect("failed to convert"); + + if let Transaction::Deposit(deposit_tx) = reth_tx { + assert_eq!( + deposit_tx.source_hash, + "0xe0358cd2b2686d297c5c859646a613124a874fb9d9c4a2c88636a46a65c06e48" + .parse::() + .unwrap() + ); + assert_eq!( + deposit_tx.from, + "0x36bde71c97b33cc4729cf772ae268934f7ab70b2".parse::
().unwrap() + ); + assert_eq!( + deposit_tx.to, + TxKind::from(address!("4200000000000000000000000000000000000007")) + ); + assert_eq!(deposit_tx.mint, Some(656890000000000000000)); + assert_eq!(deposit_tx.value, U256::from(0x239c2e16a5ca590000_u128)); + assert_eq!(deposit_tx.gas_limit, 491822); + assert!(!deposit_tx.is_system_transaction); + } else { + panic!("Expected Deposit transaction"); + } + } +} diff --git a/crates/primitives/src/revm/config.rs b/crates/primitives/src/revm/config.rs index 6ad76123f1499..5914dbf593487 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/primitives/src/revm/config.rs @@ -11,7 +11,9 @@ pub fn revm_spec_by_timestamp_after_merge( ) -> revm_primitives::SpecId { #[cfg(feature = "optimism")] if chain_spec.is_optimism() { - return if chain_spec.fork(Hardfork::Ecotone).active_at_timestamp(timestamp) { + return if chain_spec.fork(Hardfork::Fjord).active_at_timestamp(timestamp) { + revm_primitives::FJORD + } else if chain_spec.fork(Hardfork::Ecotone).active_at_timestamp(timestamp) { revm_primitives::ECOTONE } else if chain_spec.fork(Hardfork::Canyon).active_at_timestamp(timestamp) { revm_primitives::CANYON @@ -90,6 +92,56 @@ mod tests { use crate::U256; use reth_chainspec::{ChainSpecBuilder, MAINNET}; + #[test] + fn test_revm_spec_by_timestamp_after_merge() { + assert_eq!( + revm_spec_by_timestamp_after_merge( + &ChainSpecBuilder::mainnet().cancun_activated().build(), + 0 + ), + revm_primitives::CANCUN + ); + assert_eq!( + revm_spec_by_timestamp_after_merge( + &ChainSpecBuilder::mainnet().shanghai_activated().build(), + 0 + ), + revm_primitives::SHANGHAI + ); + assert_eq!( + revm_spec_by_timestamp_after_merge(&ChainSpecBuilder::mainnet().build(), 0), + revm_primitives::MERGE + ); + #[cfg(feature = "optimism")] + { + #[inline(always)] + fn op_cs(f: impl FnOnce(ChainSpecBuilder) -> ChainSpecBuilder) -> ChainSpec { + let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10)); + f(cs).build() + } + assert_eq!( + revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.fjord_activated()), 0), + revm_primitives::FJORD + ); + assert_eq!( + revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.ecotone_activated()), 0), + revm_primitives::ECOTONE + ); + assert_eq!( + revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.canyon_activated()), 0), + revm_primitives::CANYON + ); + assert_eq!( + revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.bedrock_activated()), 0), + revm_primitives::BEDROCK + ); + assert_eq!( + revm_spec_by_timestamp_after_merge(&op_cs(|cs| cs.regolith_activated()), 0), + revm_primitives::REGOLITH + ); + } + } + #[test] fn test_to_revm_spec() { assert_eq!( @@ -178,6 +230,15 @@ mod tests { #[test] fn test_eth_spec() { + assert_eq!( + revm_spec(&MAINNET, Head { timestamp: 1710338135, ..Default::default() }), + revm_primitives::CANCUN + ); + assert_eq!( + revm_spec(&MAINNET, Head { timestamp: 1681338455, ..Default::default() }), + revm_primitives::SHANGHAI + ); + assert_eq!( revm_spec( &MAINNET, diff --git a/crates/prune/prune/Cargo.toml b/crates/prune/prune/Cargo.toml index c45ea9d3f7f15..b5d9059c95b8b 100644 --- a/crates/prune/prune/Cargo.toml +++ b/crates/prune/prune/Cargo.toml @@ -15,7 +15,6 @@ workspace = true # reth reth-chainspec.workspace = true reth-exex-types.workspace = true -reth-primitives.workspace = true reth-db.workspace = true reth-db-api.workspace = true reth-errors.workspace = true @@ -23,6 +22,7 @@ reth-provider.workspace = true reth-tokio-util.workspace = true reth-config.workspace = true reth-prune-types.workspace = true +reth-static-file-types.workspace = true # metrics reth-metrics.workspace = true diff --git a/crates/prune/prune/src/pruner.rs b/crates/prune/prune/src/pruner.rs index 47864a274e03f..656aa69adeb2e 100644 --- a/crates/prune/prune/src/pruner.rs +++ b/crates/prune/prune/src/pruner.rs @@ -5,13 +5,14 @@ use crate::{ segments::{PruneInput, Segment}, Metrics, PrunerError, PrunerEvent, }; +use alloy_primitives::BlockNumber; use reth_db_api::database::Database; use reth_exex_types::FinishedExExHeight; -use reth_primitives::{BlockNumber, StaticFileSegment}; use reth_provider::{ DatabaseProviderRW, ProviderFactory, PruneCheckpointReader, StaticFileProviderFactory, }; use reth_prune_types::{PruneLimiter, PruneMode, PruneProgress, PrunePurpose, PruneSegment}; +use reth_static_file_types::StaticFileSegment; use reth_tokio_util::{EventSender, EventStream}; use std::{ collections::BTreeMap, diff --git a/crates/prune/prune/src/segments/account_history.rs b/crates/prune/prune/src/segments/account_history.rs index 78ca36219d041..ab2800a317183 100644 --- a/crates/prune/prune/src/segments/account_history.rs +++ b/crates/prune/prune/src/segments/account_history.rs @@ -106,9 +106,9 @@ mod tests { account_history::ACCOUNT_HISTORY_TABLES_TO_PRUNE, AccountHistory, PruneInput, PruneOutput, Segment, }; + use alloy_primitives::{BlockNumber, B256}; use assert_matches::assert_matches; use reth_db::{tables, BlockNumberList}; - use reth_primitives::{BlockNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{ PruneCheckpoint, PruneInterruptReason, PruneLimiter, PruneMode, PruneProgress, PruneSegment, diff --git a/crates/prune/prune/src/segments/headers.rs b/crates/prune/prune/src/segments/headers.rs index 3cf2beeba2e35..1c49fe8c10866 100644 --- a/crates/prune/prune/src/segments/headers.rs +++ b/crates/prune/prune/src/segments/headers.rs @@ -188,10 +188,10 @@ where #[cfg(test)] mod tests { + use alloy_primitives::{BlockNumber, B256, U256}; use assert_matches::assert_matches; use reth_db::tables; use reth_db_api::transaction::DbTx; - use reth_primitives::{BlockNumber, B256, U256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{ PruneCheckpoint, PruneInterruptReason, PruneLimiter, PruneMode, PruneProgress, PruneSegment, diff --git a/crates/prune/prune/src/segments/history.rs b/crates/prune/prune/src/segments/history.rs index 253d453aa597d..ee841ef897170 100644 --- a/crates/prune/prune/src/segments/history.rs +++ b/crates/prune/prune/src/segments/history.rs @@ -1,3 +1,4 @@ +use alloy_primitives::BlockNumber; use reth_db::BlockNumberList; use reth_db_api::{ cursor::{DbCursorRO, DbCursorRW}, @@ -7,7 +8,6 @@ use reth_db_api::{ transaction::DbTxMut, DatabaseError, }; -use reth_primitives::BlockNumber; use reth_provider::DatabaseProviderRW; /// Prune history indices up to the provided block, inclusive. diff --git a/crates/prune/prune/src/segments/receipts.rs b/crates/prune/prune/src/segments/receipts.rs index ef6e502c7e9f3..5b8118778898d 100644 --- a/crates/prune/prune/src/segments/receipts.rs +++ b/crates/prune/prune/src/segments/receipts.rs @@ -94,13 +94,13 @@ impl Segment for Receipts { #[cfg(test)] mod tests { use crate::segments::{PruneInput, PruneOutput, Receipts, Segment}; + use alloy_primitives::{BlockNumber, TxNumber, B256}; use assert_matches::assert_matches; use itertools::{ FoldWhile::{Continue, Done}, Itertools, }; use reth_db::tables; - use reth_primitives::{BlockNumber, TxNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{ PruneCheckpoint, PruneInterruptReason, PruneLimiter, PruneMode, PruneProgress, PruneSegment, diff --git a/crates/prune/prune/src/segments/receipts_by_logs.rs b/crates/prune/prune/src/segments/receipts_by_logs.rs index f4ccad810ce36..63b5941c34b50 100644 --- a/crates/prune/prune/src/segments/receipts_by_logs.rs +++ b/crates/prune/prune/src/segments/receipts_by_logs.rs @@ -216,10 +216,10 @@ impl Segment for ReceiptsByLogs { #[cfg(test)] mod tests { use crate::segments::{receipts_by_logs::ReceiptsByLogs, PruneInput, Segment}; + use alloy_primitives::B256; use assert_matches::assert_matches; use reth_db::tables; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; - use reth_primitives::B256; use reth_provider::{PruneCheckpointReader, TransactionsProvider}; use reth_prune_types::{PruneLimiter, PruneMode, PruneSegment, ReceiptsLogPruneConfig}; use reth_stages::test_utils::{StorageKind, TestStageDB}; diff --git a/crates/prune/prune/src/segments/sender_recovery.rs b/crates/prune/prune/src/segments/sender_recovery.rs index f13dfde254a4c..94ef6ffb7c78d 100644 --- a/crates/prune/prune/src/segments/sender_recovery.rs +++ b/crates/prune/prune/src/segments/sender_recovery.rs @@ -77,13 +77,13 @@ impl Segment for SenderRecovery { #[cfg(test)] mod tests { use crate::segments::{PruneInput, PruneOutput, Segment, SenderRecovery}; + use alloy_primitives::{BlockNumber, TxNumber, B256}; use assert_matches::assert_matches; use itertools::{ FoldWhile::{Continue, Done}, Itertools, }; use reth_db::tables; - use reth_primitives::{BlockNumber, TxNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{PruneCheckpoint, PruneLimiter, PruneMode, PruneProgress, PruneSegment}; use reth_stages::test_utils::{StorageKind, TestStageDB}; diff --git a/crates/prune/prune/src/segments/storage_history.rs b/crates/prune/prune/src/segments/storage_history.rs index 18af8134cf5f4..3e7ad86a7da46 100644 --- a/crates/prune/prune/src/segments/storage_history.rs +++ b/crates/prune/prune/src/segments/storage_history.rs @@ -109,9 +109,9 @@ mod tests { storage_history::STORAGE_HISTORY_TABLES_TO_PRUNE, PruneInput, PruneOutput, Segment, StorageHistory, }; + use alloy_primitives::{BlockNumber, B256}; use assert_matches::assert_matches; use reth_db::{tables, BlockNumberList}; - use reth_primitives::{BlockNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{PruneCheckpoint, PruneLimiter, PruneMode, PruneProgress, PruneSegment}; use reth_stages::test_utils::{StorageKind, TestStageDB}; diff --git a/crates/prune/prune/src/segments/transaction_lookup.rs b/crates/prune/prune/src/segments/transaction_lookup.rs index b77b0193329cf..457f551c167ba 100644 --- a/crates/prune/prune/src/segments/transaction_lookup.rs +++ b/crates/prune/prune/src/segments/transaction_lookup.rs @@ -104,13 +104,13 @@ impl Segment for TransactionLookup { #[cfg(test)] mod tests { use crate::segments::{PruneInput, PruneOutput, Segment, TransactionLookup}; + use alloy_primitives::{BlockNumber, TxNumber, B256}; use assert_matches::assert_matches; use itertools::{ FoldWhile::{Continue, Done}, Itertools, }; use reth_db::tables; - use reth_primitives::{BlockNumber, TxNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{ PruneCheckpoint, PruneInterruptReason, PruneLimiter, PruneMode, PruneProgress, PruneSegment, diff --git a/crates/prune/prune/src/segments/transactions.rs b/crates/prune/prune/src/segments/transactions.rs index 5a7305a1b50aa..fd24a380de5b8 100644 --- a/crates/prune/prune/src/segments/transactions.rs +++ b/crates/prune/prune/src/segments/transactions.rs @@ -76,13 +76,13 @@ impl Segment for Transactions { #[cfg(test)] mod tests { use crate::segments::{PruneInput, PruneOutput, Segment, Transactions}; + use alloy_primitives::{BlockNumber, TxNumber, B256}; use assert_matches::assert_matches; use itertools::{ FoldWhile::{Continue, Done}, Itertools, }; use reth_db::tables; - use reth_primitives::{BlockNumber, TxNumber, B256}; use reth_provider::PruneCheckpointReader; use reth_prune_types::{ PruneCheckpoint, PruneInterruptReason, PruneLimiter, PruneMode, PruneProgress, PruneSegment, diff --git a/crates/revm/src/state_change.rs b/crates/revm/src/state_change.rs index 1709b54cb80de..947c08da7efc8 100644 --- a/crates/revm/src/state_change.rs +++ b/crates/revm/src/state_change.rs @@ -17,7 +17,8 @@ use reth_storage_errors::provider::ProviderError; use revm::{ interpreter::Host, primitives::{ - Account, AccountInfo, Bytecode, EvmStorageSlot, ExecutionResult, FixedBytes, ResultAndState, + Account, AccountInfo, Bytecode, EvmStorageSlot, ExecutionResult, FixedBytes, + ResultAndState, BLOCKHASH_SERVE_WINDOW, }, Database, DatabaseCommit, Evm, }; @@ -67,9 +68,6 @@ pub fn post_block_balance_increments( balance_increments } -/// todo: temporary move over of constants from revm until we've migrated to the latest version -pub const HISTORY_SERVE_WINDOW: u64 = 8192; - /// Applies the pre-block state change outlined in [EIP-2935] to store historical blockhashes in a /// system contract. /// @@ -131,7 +129,7 @@ fn eip2935_block_hash_slot>( block_number: u64, block_hash: B256, ) -> Result<(U256, EvmStorageSlot), BlockValidationError> { - let slot = U256::from(block_number % HISTORY_SERVE_WINDOW); + let slot = U256::from(block_number % BLOCKHASH_SERVE_WINDOW as u64); let current_hash = db .storage(HISTORY_STORAGE_ADDRESS, slot) .map_err(BlockValidationError::BlockHashAccountLoadingFailed)?; diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index d05ec82397225..93d4e6b264ee5 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -1306,7 +1306,7 @@ impl RpcServerConfig { /// Returns true if any server is configured. /// - /// If no server is configured, no server will be be launched on [`RpcServerConfig::start`]. + /// If no server is configured, no server will be launched on [`RpcServerConfig::start`]. pub const fn has_server(&self) -> bool { self.http_server_config.is_some() || self.ws_server_config.is_some() || diff --git a/crates/rpc/rpc/src/eth/api/fees.rs b/crates/rpc/rpc/src/eth/api/fees.rs index 68789674ce5da..2493d60557780 100644 --- a/crates/rpc/rpc/src/eth/api/fees.rs +++ b/crates/rpc/rpc/src/eth/api/fees.rs @@ -153,8 +153,10 @@ where } for header in &headers { + let ratio = if header.gas_limit > 0 {header.gas_used as f64 / header.gas_limit as f64} else {1.0}; + base_fee_per_gas.push(header.base_fee_per_gas.unwrap_or_default() as u128); - gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64); + gas_used_ratio.push(ratio); base_fee_per_blob_gas.push(header.blob_fee().unwrap_or_default()); blob_gas_used_ratio.push( header.blob_gas_used.unwrap_or_default() as f64 / diff --git a/crates/stages/api/Cargo.toml b/crates/stages/api/Cargo.toml index cb58818b503c4..a5db5b9fb20ca 100644 --- a/crates/stages/api/Cargo.toml +++ b/crates/stages/api/Cargo.toml @@ -12,7 +12,7 @@ workspace = true [dependencies] # reth -reth-primitives.workspace = true +reth-primitives-traits.workspace = true reth-provider.workspace = true reth-db-api.workspace = true reth-static-file.workspace = true @@ -22,6 +22,9 @@ reth-consensus.workspace = true reth-prune.workspace = true reth-errors.workspace = true reth-stages-types.workspace = true +reth-static-file-types.workspace = true + +alloy-primitives.workspace = true # metrics reth-metrics.workspace = true diff --git a/crates/stages/api/src/error.rs b/crates/stages/api/src/error.rs index ab525f8f5331a..2f113f2fa8132 100644 --- a/crates/stages/api/src/error.rs +++ b/crates/stages/api/src/error.rs @@ -1,9 +1,11 @@ use crate::PipelineEvent; +use alloy_primitives::{BlockNumber, TxNumber}; use reth_consensus::ConsensusError; use reth_errors::{BlockExecutionError, DatabaseError, RethError}; use reth_network_p2p::error::DownloadError; -use reth_primitives::{BlockNumber, SealedHeader, StaticFileSegment, TxNumber}; +use reth_primitives_traits::SealedHeader; use reth_provider::ProviderError; +use reth_static_file_types::StaticFileSegment; use thiserror::Error; use tokio::sync::broadcast::error::SendError; diff --git a/crates/stages/api/src/metrics/listener.rs b/crates/stages/api/src/metrics/listener.rs index 408ecab4a95ca..e703367bcd672 100644 --- a/crates/stages/api/src/metrics/listener.rs +++ b/crates/stages/api/src/metrics/listener.rs @@ -1,5 +1,6 @@ use crate::{metrics::SyncMetrics, StageCheckpoint, StageId}; -use reth_primitives::{constants::MGAS_TO_GAS, BlockNumber}; +use alloy_primitives::BlockNumber; +use reth_primitives_traits::constants::MGAS_TO_GAS; use std::{ future::Future, pin::Pin, diff --git a/crates/stages/api/src/pipeline/builder.rs b/crates/stages/api/src/pipeline/builder.rs index ada5ffd3734a8..1e83af4c3c825 100644 --- a/crates/stages/api/src/pipeline/builder.rs +++ b/crates/stages/api/src/pipeline/builder.rs @@ -1,6 +1,6 @@ use crate::{pipeline::BoxedStage, MetricEventsSender, Pipeline, Stage, StageId, StageSet}; +use alloy_primitives::{BlockNumber, B256}; use reth_db_api::database::Database; -use reth_primitives::{BlockNumber, B256}; use reth_provider::ProviderFactory; use reth_static_file::StaticFileProducer; use tokio::sync::watch; diff --git a/crates/stages/api/src/pipeline/ctrl.rs b/crates/stages/api/src/pipeline/ctrl.rs index 83dbe0cf394c1..8fc64c2ab708a 100644 --- a/crates/stages/api/src/pipeline/ctrl.rs +++ b/crates/stages/api/src/pipeline/ctrl.rs @@ -1,4 +1,5 @@ -use reth_primitives::{BlockNumber, SealedHeader}; +use alloy_primitives::BlockNumber; +use reth_primitives_traits::SealedHeader; /// Determines the control flow during pipeline execution. /// diff --git a/crates/stages/api/src/pipeline/event.rs b/crates/stages/api/src/pipeline/event.rs index 9bbaaa79b4684..879725886cf94 100644 --- a/crates/stages/api/src/pipeline/event.rs +++ b/crates/stages/api/src/pipeline/event.rs @@ -2,7 +2,7 @@ use crate::{ stage::{ExecOutput, UnwindInput, UnwindOutput}, StageCheckpoint, StageId, }; -use reth_primitives::BlockNumber; +use alloy_primitives::BlockNumber; use std::fmt::{Display, Formatter}; /// An event emitted by a [Pipeline][crate::Pipeline]. diff --git a/crates/stages/api/src/pipeline/mod.rs b/crates/stages/api/src/pipeline/mod.rs index 2b7fcf6cbec4d..67ef53855b15a 100644 --- a/crates/stages/api/src/pipeline/mod.rs +++ b/crates/stages/api/src/pipeline/mod.rs @@ -2,19 +2,18 @@ mod ctrl; mod event; pub use crate::pipeline::ctrl::ControlFlow; use crate::{PipelineTarget, StageCheckpoint, StageId}; +use alloy_primitives::{BlockNumber, B256}; pub use event::*; use futures_util::Future; use reth_db_api::database::Database; -use reth_primitives::{ - constants::BEACON_CONSENSUS_REORG_UNWIND_DEPTH, static_file::HighestStaticFiles, BlockNumber, - B256, -}; +use reth_primitives_traits::constants::BEACON_CONSENSUS_REORG_UNWIND_DEPTH; use reth_provider::{ providers::StaticFileWriter, FinalizedBlockReader, FinalizedBlockWriter, ProviderFactory, StageCheckpointReader, StageCheckpointWriter, StaticFileProviderFactory, }; use reth_prune::PrunerBuilder; use reth_static_file::StaticFileProducer; +use reth_static_file_types::HighestStaticFiles; use reth_tokio_util::{EventSender, EventStream}; use std::pin::Pin; use tokio::sync::watch; @@ -237,13 +236,13 @@ where /// Run [static file producer](StaticFileProducer) and [pruner](reth_prune::Pruner) to **move** /// all data from the database to static files for corresponding - /// [segments](reth_primitives::static_file::StaticFileSegment), according to their [stage + /// [segments](reth_static_file_types::StaticFileSegment), according to their [stage /// checkpoints](StageCheckpoint): - /// - [`StaticFileSegment::Headers`](reth_primitives::static_file::StaticFileSegment::Headers) - /// -> [`StageId::Headers`] - /// - [`StaticFileSegment::Receipts`](reth_primitives::static_file::StaticFileSegment::Receipts) - /// -> [`StageId::Execution`] - /// - [`StaticFileSegment::Transactions`](reth_primitives::static_file::StaticFileSegment::Transactions) + /// - [`StaticFileSegment::Headers`](reth_static_file_types::StaticFileSegment::Headers) -> + /// [`StageId::Headers`] + /// - [`StaticFileSegment::Receipts`](reth_static_file_types::StaticFileSegment::Receipts) -> + /// [`StageId::Execution`] + /// - [`StaticFileSegment::Transactions`](reth_static_file_types::StaticFileSegment::Transactions) /// -> [`StageId::Bodies`] /// /// CAUTION: This method locks the static file producer Mutex, hence can block the thread if the diff --git a/crates/stages/api/src/pipeline/progress.rs b/crates/stages/api/src/pipeline/progress.rs index 4bb1848543a9d..4138f95ddf593 100644 --- a/crates/stages/api/src/pipeline/progress.rs +++ b/crates/stages/api/src/pipeline/progress.rs @@ -1,5 +1,5 @@ use crate::{util::opt, ControlFlow}; -use reth_primitives::BlockNumber; +use alloy_primitives::BlockNumber; #[derive(Debug, Default)] pub(crate) struct PipelineProgress { diff --git a/crates/stages/api/src/stage.rs b/crates/stages/api/src/stage.rs index 381acf5f2d99d..b8178df46d515 100644 --- a/crates/stages/api/src/stage.rs +++ b/crates/stages/api/src/stage.rs @@ -1,6 +1,6 @@ use crate::{error::StageError, StageCheckpoint, StageId}; +use alloy_primitives::{BlockNumber, TxNumber}; use reth_db_api::database::Database; -use reth_primitives::{BlockNumber, TxNumber}; use reth_provider::{BlockReader, DatabaseProviderRW, ProviderError, TransactionsProvider}; use std::{ cmp::{max, min}, diff --git a/crates/static-file/static-file/Cargo.toml b/crates/static-file/static-file/Cargo.toml index 4d4e31509aeb8..29a601f050d0e 100644 --- a/crates/static-file/static-file/Cargo.toml +++ b/crates/static-file/static-file/Cargo.toml @@ -13,7 +13,6 @@ workspace = true [dependencies] # reth -reth-primitives.workspace = true reth-db.workspace = true reth-db-api.workspace = true reth-provider.workspace = true @@ -21,6 +20,9 @@ reth-storage-errors.workspace = true reth-nippy-jar.workspace = true reth-tokio-util.workspace = true reth-prune-types.workspace = true +reth-static-file-types.workspace = true + +alloy-primitives.workspace = true # misc tracing.workspace = true diff --git a/crates/static-file/static-file/src/lib.rs b/crates/static-file/static-file/src/lib.rs index f545298ebd47d..1bfe4134e954f 100644 --- a/crates/static-file/static-file/src/lib.rs +++ b/crates/static-file/static-file/src/lib.rs @@ -16,3 +16,6 @@ pub use static_file_producer::{ StaticFileProducer, StaticFileProducerInner, StaticFileProducerResult, StaticFileProducerWithResult, StaticFileTargets, }; + +// Re-export for convenience. +pub use reth_static_file_types::*; diff --git a/crates/static-file/static-file/src/segments/headers.rs b/crates/static-file/static-file/src/segments/headers.rs index 5fb1a4422e82a..e87c1fdc58e8e 100644 --- a/crates/static-file/static-file/src/segments/headers.rs +++ b/crates/static-file/static-file/src/segments/headers.rs @@ -1,11 +1,12 @@ use crate::segments::{dataset_for_compression, prepare_jar, Segment, SegmentHeader}; +use alloy_primitives::BlockNumber; use reth_db::{static_file::create_static_file_T1_T2_T3, tables, RawKey, RawTable}; use reth_db_api::{cursor::DbCursorRO, database::Database, transaction::DbTx}; -use reth_primitives::{static_file::SegmentConfig, BlockNumber, StaticFileSegment}; use reth_provider::{ providers::{StaticFileProvider, StaticFileWriter}, DatabaseProviderRO, }; +use reth_static_file_types::{SegmentConfig, StaticFileSegment}; use reth_storage_errors::provider::ProviderResult; use std::{ops::RangeInclusive, path::Path}; diff --git a/crates/static-file/static-file/src/segments/mod.rs b/crates/static-file/static-file/src/segments/mod.rs index e21f8ad7a12b0..77798dd085426 100644 --- a/crates/static-file/static-file/src/segments/mod.rs +++ b/crates/static-file/static-file/src/segments/mod.rs @@ -9,19 +9,17 @@ pub use headers::Headers; mod receipts; pub use receipts::Receipts; +use alloy_primitives::BlockNumber; use reth_db::{RawKey, RawTable}; use reth_db_api::{cursor::DbCursorRO, database::Database, table::Table, transaction::DbTx}; use reth_nippy_jar::NippyJar; -use reth_primitives::{ - static_file::{ - find_fixed_range, Compression, Filters, InclusionFilter, PerfectHashingFunction, - SegmentConfig, SegmentHeader, - }, - BlockNumber, StaticFileSegment, -}; use reth_provider::{ providers::StaticFileProvider, DatabaseProviderRO, ProviderError, TransactionsProviderExt, }; +use reth_static_file_types::{ + find_fixed_range, Compression, Filters, InclusionFilter, PerfectHashingFunction, SegmentConfig, + SegmentHeader, StaticFileSegment, +}; use reth_storage_errors::provider::ProviderResult; use std::{ops::RangeInclusive, path::Path}; diff --git a/crates/static-file/static-file/src/segments/receipts.rs b/crates/static-file/static-file/src/segments/receipts.rs index e0ed580867226..e09b5e690df9c 100644 --- a/crates/static-file/static-file/src/segments/receipts.rs +++ b/crates/static-file/static-file/src/segments/receipts.rs @@ -1,14 +1,12 @@ use crate::segments::{dataset_for_compression, prepare_jar, Segment}; +use alloy_primitives::{BlockNumber, TxNumber}; use reth_db::{static_file::create_static_file_T1, tables}; use reth_db_api::{cursor::DbCursorRO, database::Database, transaction::DbTx}; -use reth_primitives::{ - static_file::{SegmentConfig, SegmentHeader}, - BlockNumber, StaticFileSegment, TxNumber, -}; use reth_provider::{ providers::{StaticFileProvider, StaticFileWriter}, BlockReader, DatabaseProviderRO, TransactionsProviderExt, }; +use reth_static_file_types::{SegmentConfig, SegmentHeader, StaticFileSegment}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ops::RangeInclusive, path::Path}; diff --git a/crates/static-file/static-file/src/segments/transactions.rs b/crates/static-file/static-file/src/segments/transactions.rs index 47eaa727250c1..c7daeba0675f8 100644 --- a/crates/static-file/static-file/src/segments/transactions.rs +++ b/crates/static-file/static-file/src/segments/transactions.rs @@ -1,14 +1,12 @@ use crate::segments::{dataset_for_compression, prepare_jar, Segment}; +use alloy_primitives::{BlockNumber, TxNumber}; use reth_db::{static_file::create_static_file_T1, tables}; use reth_db_api::{cursor::DbCursorRO, database::Database, transaction::DbTx}; -use reth_primitives::{ - static_file::{SegmentConfig, SegmentHeader}, - BlockNumber, StaticFileSegment, TxNumber, -}; use reth_provider::{ providers::{StaticFileProvider, StaticFileWriter}, BlockReader, DatabaseProviderRO, TransactionsProviderExt, }; +use reth_static_file_types::{SegmentConfig, SegmentHeader, StaticFileSegment}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ops::RangeInclusive, path::Path}; diff --git a/crates/static-file/static-file/src/static_file_producer.rs b/crates/static-file/static-file/src/static_file_producer.rs index 396fdd5ed08d2..44ea3a5c84b4e 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -1,12 +1,13 @@ //! Support for producing static files. use crate::{segments, segments::Segment, StaticFileProducerEvent}; +use alloy_primitives::BlockNumber; use parking_lot::Mutex; use rayon::prelude::*; use reth_db_api::database::Database; -use reth_primitives::{static_file::HighestStaticFiles, BlockNumber}; use reth_provider::{providers::StaticFileWriter, ProviderFactory, StaticFileProviderFactory}; use reth_prune_types::PruneModes; +use reth_static_file_types::HighestStaticFiles; use reth_storage_errors::provider::ProviderResult; use reth_tokio_util::{EventSender, EventStream}; use std::{ @@ -228,15 +229,16 @@ mod tests { use crate::static_file_producer::{ StaticFileProducer, StaticFileProducerInner, StaticFileTargets, }; + use alloy_primitives::{B256, U256}; use assert_matches::assert_matches; use reth_db::{test_utils::TempDatabase, DatabaseEnv}; use reth_db_api::{database::Database, transaction::DbTx}; - use reth_primitives::{static_file::HighestStaticFiles, StaticFileSegment, B256, U256}; use reth_provider::{ providers::StaticFileWriter, ProviderError, ProviderFactory, StaticFileProviderFactory, }; use reth_prune_types::PruneModes; use reth_stages::test_utils::{StorageKind, TestStageDB}; + use reth_static_file_types::{HighestStaticFiles, StaticFileSegment}; use reth_testing_utils::{ generators, generators::{random_block_range, random_receipt}, diff --git a/examples/stateful-precompile/Cargo.toml b/examples/stateful-precompile/Cargo.toml new file mode 100644 index 0000000000000..2a248fbefb001 --- /dev/null +++ b/examples/stateful-precompile/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "stateful-precompile" +version = "0.0.0" +publish = false +edition.workspace = true +license.workspace = true + +[dependencies] +reth.workspace = true +reth-chainspec.workspace = true +reth-node-api.workspace = true +reth-node-core.workspace = true +reth-primitives.workspace = true +reth-node-ethereum.workspace = true +reth-tracing.workspace = true + +eyre.workspace = true +parking_lot.workspace = true +schnellru.workspace = true +tokio.workspace = true diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs new file mode 100644 index 0000000000000..0cd495e85a53a --- /dev/null +++ b/examples/stateful-precompile/src/main.rs @@ -0,0 +1,237 @@ +//! This example shows how to implement a node with a custom EVM that uses a stateful precompile + +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +use parking_lot::RwLock; +use reth::{ + builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, + primitives::{ + revm_primitives::{CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv}, + Address, Bytes, U256, + }, + revm::{ + handler::register::EvmHandler, + inspector_handle_register, + precompile::{Precompile, PrecompileSpecId}, + ContextPrecompile, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, + }, + tasks::TaskManager, +}; +use reth_chainspec::{Chain, ChainSpec}; +use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes}; +use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; +use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider, EthereumNode}; +use reth_primitives::{ + revm_primitives::{SpecId, StatefulPrecompileMut}, + Genesis, Header, TransactionSigned, +}; +use reth_tracing::{RethTracer, Tracer}; +use schnellru::{ByLength, LruMap}; +use std::{collections::HashMap, sync::Arc}; + +/// A cache for precompile inputs / outputs. +/// +/// This assumes that the precompile is a standard precompile, as in `StandardPrecompileFn`, meaning +/// its inputs are only `(Bytes, u64)`. +/// +/// NOTE: This does not work with "context stateful precompiles", ie `ContextStatefulPrecompile` or +/// `ContextStatefulPrecompileMut`. They are explicitly banned. +#[derive(Debug, Default)] +pub struct PrecompileCache { + /// Caches for each precompile input / output. + #[allow(clippy::type_complexity)] + cache: HashMap<(Address, SpecId), Arc>>>, +} + +/// Custom EVM configuration +#[derive(Debug, Clone, Default)] +#[non_exhaustive] +pub struct MyEvmConfig { + precompile_cache: Arc>, +} + +impl MyEvmConfig { + /// Sets the precompiles to the EVM handler + /// + /// This will be invoked when the EVM is created via [ConfigureEvm::evm] or + /// [ConfigureEvm::evm_with_inspector] + /// + /// This will use the default mainnet precompiles and wrap them with a cache. + pub fn set_precompiles( + handler: &mut EvmHandler, + cache: Arc>, + ) where + DB: Database, + { + // first we need the evm spec id, which determines the precompiles + let spec_id = handler.cfg.spec_id; + + let mut loaded_precompiles: ContextPrecompiles = + ContextPrecompiles::new(PrecompileSpecId::from_spec_id(spec_id)); + for (address, precompile) in loaded_precompiles.to_mut().iter_mut() { + // get or insert the cache for this address / spec + let mut cache = cache.write(); + let cache = cache + .cache + .entry((*address, spec_id)) + .or_insert(Arc::new(RwLock::new(LruMap::new(ByLength::new(1024))))); + + *precompile = Self::wrap_precompile(precompile.clone(), cache.clone()); + } + + // install the precompiles + handler.pre_execution.load_precompiles = Arc::new(move || loaded_precompiles.clone()); + } + + /// Given a [`ContextPrecompile`] and cache for a specific precompile, create a new precompile + /// that wraps the precompile with the cache. + fn wrap_precompile( + precompile: ContextPrecompile, + cache: Arc>>, + ) -> ContextPrecompile + where + DB: Database, + { + let ContextPrecompile::Ordinary(precompile) = precompile else { + // context stateful precompiles are not supported, due to lifetime issues or skill + // issues + panic!("precompile is not ordinary"); + }; + + let wrapped = WrappedPrecompile { precompile, cache: cache.clone() }; + + ContextPrecompile::Ordinary(Precompile::StatefulMut(Box::new(wrapped))) + } +} + +/// A custom precompile that contains the cache and precompile it wraps. +#[derive(Clone)] +pub struct WrappedPrecompile { + /// The precompile to wrap. + precompile: Precompile, + /// The cache to use. + cache: Arc>>, +} + +impl StatefulPrecompileMut for WrappedPrecompile { + fn call_mut(&mut self, bytes: &Bytes, gas_price: u64, _env: &Env) -> PrecompileResult { + let mut cache = self.cache.write(); + let key = (bytes.clone(), gas_price); + + // get the result if it exists + if let Some(result) = cache.get(&key) { + return result.clone() + } + + // call the precompile if cache miss + let output = self.precompile.call(bytes, gas_price, _env); + cache.insert(key, output.clone()); + + output + } +} + +impl ConfigureEvmEnv for MyEvmConfig { + fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { + EthEvmConfig::fill_tx_env(tx_env, transaction, sender) + } + + fn fill_cfg_env( + cfg_env: &mut CfgEnvWithHandlerCfg, + chain_spec: &ChainSpec, + header: &Header, + total_difficulty: U256, + ) { + EthEvmConfig::fill_cfg_env(cfg_env, chain_spec, header, total_difficulty) + } +} + +impl ConfigureEvm for MyEvmConfig { + type DefaultExternalContext<'a> = (); + + fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, Self::DefaultExternalContext<'a>, DB> { + let new_cache = self.precompile_cache.clone(); + EvmBuilder::default() + .with_db(db) + // add additional precompiles + .append_handler_register_box(Box::new(move |handler| { + MyEvmConfig::set_precompiles(handler, new_cache.clone()) + })) + .build() + } + + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { + let new_cache = self.precompile_cache.clone(); + EvmBuilder::default() + .with_db(db) + .with_external_context(inspector) + // add additional precompiles + .append_handler_register_box(Box::new(move |handler| { + MyEvmConfig::set_precompiles(handler, new_cache.clone()) + })) + .append_handler_register(inspector_handle_register) + .build() + } +} + +/// Builds a regular ethereum block executor that uses the custom EVM. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct MyExecutorBuilder { + /// The precompile cache to use for all executors. + precompile_cache: Arc>, +} + +impl ExecutorBuilder for MyExecutorBuilder +where + Node: FullNodeTypes, +{ + type EVM = MyEvmConfig; + type Executor = EthExecutorProvider; + + async fn build_evm( + self, + ctx: &BuilderContext, + ) -> eyre::Result<(Self::EVM, Self::Executor)> { + let evm_config = MyEvmConfig { precompile_cache: self.precompile_cache.clone() }; + Ok((evm_config.clone(), EthExecutorProvider::new(ctx.chain_spec(), evm_config))) + } +} + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let _guard = RethTracer::new().init()?; + + let tasks = TaskManager::current(); + + // create a custom chain spec + let spec = ChainSpec::builder() + .chain(Chain::mainnet()) + .genesis(Genesis::default()) + .london_activated() + .paris_activated() + .shanghai_activated() + .cancun_activated() + .build(); + + let node_config = + NodeConfig::test().with_rpc(RpcServerArgs::default().with_http()).with_chain(spec); + + let handle = NodeBuilder::new(node_config) + .testing_node(tasks.executor()) + // configure the node with regular ethereum types + .with_types::() + // use default ethereum components but with our executor + .with_components(EthereumNode::components().executor(MyExecutorBuilder::default())) + .launch() + .await + .unwrap(); + + println!("Node started"); + + handle.node_exit_future.await +} diff --git a/testing/ef-tests/src/cases/blockchain_test.rs b/testing/ef-tests/src/cases/blockchain_test.rs index fdfb2a5db6f1c..87c3b8df1d8fb 100644 --- a/testing/ef-tests/src/cases/blockchain_test.rs +++ b/testing/ef-tests/src/cases/blockchain_test.rs @@ -63,7 +63,7 @@ impl Case for BlockchainTestCase { fn run(&self) -> Result<(), Error> { // If the test is marked for skipping, return a Skipped error immediately. if self.skip { - return Err(Error::Skipped); + return Err(Error::Skipped) } // Iterate through test cases, filtering by the network type to exclude specific forks. diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index 806591c47749f..2c580dc54ea85 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -243,12 +243,12 @@ impl Account { } else { return Err(Error::Assertion(format!( "Slot {slot:?} is missing from the database. Expected {value:?}" - ))); + ))) } } else { return Err(Error::Assertion(format!( "Slot {slot:?} is missing from the database. Expected {value:?}" - ))); + ))) } } diff --git a/testing/testing-utils/src/generators.rs b/testing/testing-utils/src/generators.rs index ee09e2873070f..4ef65043f6022 100644 --- a/testing/testing-utils/src/generators.rs +++ b/testing/testing-utils/src/generators.rs @@ -250,7 +250,7 @@ where } else { let old = storage.remove(&entry.key); if matches!(old, Some(U256::ZERO)) { - return None; + return None } old };