diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index b8d3f378fca4..334df715a263 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -17,38 +17,10 @@ concurrency: jobs: prepare-reth: - if: github.repository == 'paradigmxyz/reth' - timeout-minutes: 45 - runs-on: - group: Reth - steps: - - uses: actions/checkout@v4 - - run: mkdir artifacts - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Build reth - run: | - cargo build --features asm-keccak --profile hivetests --bin reth --locked - mkdir dist && cp ./target/hivetests/reth ./dist/reth - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build and export reth image - uses: docker/build-push-action@v6 - with: - context: . - file: .github/assets/hive/Dockerfile - tags: ghcr.io/paradigmxyz/reth:latest - outputs: type=docker,dest=./artifacts/reth_image.tar - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Upload reth image - uses: actions/upload-artifact@v4 - with: - name: artifacts - path: ./artifacts + uses: ./.github/workflows/prepare-reth.yml + with: + image_tag: ghcr.io/paradigmxyz/reth:latest + binary_name: reth prepare-hive: if: github.repository == 'paradigmxyz/reth' diff --git a/.github/workflows/kurtosis-op.yml b/.github/workflows/kurtosis-op.yml index c7307d10c7bd..85a8e706c6eb 100644 --- a/.github/workflows/kurtosis-op.yml +++ b/.github/workflows/kurtosis-op.yml @@ -5,8 +5,8 @@ name: kurtosis-op on: workflow_dispatch: schedule: - # every day - - cron: "0 1 * * *" + # run every 12 hours + - cron: "0 */12 * * *" env: CARGO_TERM_COLOR: always @@ -17,38 +17,12 @@ concurrency: jobs: prepare-reth: - if: github.repository == 'paradigmxyz/reth' - timeout-minutes: 45 - runs-on: - group: Reth - steps: - - uses: actions/checkout@v4 - - run: mkdir artifacts - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Build reth - run: | - cargo build --features optimism,asm-keccak --profile hivetests --bin op-reth --manifest-path crates/optimism/bin/Cargo.toml --locked - mkdir dist && cp ./target/hivetests/op-reth ./dist/reth - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build and export reth image - uses: docker/build-push-action@v6 - with: - context: . - file: .github/assets/hive/Dockerfile - tags: ghcr.io/paradigmxyz/op-reth:kurtosis-ci - outputs: type=docker,dest=./artifacts/reth_image.tar - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Upload reth image - uses: actions/upload-artifact@v4 - with: - name: artifacts - path: ./artifacts + uses: ./.github/workflows/prepare-reth.yml + with: + image_tag: ghcr.io/paradigmxyz/op-reth:kurtosis-ci + binary_name: op-reth + cargo_features: optimism,asm-keccak + cargo_package: crates/optimism/bin/Cargo.toml test: timeout-minutes: 60 diff --git a/.github/workflows/kurtosis.yml b/.github/workflows/kurtosis.yml index 3e1b74321116..ab0c95939c8e 100644 --- a/.github/workflows/kurtosis.yml +++ b/.github/workflows/kurtosis.yml @@ -17,38 +17,10 @@ concurrency: jobs: prepare-reth: - if: github.repository == 'paradigmxyz/reth' - timeout-minutes: 45 - runs-on: - group: Reth - steps: - - uses: actions/checkout@v4 - - run: mkdir artifacts - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Build reth - run: | - cargo build --features asm-keccak --profile hivetests --bin reth --locked - mkdir dist && cp ./target/hivetests/reth ./dist/reth - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Build and export reth image - uses: docker/build-push-action@v6 - with: - context: . - file: .github/assets/hive/Dockerfile - tags: ghcr.io/paradigmxyz/reth:kurtosis-ci - outputs: type=docker,dest=./artifacts/reth_image.tar - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Upload reth image - uses: actions/upload-artifact@v4 - with: - name: artifacts - path: ./artifacts + uses: ./.github/workflows/prepare-reth.yml + with: + image_tag: ghcr.io/paradigmxyz/reth:kurtosis-ci + binary_name: reth test: timeout-minutes: 60 diff --git a/.github/workflows/prepare-reth.yml b/.github/workflows/prepare-reth.yml new file mode 100644 index 000000000000..1b5f0e70cc96 --- /dev/null +++ b/.github/workflows/prepare-reth.yml @@ -0,0 +1,66 @@ +name: Prepare Reth Image + +on: + workflow_call: + inputs: + image_tag: + required: true + type: string + description: "Docker image tag to use" + binary_name: + required: false + type: string + default: "reth" + description: "Binary name to build (reth or op-reth)" + cargo_features: + required: false + type: string + default: "asm-keccak" + description: "Cargo features to enable" + cargo_package: + required: false + type: string + description: "Optional cargo package path" + +jobs: + prepare-reth: + if: github.repository == 'paradigmxyz/reth' + timeout-minutes: 45 + runs-on: + group: Reth + steps: + - uses: actions/checkout@v4 + - run: mkdir artifacts + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Build reth + run: | + CARGO_CMD="cargo build --features ${{ inputs.cargo_features }} --profile hivetests --bin ${{ inputs.binary_name }} --locked" + if [ -n "${{ inputs.cargo_package }}" ]; then + CARGO_CMD="$CARGO_CMD --manifest-path ${{ inputs.cargo_package }}" + fi + $CARGO_CMD + mkdir dist && cp ./target/hivetests/${{ inputs.binary_name }} ./dist/reth + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and export reth image + uses: docker/build-push-action@v6 + with: + context: . + file: .github/assets/hive/Dockerfile + tags: ${{ inputs.image_tag }} + outputs: type=docker,dest=./artifacts/reth_image.tar + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Upload reth image + id: upload + uses: actions/upload-artifact@v4 + with: + name: artifacts + path: ./artifacts diff --git a/Cargo.lock b/Cargo.lock index 39900bf5e639..2f7bdd6e359b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,7 +170,7 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -275,7 +275,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", ] @@ -301,7 +301,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -329,7 +329,7 @@ dependencies = [ "rand 0.8.5", "serde_json", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", "url", ] @@ -400,7 +400,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", "url", @@ -422,7 +422,7 @@ dependencies = [ "serde_json", "tokio", "tokio-stream", - "tower 0.5.1", + "tower 0.5.2", "tracing", ] @@ -467,7 +467,7 @@ dependencies = [ "serde_json", "tokio", "tokio-stream", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -533,7 +533,7 @@ dependencies = [ "alloy-serde", "serde", "serde_with", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -614,7 +614,7 @@ dependencies = [ "alloy-serde", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -652,7 +652,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -670,7 +670,7 @@ dependencies = [ "coins-bip39", "k256", "rand 0.8.5", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -755,9 +755,9 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -773,7 +773,7 @@ dependencies = [ "alloy-transport", "reqwest", "serde_json", - "tower 0.5.1", + "tower 0.5.2", "tracing", "url", ] @@ -1220,7 +1220,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5289ec98f68f28dd809fd601059e6aa908bb8f6108620930828283d4ee23d7" dependencies = [ - "fastrand 2.2.0", + "fastrand 2.3.0", "tokio", ] @@ -1577,9 +1577,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata 0.4.9", @@ -1741,9 +1741,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2647,7 +2647,7 @@ dependencies = [ [[package]] name = "ef-tests" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -2665,7 +2665,7 @@ dependencies = [ "revm", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "walkdir", ] @@ -2840,7 +2840,7 @@ dependencies = [ "reth-node-ethereum", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -2928,7 +2928,7 @@ dependencies = [ "reth-tracing", "reth-trie-db", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", ] @@ -3179,9 +3179,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fastrlp" @@ -3696,7 +3696,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tinyvec", "tokio", "tracing", @@ -3720,7 +3720,7 @@ dependencies = [ "resolv-conf", "serde", "smallvec", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] @@ -4691,9 +4691,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libloading" @@ -5421,7 +5421,7 @@ dependencies = [ "derive_more", "serde", "serde_with", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -5436,7 +5436,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_repr", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -5473,7 +5473,7 @@ dependencies = [ "op-alloy-consensus", "op-alloy-genesis", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", "unsigned-varint", ] @@ -5527,12 +5527,12 @@ dependencies = [ "op-alloy-protocol", "serde", "snap", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "op-reth" -version = "1.1.3" +version = "1.1.4" dependencies = [ "clap", "reth-cli-util", @@ -5701,7 +5701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.5", + "thiserror 2.0.6", "ucd-trie", ] @@ -6151,7 +6151,7 @@ dependencies = [ "rustc-hash 2.1.0", "rustls", "socket2", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] @@ -6170,7 +6170,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.5", + "thiserror 2.0.6", "tinyvec", "tracing", "web-time", @@ -6178,9 +6178,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" +checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" dependencies = [ "cfg_aliases", "libc", @@ -6344,9 +6344,9 @@ checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -6453,7 +6453,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-rustls", "tokio-util", @@ -6479,7 +6479,7 @@ dependencies = [ [[package]] name = "reth" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6552,7 +6552,7 @@ dependencies = [ [[package]] name = "reth-basic-payload-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6580,7 +6580,7 @@ dependencies = [ [[package]] name = "reth-beacon-consensus" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6628,7 +6628,7 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "schnellru", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -6636,7 +6636,7 @@ dependencies = [ [[package]] name = "reth-bench" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -6664,7 +6664,7 @@ dependencies = [ "reth-rpc-types-compat", "reth-tracing", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tower 0.4.13", "tracing", @@ -6672,7 +6672,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6710,7 +6710,7 @@ dependencies = [ [[package]] name = "reth-blockchain-tree-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6720,12 +6720,12 @@ dependencies = [ "reth-primitives", "reth-primitives-traits", "reth-storage-errors", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-chain-state" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6754,7 +6754,7 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-consensus", @@ -6775,7 +6775,7 @@ dependencies = [ [[package]] name = "reth-cli" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-genesis", "clap", @@ -6788,7 +6788,7 @@ dependencies = [ [[package]] name = "reth-cli-commands" -version = "1.1.3" +version = "1.1.4" dependencies = [ "ahash", "alloy-consensus", @@ -6856,7 +6856,7 @@ dependencies = [ [[package]] name = "reth-cli-runner" -version = "1.1.3" +version = "1.1.4" dependencies = [ "reth-tasks", "tokio", @@ -6865,7 +6865,7 @@ dependencies = [ [[package]] name = "reth-cli-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -6876,14 +6876,14 @@ dependencies = [ "reth-fs-util", "secp256k1", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tikv-jemallocator", "tracy-client", ] [[package]] name = "reth-codecs" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6906,7 +6906,7 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.1.3" +version = "1.1.4" dependencies = [ "convert_case", "proc-macro2", @@ -6917,7 +6917,7 @@ dependencies = [ [[package]] name = "reth-config" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "eyre", @@ -6933,7 +6933,7 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6946,7 +6946,7 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6963,7 +6963,7 @@ dependencies = [ [[package]] name = "reth-consensus-debug-client" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -6986,7 +6986,7 @@ dependencies = [ [[package]] name = "reth-db" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7022,12 +7022,12 @@ dependencies = [ "sysinfo", "tempfile", "test-fuzz", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-db-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -7056,7 +7056,7 @@ dependencies = [ [[package]] name = "reth-db-common" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -7079,13 +7079,13 @@ dependencies = [ "reth-trie-db", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-db-models" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7102,7 +7102,7 @@ dependencies = [ [[package]] name = "reth-discv4" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7121,7 +7121,7 @@ dependencies = [ "schnellru", "secp256k1", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -7129,7 +7129,7 @@ dependencies = [ [[package]] name = "reth-discv5" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7146,14 +7146,14 @@ dependencies = [ "reth-network-peers", "reth-tracing", "secp256k1", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-dns-discovery" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-primitives", @@ -7173,7 +7173,7 @@ dependencies = [ "secp256k1", "serde", "serde_with", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -7181,7 +7181,7 @@ dependencies = [ [[package]] name = "reth-downloaders" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7211,7 +7211,7 @@ dependencies = [ "reth-testing-utils", "reth-tracing", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -7220,7 +7220,7 @@ dependencies = [ [[package]] name = "reth-e2e-test-utils" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7268,7 +7268,7 @@ dependencies = [ [[package]] name = "reth-ecies" -version = "1.1.3" +version = "1.1.4" dependencies = [ "aes", "alloy-primitives", @@ -7288,7 +7288,7 @@ dependencies = [ "secp256k1", "sha2 0.10.8", "sha3", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -7298,7 +7298,7 @@ dependencies = [ [[package]] name = "reth-engine-local" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7330,7 +7330,7 @@ dependencies = [ [[package]] name = "reth-engine-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7344,13 +7344,13 @@ dependencies = [ "reth-primitives-traits", "reth-trie", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", ] [[package]] name = "reth-engine-service" -version = "1.1.3" +version = "1.1.4" dependencies = [ "futures", "pin-project", @@ -7371,14 +7371,14 @@ dependencies = [ "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", ] [[package]] name = "reth-engine-tree" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7427,14 +7427,14 @@ dependencies = [ "reth-trie-parallel", "reth-trie-sparse", "revm-primitives", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-engine-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7466,19 +7466,19 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.1.3" +version = "1.1.4" dependencies = [ "reth-blockchain-tree-api", "reth-consensus", "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-eth-wire" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-eips", @@ -7506,7 +7506,7 @@ dependencies = [ "serde", "snap", "test-fuzz", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -7515,7 +7515,7 @@ dependencies = [ [[package]] name = "reth-eth-wire-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-consensus", @@ -7535,12 +7535,12 @@ dependencies = [ "reth-primitives", "reth-primitives-traits", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-ethereum-cli" -version = "1.1.3" +version = "1.1.4" dependencies = [ "clap", "eyre", @@ -7551,7 +7551,7 @@ dependencies = [ [[package]] name = "reth-ethereum-consensus" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7566,7 +7566,7 @@ dependencies = [ [[package]] name = "reth-ethereum-engine-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7586,7 +7586,7 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-consensus", @@ -7601,12 +7601,12 @@ dependencies = [ "proptest-derive", "rustc-hash 2.1.0", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-ethereum-payload-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7631,11 +7631,23 @@ dependencies = [ [[package]] name = "reth-ethereum-primitives" -version = "1.1.3" +version = "1.1.4" +dependencies = [ + "alloy-consensus", + "alloy-primitives", + "alloy-rlp", + "arbitrary", + "modular-bitfield", + "reth-codecs", + "reth-primitives-traits", + "reth-zstd-compressors", + "serde", + "test-fuzz", +] [[package]] name = "reth-etl" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "rayon", @@ -7645,7 +7657,7 @@ dependencies = [ [[package]] name = "reth-evm" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7673,7 +7685,7 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7696,7 +7708,7 @@ dependencies = [ [[package]] name = "reth-execution-errors" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7706,12 +7718,12 @@ dependencies = [ "reth-prune-types", "reth-storage-errors", "revm-primitives", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-execution-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7731,7 +7743,7 @@ dependencies = [ [[package]] name = "reth-exex" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7774,7 +7786,7 @@ dependencies = [ [[package]] name = "reth-exex-test-utils" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "eyre", @@ -7801,13 +7813,13 @@ dependencies = [ "reth-transaction-pool", "reth-trie-db", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", ] [[package]] name = "reth-exex-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -7824,16 +7836,16 @@ dependencies = [ [[package]] name = "reth-fs-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-invalid-block-hooks" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -7859,7 +7871,7 @@ dependencies = [ [[package]] name = "reth-ipc" -version = "1.1.3" +version = "1.1.4" dependencies = [ "async-trait", "bytes", @@ -7871,7 +7883,7 @@ dependencies = [ "rand 0.8.5", "reth-tracing", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -7881,7 +7893,7 @@ dependencies = [ [[package]] name = "reth-libmdbx" -version = "1.1.3" +version = "1.1.4" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -7896,13 +7908,13 @@ dependencies = [ "reth-mdbx-sys", "smallvec", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-mdbx-sys" -version = "1.1.3" +version = "1.1.4" dependencies = [ "bindgen", "cc", @@ -7910,7 +7922,7 @@ dependencies = [ [[package]] name = "reth-metrics" -version = "1.1.3" +version = "1.1.4" dependencies = [ "futures", "metrics", @@ -7921,28 +7933,28 @@ dependencies = [ [[package]] name = "reth-net-banlist" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", ] [[package]] name = "reth-net-nat" -version = "1.1.3" +version = "1.1.4" dependencies = [ "futures-util", "if-addrs", "reqwest", "reth-tracing", "serde_with", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-network" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -7995,7 +8007,7 @@ dependencies = [ "serial_test", "smallvec", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tokio-util", @@ -8005,7 +8017,7 @@ dependencies = [ [[package]] name = "reth-network-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rpc-types-admin", @@ -8020,14 +8032,14 @@ dependencies = [ "reth-network-types", "reth-tokio-util", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", ] [[package]] name = "reth-network-p2p" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8049,7 +8061,7 @@ dependencies = [ [[package]] name = "reth-network-peers" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -8058,14 +8070,14 @@ dependencies = [ "secp256k1", "serde_json", "serde_with", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "url", ] [[package]] name = "reth-network-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "humantime-serde", "reth-ethereum-forks", @@ -8078,7 +8090,7 @@ dependencies = [ [[package]] name = "reth-nippy-jar" -version = "1.1.3" +version = "1.1.4" dependencies = [ "anyhow", "bincode", @@ -8089,14 +8101,14 @@ dependencies = [ "reth-fs-util", "serde", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", "zstd", ] [[package]] name = "reth-node-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-rpc-types-engine", "eyre", @@ -8116,7 +8128,7 @@ dependencies = [ [[package]] name = "reth-node-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8180,7 +8192,7 @@ dependencies = [ [[package]] name = "reth-node-core" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8222,7 +8234,7 @@ dependencies = [ "serde", "shellexpand", "strum", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "toml", "tracing", @@ -8231,7 +8243,7 @@ dependencies = [ [[package]] name = "reth-node-ethereum" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-contract", @@ -8280,7 +8292,7 @@ dependencies = [ [[package]] name = "reth-node-events" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8303,7 +8315,7 @@ dependencies = [ [[package]] name = "reth-node-metrics" -version = "1.1.3" +version = "1.1.4" dependencies = [ "eyre", "http", @@ -8326,7 +8338,7 @@ dependencies = [ [[package]] name = "reth-node-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "reth-chainspec", "reth-db-api", @@ -8337,7 +8349,7 @@ dependencies = [ [[package]] name = "reth-optimism-chainspec" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-consensus", @@ -8357,7 +8369,7 @@ dependencies = [ [[package]] name = "reth-optimism-cli" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8408,7 +8420,7 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8427,7 +8439,7 @@ dependencies = [ [[package]] name = "reth-optimism-evm" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8457,7 +8469,7 @@ dependencies = [ [[package]] name = "reth-optimism-forks" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-chains", "alloy-primitives", @@ -8468,7 +8480,7 @@ dependencies = [ [[package]] name = "reth-optimism-node" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8522,7 +8534,7 @@ dependencies = [ [[package]] name = "reth-optimism-payload-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8552,13 +8564,13 @@ dependencies = [ "reth-transaction-pool", "revm", "sha2 0.10.8", - "thiserror 2.0.5", + "thiserror 2.0.6", "tracing", ] [[package]] name = "reth-optimism-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8582,7 +8594,7 @@ dependencies = [ [[package]] name = "reth-optimism-rpc" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8620,14 +8632,14 @@ dependencies = [ "reth-transaction-pool", "revm", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-optimism-storage" -version = "1.1.3" +version = "1.1.4" dependencies = [ "reth-codecs", "reth-db-api", @@ -8638,7 +8650,7 @@ dependencies = [ [[package]] name = "reth-payload-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8660,7 +8672,7 @@ dependencies = [ [[package]] name = "reth-payload-builder-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-rpc-types-engine", "async-trait", @@ -8673,7 +8685,7 @@ dependencies = [ [[package]] name = "reth-payload-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -8685,13 +8697,13 @@ dependencies = [ "reth-primitives", "revm-primitives", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", ] [[package]] name = "reth-payload-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -8700,7 +8712,7 @@ dependencies = [ [[package]] name = "reth-payload-validator" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-rpc-types", "reth-chainspec", @@ -8710,7 +8722,7 @@ dependencies = [ [[package]] name = "reth-primitives" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8757,7 +8769,7 @@ dependencies = [ [[package]] name = "reth-primitives-traits" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8785,7 +8797,7 @@ dependencies = [ [[package]] name = "reth-provider" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8835,7 +8847,7 @@ dependencies = [ [[package]] name = "reth-prune" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8860,19 +8872,18 @@ dependencies = [ "reth-tokio-util", "reth-tracing", "rustc-hash 2.1.0", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-prune-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "arbitrary", "assert_matches", - "bytes", "derive_more", "modular-bitfield", "proptest", @@ -8881,13 +8892,13 @@ dependencies = [ "serde", "serde_json", "test-fuzz", - "thiserror 2.0.5", + "thiserror 2.0.6", "toml", ] [[package]] name = "reth-revm" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -8905,7 +8916,7 @@ dependencies = [ [[package]] name = "reth-rpc" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -8967,7 +8978,7 @@ dependencies = [ "revm-primitives", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tower 0.4.13", @@ -8977,7 +8988,7 @@ dependencies = [ [[package]] name = "reth-rpc-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-json-rpc", @@ -9001,7 +9012,7 @@ dependencies = [ [[package]] name = "reth-rpc-api-testing-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9020,7 +9031,7 @@ dependencies = [ [[package]] name = "reth-rpc-builder" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9060,7 +9071,7 @@ dependencies = [ "reth-transaction-pool", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-util", "tower 0.4.13", @@ -9070,7 +9081,7 @@ dependencies = [ [[package]] name = "reth-rpc-engine-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9101,14 +9112,14 @@ dependencies = [ "reth-tokio-util", "reth-transaction-pool", "serde", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-rpc-eth-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -9151,7 +9162,7 @@ dependencies = [ [[package]] name = "reth-rpc-eth-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9185,7 +9196,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -9193,7 +9204,7 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-rpc-types-engine", "http", @@ -9210,7 +9221,7 @@ dependencies = [ [[package]] name = "reth-rpc-server-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9225,7 +9236,7 @@ dependencies = [ [[package]] name = "reth-rpc-types-compat" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9242,7 +9253,7 @@ dependencies = [ [[package]] name = "reth-stages" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9286,14 +9297,14 @@ dependencies = [ "reth-trie", "reth-trie-db", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-stages-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9314,7 +9325,7 @@ dependencies = [ "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -9322,7 +9333,7 @@ dependencies = [ [[package]] name = "reth-stages-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "arbitrary", @@ -9339,7 +9350,7 @@ dependencies = [ [[package]] name = "reth-static-file" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "assert_matches", @@ -9363,7 +9374,7 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "clap", @@ -9374,7 +9385,7 @@ dependencies = [ [[package]] name = "reth-storage-api" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9398,7 +9409,7 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-eips", "alloy-primitives", @@ -9411,7 +9422,7 @@ dependencies = [ [[package]] name = "reth-tasks" -version = "1.1.3" +version = "1.1.4" dependencies = [ "auto_impl", "dyn-clone", @@ -9420,7 +9431,7 @@ dependencies = [ "pin-project", "rayon", "reth-metrics", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", "tracing-futures", @@ -9428,7 +9439,7 @@ dependencies = [ [[package]] name = "reth-testing-utils" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9442,7 +9453,7 @@ dependencies = [ [[package]] name = "reth-tokio-util" -version = "1.1.3" +version = "1.1.4" dependencies = [ "tokio", "tokio-stream", @@ -9451,7 +9462,7 @@ dependencies = [ [[package]] name = "reth-tracing" -version = "1.1.3" +version = "1.1.4" dependencies = [ "clap", "eyre", @@ -9465,7 +9476,7 @@ dependencies = [ [[package]] name = "reth-transaction-pool" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9505,7 +9516,7 @@ dependencies = [ "serde_json", "smallvec", "tempfile", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tokio-stream", "tracing", @@ -9513,7 +9524,7 @@ dependencies = [ [[package]] name = "reth-trie" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-eips", @@ -9542,7 +9553,7 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-genesis", @@ -9572,7 +9583,7 @@ dependencies = [ [[package]] name = "reth-trie-db" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -9601,7 +9612,7 @@ dependencies = [ [[package]] name = "reth-trie-parallel" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -9621,14 +9632,14 @@ dependencies = [ "reth-trie", "reth-trie-common", "reth-trie-db", - "thiserror 2.0.5", + "thiserror 2.0.6", "tokio", "tracing", ] [[package]] name = "reth-trie-sparse" -version = "1.1.3" +version = "1.1.4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -9647,12 +9658,12 @@ dependencies = [ "reth-trie", "reth-trie-common", "smallvec", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] name = "reth-zstd-compressors" -version = "1.1.3" +version = "1.1.4" dependencies = [ "zstd", ] @@ -9688,7 +9699,7 @@ dependencies = [ "colorchoice", "revm", "serde_json", - "thiserror 2.0.5", + "thiserror 2.0.6", ] [[package]] @@ -9964,22 +9975,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -10269,18 +10280,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -10755,12 +10766,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -10813,7 +10818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", - "fastrand 2.2.0", + "fastrand 2.3.0", "once_cell", "rustix", "windows-sys 0.59.0", @@ -10894,11 +10899,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643caef17e3128658ff44d85923ef2d28af81bb71e0d67bbfe1d76f19a73e053" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "thiserror-impl 2.0.5", + "thiserror-impl 2.0.6", ] [[package]] @@ -10914,9 +10919,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995d0bbc9995d1f19d28b7215a9352b0fc3cd3a2d2ec95c2cadc485cdedbcdde" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", @@ -11190,14 +11195,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", "tower-layer", "tower-service", ] @@ -11226,7 +11231,7 @@ dependencies = [ "pin-project-lite", "tokio", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", diff --git a/Cargo.toml b/Cargo.toml index ee6282b21697..655a2cba63bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "1.1.3" +version = "1.1.4" edition = "2021" rust-version = "1.82" license = "MIT OR Apache-2.0" @@ -40,6 +40,7 @@ members = [ "crates/ethereum/node", "crates/ethereum/payload/", "crates/ethereum/primitives/", + "crates/ethereum/primitives/", "crates/etl/", "crates/evm/", "crates/evm/execution-errors", @@ -119,6 +120,7 @@ members = [ "crates/storage/provider/", "crates/storage/storage-api/", "crates/storage/zstd-compressors/", + "crates/storage/zstd-compressors/", "crates/tasks/", "crates/tokio-util/", "crates/tracing/", @@ -344,6 +346,7 @@ reth-ethereum-engine-primitives = { path = "crates/ethereum/engine-primitives" } reth-ethereum-forks = { path = "crates/ethereum-forks", default-features = false } reth-ethereum-payload-builder = { path = "crates/ethereum/payload" } reth-ethereum-primitives = { path = "crates/ethereum/primitives", default-features = false } +reth-ethereum-primitives = { path = "crates/ethereum/primitives", default-features = false } reth-etl = { path = "crates/etl" } reth-evm = { path = "crates/evm" } reth-evm-ethereum = { path = "crates/ethereum/evm" } @@ -424,12 +427,15 @@ reth-trie-db = { path = "crates/trie/db" } reth-trie-parallel = { path = "crates/trie/parallel" } reth-trie-sparse = { path = "crates/trie/sparse" } reth-zstd-compressors = { path = "crates/storage/zstd-compressors", default-features = false } +reth-zstd-compressors = { path = "crates/storage/zstd-compressors", default-features = false } # revm revm = { version = "18.0.0", features = ["std"], default-features = false } revm-inspectors = "0.13.0" +revm-inspectors = "0.13.0" revm-primitives = { version = "14.0.0", default-features = false } revm-interpreter = { version = "14.0.0", default-features = false } +revm-interpreter = { version = "14.0.0", default-features = false } # eth alloy-chains = { version = "0.1.32", default-features = false } @@ -439,8 +445,23 @@ alloy-primitives = { version = "0.8.15", default-features = false, features = [ ] } alloy-rlp = { version = "0.3.10", default-features = false } alloy-sol-types = "0.8.15" +alloy-dyn-abi = "0.8.15" +alloy-primitives = { version = "0.8.15", default-features = false, features = [ + "map-foldhash", +] } +alloy-rlp = { version = "0.3.10", default-features = false } +alloy-sol-types = "0.8.15" alloy-trie = { version = "0.7", default-features = false } +alloy-consensus = { version = "0.8.0", default-features = false } +alloy-contract = { version = "0.8.0", default-features = false } +alloy-eips = { version = "0.8.0", default-features = false } +alloy-genesis = { version = "0.8.0", default-features = false } +alloy-json-rpc = { version = "0.8.0", default-features = false } +alloy-network = { version = "0.8.0", default-features = false } +alloy-network-primitives = { version = "0.8.0", default-features = false } +alloy-node-bindings = { version = "0.8.0", default-features = false } +alloy-provider = { version = "0.8.0", features = [ alloy-consensus = { version = "0.8.0", default-features = false } alloy-contract = { version = "0.8.0", default-features = false } alloy-eips = { version = "0.8.0", default-features = false } @@ -454,6 +475,9 @@ alloy-provider = { version = "0.8.0", features = [ ], default-features = false } alloy-pubsub = { version = "0.8.0", default-features = false } alloy-rpc-client = { version = "0.8.0", default-features = false } +alloy-rpc-types = { version = "0.8.0", features = [ +alloy-pubsub = { version = "0.8.0", default-features = false } +alloy-rpc-client = { version = "0.8.0", default-features = false } alloy-rpc-types = { version = "0.8.0", features = [ "eth", ], default-features = false } @@ -470,11 +494,27 @@ alloy-serde = { version = "0.8.0", default-features = false } alloy-signer = { version = "0.8.0", default-features = false } alloy-signer-local = { version = "0.8.0", default-features = false } alloy-transport = { version = "0.8.0" } +alloy-transport-http = { version = "0.8.0", features = [ +alloy-rpc-types-admin = { version = "0.8.0", default-features = false } +alloy-rpc-types-anvil = { version = "0.8.0", default-features = false } +alloy-rpc-types-beacon = { version = "0.8.0", default-features = false } +alloy-rpc-types-debug = { version = "0.8.0", default-features = false } +alloy-rpc-types-engine = { version = "0.8.0", default-features = false } +alloy-rpc-types-eth = { version = "0.8.0", default-features = false } +alloy-rpc-types-mev = { version = "0.8.0", default-features = false } +alloy-rpc-types-trace = { version = "0.8.0", default-features = false } +alloy-rpc-types-txpool = { version = "0.8.0", default-features = false } +alloy-serde = { version = "0.8.0", default-features = false } +alloy-signer = { version = "0.8.0", default-features = false } +alloy-signer-local = { version = "0.8.0", default-features = false } +alloy-transport = { version = "0.8.0" } alloy-transport-http = { version = "0.8.0", features = [ "reqwest-rustls-tls", ], default-features = false } alloy-transport-ipc = { version = "0.8.0", default-features = false } alloy-transport-ws = { version = "0.8.0", default-features = false } +alloy-transport-ipc = { version = "0.8.0", default-features = false } +alloy-transport-ws = { version = "0.8.0", default-features = false } # op op-alloy-rpc-types = "0.8.0" @@ -482,6 +522,11 @@ op-alloy-rpc-types-engine = "0.8.0" op-alloy-rpc-jsonrpsee = "0.8.0" op-alloy-network = "0.8.0" op-alloy-consensus = "0.8.0" +op-alloy-rpc-types = "0.8.0" +op-alloy-rpc-types-engine = "0.8.0" +op-alloy-rpc-jsonrpsee = "0.8.0" +op-alloy-network = "0.8.0" +op-alloy-consensus = "0.8.0" # misc aquamarine = "0.6" @@ -499,6 +544,7 @@ clap = "4" const_format = { version = "0.2.32", features = ["rust_1_64"] } dashmap = "6.0" derive_more = { version = "1", default-features = false, features = ["full"] } +derive_more = { version = "1", default-features = false, features = ["full"] } dyn-clone = "1.0.17" eyre = "0.6" fdlimit = "0.3.0" @@ -533,6 +579,7 @@ thiserror = { version = "2.0.0", default-features = false } tracing = "0.1.0" tracing-appender = "0.2" url = { version = "2.3", default-features = false } +url = { version = "2.3", default-features = false } zstd = "0.13" byteorder = "1" diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 41a9d9f4f570..6aafa7e604c6 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -22,6 +22,7 @@ use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, Environ use reth_cli_runner::CliContext; use reth_consensus::{Consensus, FullConsensus}; use reth_errors::RethResult; +use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_types::ExecutionOutcome; use reth_fs_util as fs; @@ -228,7 +229,6 @@ impl> Command { }; let payload_config = PayloadConfig::new( Arc::new(SealedHeader::new(best_block.header().clone(), best_block.hash())), - Bytes::default(), reth_payload_builder::EthPayloadBuilderAttributes::try_new( best_block.hash(), payload_attrs, @@ -247,6 +247,7 @@ impl> Command { let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::new( EthEvmConfig::new(provider_factory.chain_spec()), + EthereumBuilderConfig::new(Default::default()), ); match payload_builder.try_build(args)? { diff --git a/bin/reth/src/commands/debug_cmd/replay_engine.rs b/bin/reth/src/commands/debug_cmd/replay_engine.rs index 4b98fc85d0b2..bd734f449a36 100644 --- a/bin/reth/src/commands/debug_cmd/replay_engine.rs +++ b/bin/reth/src/commands/debug_cmd/replay_engine.rs @@ -15,6 +15,7 @@ use reth_config::Config; use reth_consensus::FullConsensus; use reth_db::DatabaseEnv; use reth_engine_util::engine_store::{EngineMessageStore, StoredEngineApiMessage}; +use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_fs_util as fs; use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network_api::NetworkInfo; @@ -123,6 +124,7 @@ impl> Command { // Set up payload builder let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::new( EthEvmConfig::new(provider_factory.chain_spec()), + EthereumBuilderConfig::new(Default::default()), ); let payload_generator = BasicPayloadJobGenerator::with_builder( diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 6d1d8930defc..2c3e62412f20 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1376,7 +1376,10 @@ where mod tests { use super::*; use alloy_consensus::{Header, TxEip1559, EMPTY_ROOT_HASH}; - use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip4895::Withdrawals}; + use alloy_eips::{ + eip1559::{ETHEREUM_BLOCK_GAS_LIMIT, INITIAL_BASE_FEE}, + eip4895::Withdrawals, + }; use alloy_genesis::{Genesis, GenesisAccount}; use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, B256}; use assert_matches::assert_matches; @@ -1618,7 +1621,7 @@ mod tests { number, parent_hash: parent.unwrap_or_default(), gas_used: body.len() as u64 * MIN_TRANSACTION_GAS, - gas_limit: chain_spec.max_gas_limit, + gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, mix_hash: B256::random(), base_fee_per_gas: Some(INITIAL_BASE_FEE), transactions_root, diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 536f6baf96e8..5b8bb150804e 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -540,7 +540,7 @@ impl CanonicalInMemoryState { self.inner.in_memory_state.head_state().into_iter().flat_map(|head| head.iter()) } - /// Returns a `TransactionSigned` for the given `TxHash` if found. + /// Returns [`SignedTransaction`] type for the given `TxHash` if found. pub fn transaction_by_hash(&self, hash: TxHash) -> Option where N::SignedTx: Encodable2718, @@ -560,8 +560,8 @@ impl CanonicalInMemoryState { None } - /// Returns a tuple with `TransactionSigned` and `TransactionMeta` for the - /// given `TxHash` if found. + /// Returns a tuple with [`SignedTransaction`] type and [`TransactionMeta`] for the + /// given [`TxHash`] if found. pub fn transaction_by_hash_with_meta( &self, tx_hash: TxHash, diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index 1cd9f2df96b9..a5c0133f59f3 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -5,7 +5,10 @@ use crate::{ CanonStateSubscriptions, }; use alloy_consensus::{Header, Transaction as _, TxEip1559, EMPTY_ROOT_HASH}; -use alloy_eips::{eip1559::INITIAL_BASE_FEE, eip7685::Requests}; +use alloy_eips::{ + eip1559::{ETHEREUM_BLOCK_GAS_LIMIT, INITIAL_BASE_FEE}, + eip7685::Requests, +}; use alloy_primitives::{Address, BlockNumber, B256, U256}; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; @@ -137,8 +140,8 @@ impl TestBlockBuilder { number, parent_hash, gas_used: transactions.len() as u64 * MIN_TRANSACTION_GAS, - gas_limit: self.chain_spec.max_gas_limit, mix_hash: B256::random(), + gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, base_fee_per_gas: Some(INITIAL_BASE_FEE), transactions_root: calculate_transaction_root( &transactions.clone().into_iter().map(|tx| tx.into_signed()).collect::>(), diff --git a/crates/chainspec/src/api.rs b/crates/chainspec/src/api.rs index 348051bef9cc..4b0beb45cb5b 100644 --- a/crates/chainspec/src/api.rs +++ b/crates/chainspec/src/api.rs @@ -49,9 +49,6 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { /// The genesis block specification. fn genesis(&self) -> &Genesis; - /// The block gas limit. - fn max_gas_limit(&self) -> u64; - /// The bootnodes for the chain, if any. fn bootnodes(&self) -> Option>; @@ -105,10 +102,6 @@ impl EthChainSpec for ChainSpec { self.genesis() } - fn max_gas_limit(&self) -> u64 { - self.max_gas_limit - } - fn bootnodes(&self) -> Option> { self.bootnodes() } diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 1f8ebd45f45d..06abf129ce3f 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -1,8 +1,15 @@ pub use alloy_eips::eip1559::BaseFeeParams; +use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec, LazyLock, OnceLock}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_chains::{Chain, NamedChain}; -use alloy_consensus::constants::EMPTY_WITHDRAWALS; +use alloy_consensus::{ + constants::{ + DEV_GENESIS_HASH, EMPTY_WITHDRAWALS, HOLESKY_GENESIS_HASH, MAINNET_GENESIS_HASH, + SEPOLIA_GENESIS_HASH, + }, + Header, +}; use alloy_eips::{ eip1559::INITIAL_BASE_FEE, eip6110::MAINNET_DEPOSIT_CONTRACT_ADDRESS, eip7685::EMPTY_REQUESTS_HASH, @@ -10,14 +17,6 @@ use alloy_eips::{ use alloy_genesis::Genesis; use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; use derive_more::From; - -use alloy_consensus::{ - constants::{ - DEV_GENESIS_HASH, HOLESKY_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH, - }, - Header, -}; -use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use reth_ethereum_forks::{ ChainHardforks, DisplayHardforks, EthereumHardfork, EthereumHardforks, ForkCondition, ForkFilter, ForkFilterKey, ForkHash, ForkId, Hardfork, Hardforks, Head, DEV_HARDFORKS, @@ -29,8 +28,6 @@ use reth_network_peers::{ use reth_primitives_traits::SealedHeader; use reth_trie_common::root::state_root_ref_unhashed; -use crate::{constants::MAINNET_DEPOSIT_CONTRACT, once_cell_set, EthChainSpec, LazyLock, OnceLock}; - /// The Ethereum mainnet spec pub static MAINNET: LazyLock> = LazyLock::new(|| { let mut spec = ChainSpec { @@ -52,7 +49,6 @@ pub static MAINNET: LazyLock> = LazyLock::new(|| { b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: 20000, }; spec.genesis.config.dao_fork_support = true; @@ -77,7 +73,6 @@ pub static SEPOLIA: LazyLock> = LazyLock::new(|| { b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: 10000, }; spec.genesis.config.dao_fork_support = true; @@ -100,7 +95,6 @@ pub static HOLESKY: LazyLock> = LazyLock::new(|| { b256!("649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5"), )), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: 10000, }; spec.genesis.config.dao_fork_support = true; @@ -208,9 +202,6 @@ pub struct ChainSpec { /// The parameters that configure how a block's base fee is computed pub base_fee_params: BaseFeeParamsKind, - /// The maximum gas limit - pub max_gas_limit: u64, - /// The delete limit for pruner, per run. pub prune_delete_limit: usize, } @@ -226,7 +217,6 @@ impl Default for ChainSpec { hardforks: Default::default(), deposit_contract: Default::default(), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: MAINNET.prune_delete_limit, } } diff --git a/crates/consensus/beacon/src/engine/hooks/static_file.rs b/crates/consensus/beacon/src/engine/hooks/static_file.rs index b4b38239a03f..99387492c3bf 100644 --- a/crates/consensus/beacon/src/engine/hooks/static_file.rs +++ b/crates/consensus/beacon/src/engine/hooks/static_file.rs @@ -36,7 +36,11 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives< + SignedTx: Value + Compact, + BlockHeader: Value + Compact, + Receipt: Value + Compact, + >, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, @@ -152,7 +156,11 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives< + SignedTx: Value + Compact, + BlockHeader: Value + Compact, + Receipt: Value + Compact, + >, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, diff --git a/crates/consensus/beacon/src/engine/sync.rs b/crates/consensus/beacon/src/engine/sync.rs index 861aeebf1eb8..adbb531b22fd 100644 --- a/crates/consensus/beacon/src/engine/sync.rs +++ b/crates/consensus/beacon/src/engine/sync.rs @@ -9,8 +9,9 @@ use alloy_primitives::{BlockNumber, B256}; use futures::FutureExt; use reth_network_p2p::{ full_block::{FetchFullBlockFuture, FetchFullBlockRangeFuture, FullBlockClient}, - EthBlockClient, + BlockClient, }; +use reth_node_types::{BodyTy, HeaderTy}; use reth_primitives::{BlockBody, EthPrimitives, NodePrimitives, SealedBlock}; use reth_provider::providers::ProviderNodeTypes; use reth_stages_api::{ControlFlow, Pipeline, PipelineError, PipelineTarget, PipelineWithResult}; @@ -35,7 +36,7 @@ use tracing::trace; pub(crate) struct EngineSyncController where N: ProviderNodeTypes, - Client: EthBlockClient, + Client: BlockClient, { /// A downloader that can download full blocks from the network. full_block_client: FullBlockClient, @@ -51,10 +52,10 @@ where /// In-flight full block _range_ requests in progress. inflight_block_range_requests: Vec>, /// Sender for engine events. - event_sender: EventSender, + event_sender: EventSender>, /// Buffered blocks from downloads - this is a min-heap of blocks, using the block number for /// ordering. This means the blocks will be popped from the heap with ascending block numbers. - range_buffered_blocks: BinaryHeap>, + range_buffered_blocks: BinaryHeap, BodyTy>>>, /// Max block after which the consensus engine would terminate the sync. Used for debugging /// purposes. max_block: Option, @@ -65,7 +66,7 @@ where impl EngineSyncController where N: ProviderNodeTypes, - Client: EthBlockClient + 'static, + Client: BlockClient, { /// Create a new instance pub(crate) fn new( @@ -74,7 +75,7 @@ where pipeline_task_spawner: Box, max_block: Option, chain_spec: Arc, - event_sender: EventSender, + event_sender: EventSender>, ) -> Self { Self { full_block_client: FullBlockClient::new( @@ -92,7 +93,13 @@ where metrics: EngineSyncMetrics::default(), } } +} +impl EngineSyncController +where + N: ProviderNodeTypes, + Client: BlockClient
, Body = BodyTy> + 'static, +{ /// Sets the metrics for the active downloads fn update_block_download_metrics(&self) { self.metrics.active_block_downloads.set(self.inflight_full_block_requests.len() as f64); @@ -234,7 +241,7 @@ where /// Advances the pipeline state. /// /// This checks for the result in the channel, or returns pending if the pipeline is idle. - fn poll_pipeline(&mut self, cx: &mut Context<'_>) -> Poll { + fn poll_pipeline(&mut self, cx: &mut Context<'_>) -> Poll> { let res = match self.pipeline_state { PipelineState::Idle(_) => return Poll::Pending, PipelineState::Running(ref mut fut) => { @@ -259,7 +266,7 @@ where /// This will spawn the pipeline if it is idle and a target is set or if the pipeline is set to /// run continuously. - fn try_spawn_pipeline(&mut self) -> Option { + fn try_spawn_pipeline(&mut self) -> Option> { match &mut self.pipeline_state { PipelineState::Idle(pipeline) => { let target = self.pending_pipeline_target.take()?; @@ -286,7 +293,7 @@ where } /// Advances the sync process. - pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll { + pub(crate) fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { // try to spawn a pipeline if a target is set if let Some(event) = self.try_spawn_pipeline() { return Poll::Ready(event) @@ -420,10 +427,11 @@ impl PipelineState { mod tests { use super::*; use alloy_consensus::Header; + use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use assert_matches::assert_matches; use futures::poll; use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET}; - use reth_network_p2p::{either::Either, test_utils::TestFullBlockClient}; + use reth_network_p2p::{either::Either, test_utils::TestFullBlockClient, EthBlockClient}; use reth_primitives::{BlockBody, SealedHeader}; use reth_provider::{ test_utils::{create_test_provider_factory_with_chain_spec, MockNodeTypesWithDB}, @@ -626,7 +634,7 @@ mod tests { let client = TestFullBlockClient::default(); let header = Header { base_fee_per_gas: Some(7), - gas_limit: chain_spec.max_gas_limit, + gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, ..Default::default() }; let header = SealedHeader::seal(header); diff --git a/crates/engine/tree/benches/state_root_task.rs b/crates/engine/tree/benches/state_root_task.rs index 391fd333d12f..9055190fb6f4 100644 --- a/crates/engine/tree/benches/state_root_task.rs +++ b/crates/engine/tree/benches/state_root_task.rs @@ -13,7 +13,11 @@ use reth_provider::{ HashingWriter, ProviderFactory, }; use reth_testing_utils::generators::{self, Rng}; -use reth_trie::TrieInput; +use reth_trie::{ + hashed_cursor::HashedPostStateCursorFactory, proof::ProofBlindedProviderFactory, + trie_cursor::InMemoryTrieCursorFactory, TrieInput, +}; +use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use revm_primitives::{ Account as RevmAccount, AccountInfo, AccountStatus, Address, EvmState, EvmStorageSlot, HashMap, B256, KECCAK_EMPTY, U256, @@ -139,20 +143,38 @@ fn bench_state_root(c: &mut Criterion) { consistent_view: ConsistentDbView::new(factory, None), input: trie_input, }; + let provider = config.consistent_view.provider_ro().unwrap(); + let nodes_sorted = config.input.nodes.clone().into_sorted(); + let state_sorted = config.input.state.clone().into_sorted(); + let prefix_sets = Arc::new(config.input.prefix_sets.clone()); - (config, state_updates) + (config, state_updates, provider, nodes_sorted, state_sorted, prefix_sets) }, - |(config, state_updates)| { - let task = StateRootTask::new(config); - let mut hook = task.state_hook(); - let handle = task.spawn(); - - for update in state_updates { - hook.on_state(&update) - } - drop(hook); - - black_box(handle.wait_for_result().expect("task failed")); + |(config, state_updates, provider, nodes_sorted, state_sorted, prefix_sets)| { + let blinded_provider_factory = ProofBlindedProviderFactory::new( + InMemoryTrieCursorFactory::new( + DatabaseTrieCursorFactory::new(provider.tx_ref()), + &nodes_sorted, + ), + HashedPostStateCursorFactory::new( + DatabaseHashedCursorFactory::new(provider.tx_ref()), + &state_sorted, + ), + prefix_sets, + ); + + black_box(std::thread::scope(|scope| { + let task = StateRootTask::new(config, blinded_provider_factory); + let mut hook = task.state_hook(); + let handle = task.spawn(scope); + + for update in state_updates { + hook.on_state(&update) + } + drop(hook); + + handle.wait_for_result().expect("task failed") + })); }, ) }, diff --git a/crates/engine/tree/src/backfill.rs b/crates/engine/tree/src/backfill.rs index 2ed0e758d505..a0eb8dd957e1 100644 --- a/crates/engine/tree/src/backfill.rs +++ b/crates/engine/tree/src/backfill.rs @@ -231,6 +231,7 @@ mod tests { use super::*; use crate::test_utils::{insert_headers_into_client, TestPipelineBuilder}; use alloy_consensus::Header; + use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use alloy_primitives::{BlockNumber, B256}; use assert_matches::assert_matches; use futures::poll; @@ -264,13 +265,13 @@ mod tests { checkpoint: StageCheckpoint::new(BlockNumber::from(pipeline_done_after)), done: true, })])) - .build(chain_spec.clone()); + .build(chain_spec); let pipeline_sync = PipelineSync::new(pipeline, Box::::default()); let client = TestFullBlockClient::default(); let header = Header { base_fee_per_gas: Some(7), - gas_limit: chain_spec.max_gas_limit, + gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, ..Default::default() }; let header = SealedHeader::seal(header); diff --git a/crates/engine/tree/src/download.rs b/crates/engine/tree/src/download.rs index 199e5f964061..1e42e25477b1 100644 --- a/crates/engine/tree/src/download.rs +++ b/crates/engine/tree/src/download.rs @@ -321,6 +321,7 @@ mod tests { use super::*; use crate::test_utils::insert_headers_into_client; use alloy_consensus::Header; + use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use assert_matches::assert_matches; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::{ChainSpecBuilder, MAINNET}; @@ -346,7 +347,7 @@ mod tests { let client = TestFullBlockClient::default(); let header = Header { base_fee_per_gas: Some(7), - gas_limit: chain_spec.max_gas_limit, + gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, ..Default::default() }; let header = SealedHeader::seal(header); diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 72b18d49f52c..7254cc882a7e 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -14,7 +14,8 @@ use reth_trie::{ use reth_trie_db::DatabaseProof; use reth_trie_parallel::root::ParallelStateRootError; use reth_trie_sparse::{ - errors::{SparseStateTrieResult, SparseTrieErrorKind}, + blinded::{BlindedProvider, BlindedProviderFactory}, + errors::{SparseStateTrieResult, SparseTrieError, SparseTrieErrorKind}, SparseStateTrie, }; use revm_primitives::{keccak256, EvmState, B256}; @@ -25,6 +26,7 @@ use std::{ mpsc::{self, channel, Receiver, Sender}, Arc, }, + thread::{self}, time::{Duration, Instant}, }; use tracing::{debug, error, trace}; @@ -68,7 +70,7 @@ pub struct StateRootConfig { /// Messages used internally by the state root task #[derive(Debug)] #[allow(dead_code)] -pub enum StateRootMessage { +pub enum StateRootMessage { /// New state update from transaction execution StateUpdate(EvmState), /// Proof calculation completed for a specific state update @@ -83,7 +85,7 @@ pub enum StateRootMessage { /// State root calculation completed RootCalculated { /// The updated sparse trie - trie: Box, + trie: Box>, /// Time taken to calculate the root elapsed: Duration, }, @@ -159,24 +161,24 @@ impl ProofSequencer { /// A wrapper for the sender that signals completion when dropped #[allow(dead_code)] -pub(crate) struct StateHookSender(Sender); +pub(crate) struct StateHookSender(Sender>); #[allow(dead_code)] -impl StateHookSender { - pub(crate) const fn new(inner: Sender) -> Self { +impl StateHookSender { + pub(crate) const fn new(inner: Sender>) -> Self { Self(inner) } } -impl Deref for StateHookSender { - type Target = Sender; +impl Deref for StateHookSender { + type Target = Sender>; fn deref(&self) -> &Self::Target { &self.0 } } -impl Drop for StateHookSender { +impl Drop for StateHookSender { fn drop(&mut self) { // Send completion signal when the sender is dropped let _ = self.0.send(StateRootMessage::FinishedStateUpdates); @@ -224,24 +226,24 @@ fn evm_state_to_hashed_post_state(update: EvmState) -> HashedPostState { /// to the tree. /// Then it updates relevant leaves according to the result of the transaction. #[derive(Debug)] -pub struct StateRootTask { +pub struct StateRootTask { /// Task configuration. config: StateRootConfig, /// Receiver for state root related messages. - rx: Receiver, + rx: Receiver>, /// Sender for state root related messages. - tx: Sender, + tx: Sender>, /// Proof targets that have been already fetched. fetched_proof_targets: MultiProofTargets, /// Proof sequencing handler. proof_sequencer: ProofSequencer, /// The sparse trie used for the state root calculation. If [`None`], then update is in /// progress. - sparse_trie: Option>, + sparse_trie: Option>>, } #[allow(dead_code)] -impl StateRootTask +impl<'env, Factory, ABP, SBP, BPF> StateRootTask where Factory: DatabaseProviderFactory + StateCommitmentProvider @@ -249,9 +251,15 @@ where + Send + Sync + 'static, + ABP: BlindedProvider + Send + Sync + 'env, + SBP: BlindedProvider + Send + Sync + 'env, + BPF: BlindedProviderFactory + + Send + + Sync + + 'env, { /// Creates a new state root task with the unified message channel - pub fn new(config: StateRootConfig) -> Self { + pub fn new(config: StateRootConfig, blinded_provider: BPF) -> Self { let (tx, rx) = channel(); Self { @@ -260,18 +268,19 @@ where tx, fetched_proof_targets: Default::default(), proof_sequencer: ProofSequencer::new(), - sparse_trie: Some(Box::new(SparseStateTrie::default().with_updates(true))), + sparse_trie: Some(Box::new(SparseStateTrie::new(blinded_provider).with_updates(true))), } } /// Spawns the state root task and returns a handle to await its result. - pub fn spawn(self) -> StateRootHandle { + pub fn spawn<'scope>(self, scope: &'scope thread::Scope<'scope, 'env>) -> StateRootHandle { let (tx, rx) = mpsc::sync_channel(1); std::thread::Builder::new() .name("State Root Task".to_string()) - .spawn(move || { + .spawn_scoped(scope, move || { debug!(target: "engine::tree", "Starting state root task"); - let result = self.run(); + + let result = rayon::scope(|scope| self.run(scope)); let _ = tx.send(result); }) .expect("failed to spawn state root thread"); @@ -294,12 +303,13 @@ where /// /// Returns proof targets derived from the state update. fn on_state_update( + scope: &rayon::Scope<'env>, view: ConsistentDbView, input: Arc, update: EvmState, fetched_proof_targets: &mut MultiProofTargets, proof_sequence_number: u64, - state_root_message_sender: Sender, + state_root_message_sender: Sender>, ) { let hashed_state_update = evm_state_to_hashed_post_state(update); @@ -309,7 +319,7 @@ where } // Dispatch proof gathering for this state update - rayon::spawn(move || { + scope.spawn(move |_| { let provider = match view.provider_ro() { Ok(provider) => provider, Err(error) => { @@ -362,7 +372,12 @@ where } /// Spawns root calculation with the current state and proofs. - fn spawn_root_calculation(&mut self, state: HashedPostState, multiproof: MultiProof) { + fn spawn_root_calculation( + &mut self, + scope: &rayon::Scope<'env>, + state: HashedPostState, + multiproof: MultiProof, + ) { let Some(trie) = self.sparse_trie.take() else { return }; trace!( @@ -376,7 +391,7 @@ where let targets = get_proof_targets(&state, &HashMap::default()); let tx = self.tx.clone(); - rayon::spawn(move || { + scope.spawn(move |_| { let result = update_sparse_trie(trie, multiproof, targets, state); match result { Ok((trie, elapsed)) => { @@ -394,7 +409,7 @@ where }); } - fn run(mut self) -> StateRootResult { + fn run(mut self, scope: &rayon::Scope<'env>) -> StateRootResult { let mut current_state_update = HashedPostState::default(); let mut current_multiproof = MultiProof::default(); let mut updates_received = 0; @@ -414,6 +429,7 @@ where "Received new state update" ); Self::on_state_update( + scope, self.config.consistent_view.clone(), self.config.input.clone(), update, @@ -443,7 +459,11 @@ where current_multiproof.extend(combined_proof); current_state_update.extend(combined_state_update); } else { - self.spawn_root_calculation(combined_state_update, combined_proof); + self.spawn_root_calculation( + scope, + combined_state_update, + combined_proof, + ); } } } @@ -481,6 +501,7 @@ where "Spawning subsequent root calculation" ); self.spawn_root_calculation( + scope, std::mem::take(&mut current_state_update), std::mem::take(&mut current_multiproof), ); @@ -555,12 +576,16 @@ fn get_proof_targets( /// Updates the sparse trie with the given proofs and state, and returns the updated trie and the /// time it took. -fn update_sparse_trie( - mut trie: Box, +fn update_sparse_trie< + ABP: BlindedProvider + Send + Sync, + SBP: BlindedProvider + Send + Sync, + BPF: BlindedProviderFactory + Send + Sync, +>( + mut trie: Box>, multiproof: MultiProof, targets: MultiProofTargets, state: HashedPostState, -) -> SparseStateTrieResult<(Box, Duration)> { +) -> SparseStateTrieResult<(Box>, Duration)> { trace!(target: "engine::root::sparse", "Updating sparse trie"); let started_at = Instant::now(); @@ -582,12 +607,10 @@ fn update_sparse_trie( trace!(target: "engine::root::sparse", ?address, "Wiping storage"); storage_trie.wipe()?; } - for (slot, value) in storage.storage { let slot_nibbles = Nibbles::unpack(slot); if value.is_zero() { trace!(target: "engine::root::sparse", ?address, ?slot, "Removing storage slot"); - storage_trie.remove_leaf(&slot_nibbles)?; } else { trace!(target: "engine::root::sparse", ?address, ?slot, "Updating storage slot"); @@ -629,7 +652,11 @@ mod tests { providers::ConsistentDbView, test_utils::create_test_provider_factory, HashingWriter, }; use reth_testing_utils::generators::{self, Rng}; - use reth_trie::{test_utils::state_root, TrieInput}; + use reth_trie::{ + hashed_cursor::HashedPostStateCursorFactory, proof::ProofBlindedProviderFactory, + test_utils::state_root, trie_cursor::InMemoryTrieCursorFactory, TrieInput, + }; + use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use revm_primitives::{ Account as RevmAccount, AccountInfo, AccountStatus, Address, EvmState, EvmStorageSlot, HashMap, B256, KECCAK_EMPTY, U256, @@ -746,16 +773,32 @@ mod tests { consistent_view: ConsistentDbView::new(factory, None), input: Arc::new(TrieInput::from_state(hashed_state)), }; - let task = StateRootTask::new(config); - let mut state_hook = task.state_hook(); - let handle = task.spawn(); + let provider = config.consistent_view.provider_ro().unwrap(); + let nodes_sorted = config.input.nodes.clone().into_sorted(); + let state_sorted = config.input.state.clone().into_sorted(); + let blinded_provider_factory = ProofBlindedProviderFactory::new( + InMemoryTrieCursorFactory::new( + DatabaseTrieCursorFactory::new(provider.tx_ref()), + &nodes_sorted, + ), + HashedPostStateCursorFactory::new( + DatabaseHashedCursorFactory::new(provider.tx_ref()), + &state_sorted, + ), + Arc::new(config.input.prefix_sets.clone()), + ); + let (root_from_task, _) = std::thread::scope(|std_scope| { + let task = StateRootTask::new(config, blinded_provider_factory); + let mut state_hook = task.state_hook(); + let handle = task.spawn(std_scope); - for update in state_updates { - state_hook.on_state(&update); - } - drop(state_hook); + for update in state_updates { + state_hook.on_state(&update); + } + drop(state_hook); - let (root_from_task, _) = handle.wait_for_result().expect("task failed"); + handle.wait_for_result().expect("task failed") + }); let root_from_base = state_root(accumulated_state); assert_eq!( diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 24e141622842..84a8a0f342c2 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -415,7 +415,7 @@ where // Compute or add new fields transactions_root: proofs::calculate_transaction_root(&transactions), - receipts_root: outcome.receipts_root_slow(reorg_target.header.number).unwrap(), + receipts_root: outcome.ethereum_receipts_root(reorg_target.header.number).unwrap(), logs_bloom: outcome.block_logs_bloom(reorg_target.header.number).unwrap(), gas_used: cumulative_gas_used, blob_gas_used: blob_gas_used.map(Into::into), diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 6cbbb69c906b..99818ef548fd 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -421,8 +421,8 @@ mod tests { let err = executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { + &BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: BlockBody { transactions: vec![], @@ -430,8 +430,8 @@ mod tests { withdrawals: None, }, }, - senders: vec![], - }, + vec![], + ), U256::ZERO, ) .into(), @@ -452,8 +452,8 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { + &BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: BlockBody { transactions: vec![], @@ -461,8 +461,8 @@ mod tests { withdrawals: None, }, }, - senders: vec![], - }, + vec![], + ), U256::ZERO, ) .into(), @@ -522,8 +522,8 @@ mod tests { .batch_executor(StateProviderDatabase::new(&db)) .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { + &BlockWithSenders::new_unchecked( + Block { header, body: BlockBody { transactions: vec![], @@ -531,8 +531,8 @@ mod tests { withdrawals: None, }, }, - senders: vec![], - }, + vec![], + ), U256::ZERO, ) .into(), @@ -576,8 +576,8 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { + &BlockWithSenders::new_unchecked( + Block { header, body: BlockBody { transactions: vec![], @@ -585,8 +585,8 @@ mod tests { withdrawals: None, }, }, - senders: vec![], - }, + vec![], + ), U256::ZERO, ) .into(), @@ -622,10 +622,10 @@ mod tests { let _err = executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header: header.clone(), body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -643,10 +643,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -697,10 +697,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header: header.clone(), body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header: header.clone(), body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -773,10 +773,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -816,10 +816,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -866,10 +866,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -922,10 +922,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -970,10 +970,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -1005,10 +1005,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -1043,10 +1043,10 @@ mod tests { executor .execute_and_verify_one( ( - &BlockWithSenders { - block: Block { header, body: Default::default() }, - senders: vec![], - }, + &BlockWithSenders::new_unchecked( + Block { header, body: Default::default() }, + vec![], + ), U256::ZERO, ) .into(), @@ -1261,8 +1261,8 @@ mod tests { let header = Header { timestamp: 1, number: 1, ..Header::default() }; - let block = BlockWithSenders { - block: Block { + let block = &BlockWithSenders::new_unchecked( + Block { header, body: BlockBody { transactions: vec![], @@ -1270,8 +1270,8 @@ mod tests { withdrawals: Some(vec![withdrawal].into()), }, }, - senders: vec![], - }; + vec![], + ); let provider = executor_provider(chain_spec); let executor = provider.executor(StateProviderDatabase::new(&db)); @@ -1280,7 +1280,7 @@ mod tests { let tx_clone = tx.clone(); let _output = executor - .execute_with_state_hook((&block, U256::ZERO).into(), move |state: &EvmState| { + .execute_with_state_hook((block, U256::ZERO).into(), move |state: &EvmState| { if let Some(account) = state.get(&withdrawal_recipient) { let _ = tx_clone.send(account.info.balance); } diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index f5fe1dac234c..633705384a8b 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -27,6 +27,7 @@ reth-consensus.workspace = true reth-beacon-consensus.workspace = true reth-rpc.workspace = true reth-node-api.workspace = true +reth-node-core.workspace = true reth-chainspec.workspace = true reth-primitives.workspace = true reth-revm = { workspace = true, features = ["std"] } @@ -43,7 +44,6 @@ reth-chainspec.workspace = true reth-db.workspace = true reth-exex.workspace = true reth-node-api.workspace = true -reth-node-core.workspace = true reth-payload-primitives.workspace = true reth-e2e-test-utils.workspace = true reth-rpc-eth-api.workspace = true diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 4d87be68f5dc..7b1ce7d899a4 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -8,6 +8,7 @@ use reth_chainspec::ChainSpec; use reth_ethereum_engine_primitives::{ EthBuiltPayload, EthPayloadAttributes, EthPayloadBuilderAttributes, }; +use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_evm::execute::BasicBlockExecutorProvider; use reth_evm_ethereum::execute::EthExecutionStrategyFactory; use reth_network::{EthNetworkPrimitives, NetworkHandle, PeersInfo}; @@ -23,6 +24,7 @@ use reth_node_builder::{ rpc::{EngineValidatorBuilder, RpcAddOns}, BuilderContext, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, PayloadTypes, }; +use reth_node_core::version::default_extra_data_bytes; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_primitives::{EthPrimitives, PooledTransactionsElement}; use reth_provider::{CanonStateSubscriptions, EthStorage}; @@ -228,9 +230,24 @@ where } /// A basic ethereum payload service. -#[derive(Debug, Default, Clone)] -#[non_exhaustive] -pub struct EthereumPayloadBuilder; +#[derive(Clone, Debug)] +pub struct EthereumPayloadBuilder { + /// Payload builder configuration. + config: EthereumBuilderConfig, +} + +impl Default for EthereumPayloadBuilder { + fn default() -> Self { + Self { config: EthereumBuilderConfig::new(default_extra_data_bytes()) } + } +} + +impl EthereumPayloadBuilder { + /// Create new ethereum payload builder. + pub const fn new(config: EthereumBuilderConfig) -> Self { + Self { config } + } +} impl EthereumPayloadBuilder { /// A helper method initializing [`PayloadBuilderService`] with the given EVM config. @@ -254,7 +271,7 @@ impl EthereumPayloadBuilder { >, { let payload_builder = - reth_ethereum_payload_builder::EthereumPayloadBuilder::new(evm_config); + reth_ethereum_payload_builder::EthereumPayloadBuilder::new(evm_config, self.config); let conf = ctx.payload_builder_config(); let payload_job_config = BasicPayloadJobGeneratorConfig::default() diff --git a/crates/ethereum/payload/src/config.rs b/crates/ethereum/payload/src/config.rs new file mode 100644 index 000000000000..deacce62f70b --- /dev/null +++ b/crates/ethereum/payload/src/config.rs @@ -0,0 +1,22 @@ +use alloy_primitives::Bytes; + +/// Settings for the Ethereum builder. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct EthereumBuilderConfig { + /// Block extra data. + pub extra_data: Bytes, +} + +impl EthereumBuilderConfig { + /// Create new payload builder config. + pub const fn new(extra_data: Bytes) -> Self { + Self { extra_data } + } +} + +impl EthereumBuilderConfig { + /// Returns owned extra data bytes for the block. + pub fn extra_data(&self) -> Bytes { + self.extra_data.clone() + } +} diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index f909d3840e22..575b12659c76 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -50,21 +50,26 @@ use revm::{ use std::sync::Arc; use tracing::{debug, trace, warn}; +mod config; +pub use config::*; + type BestTransactionsIter = Box< dyn BestTransactions::Transaction>>>, >; /// Ethereum payload builder -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct EthereumPayloadBuilder { /// The type responsible for creating the evm. evm_config: EvmConfig, + /// Payload builder configuration. + builder_config: EthereumBuilderConfig, } impl EthereumPayloadBuilder { /// `EthereumPayloadBuilder` constructor. - pub const fn new(evm_config: EvmConfig) -> Self { - Self { evm_config } + pub const fn new(evm_config: EvmConfig, builder_config: EthereumBuilderConfig) -> Self { + Self { evm_config, builder_config } } } @@ -107,9 +112,14 @@ where .map_err(PayloadBuilderError::other)?; let pool = args.pool.clone(); - default_ethereum_payload(self.evm_config.clone(), args, cfg_env, block_env, |attributes| { - pool.best_transactions_with_attributes(attributes) - }) + default_ethereum_payload( + self.evm_config.clone(), + self.builder_config.clone(), + args, + cfg_env, + block_env, + |attributes| pool.best_transactions_with_attributes(attributes), + ) } fn build_empty_payload( @@ -133,9 +143,14 @@ where let pool = args.pool.clone(); - default_ethereum_payload(self.evm_config.clone(), args, cfg_env, block_env, |attributes| { - pool.best_transactions_with_attributes(attributes) - })? + default_ethereum_payload( + self.evm_config.clone(), + self.builder_config.clone(), + args, + cfg_env, + block_env, + |attributes| pool.best_transactions_with_attributes(attributes), + )? .into_payload() .ok_or_else(|| PayloadBuilderError::MissingPayload) } @@ -149,6 +164,7 @@ where #[inline] pub fn default_ethereum_payload( evm_config: EvmConfig, + builder_config: EthereumBuilderConfig, args: BuildArguments, initialized_cfg: CfgEnvWithHandlerCfg, initialized_block_env: BlockEnv, @@ -167,7 +183,7 @@ where let state = StateProviderDatabase::new(state_provider); let mut db = State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build(); - let PayloadConfig { parent_header, extra_data, attributes } = config; + let PayloadConfig { parent_header, attributes } = config; debug!(target: "payload_builder", id=%attributes.id, parent_header = ?parent_header.hash(), parent_number = parent_header.number, "building new payload"); let mut cumulative_gas_used = 0; @@ -408,7 +424,7 @@ where vec![requests.clone().unwrap_or_default()], ); let receipts_root = - execution_outcome.receipts_root_slow(block_number).expect("Number is in range"); + execution_outcome.ethereum_receipts_root(block_number).expect("Number is in range"); let logs_bloom = execution_outcome.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root @@ -470,7 +486,7 @@ where gas_limit: block_gas_limit, difficulty: U256::ZERO, gas_used: cumulative_gas_used, - extra_data, + extra_data: builder_config.extra_data, parent_beacon_block_root: attributes.parent_beacon_block_root, blob_gas_used: blob_gas_used.map(Into::into), excess_blob_gas: excess_blob_gas.map(Into::into), diff --git a/crates/ethereum/primitives/Cargo.toml b/crates/ethereum/primitives/Cargo.toml index a016d7dd652c..15190219cae8 100644 --- a/crates/ethereum/primitives/Cargo.toml +++ b/crates/ethereum/primitives/Cargo.toml @@ -12,7 +12,44 @@ description = "Ethereum primitive types" workspace = true [dependencies] +# reth +reth-codecs = { workspace = true, optional = true } +reth-primitives-traits.workspace = true +reth-zstd-compressors = { workspace = true, optional = true } + +# ethereum +alloy-primitives.workspace = true +alloy-consensus.workspace = true +alloy-rlp.workspace = true + +# misc +arbitrary = { workspace = true, optional = true, features = ["derive"] } +modular-bitfield = { workspace = true, optional = true } +serde.workspace = true + +[dev-dependencies] +test-fuzz.workspace = true [features] default = ["std"] -std = [] \ No newline at end of file +std = [ + "alloy-consensus/std", + "alloy-primitives/std", + "alloy-rlp/std", + "reth-primitives-traits/std", + "reth-zstd-compressors?/std", + "serde/std" +] +reth-codec = [ + "std", + "dep:reth-codecs", + "dep:modular-bitfield", + "dep:reth-zstd-compressors", +] +arbitrary = [ + "dep:arbitrary", + "alloy-consensus/arbitrary", + "alloy-primitives/arbitrary", + "reth-codecs?/arbitrary", + "reth-primitives-traits/arbitrary" +] diff --git a/crates/ethereum/primitives/src/lib.rs b/crates/ethereum/primitives/src/lib.rs index 78bb5d75f194..03cbade3fe69 100644 --- a/crates/ethereum/primitives/src/lib.rs +++ b/crates/ethereum/primitives/src/lib.rs @@ -8,3 +8,8 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +mod receipt; +pub use receipt::*; diff --git a/crates/ethereum/primitives/src/receipt.rs b/crates/ethereum/primitives/src/receipt.rs new file mode 100644 index 000000000000..4a37cc704cf3 --- /dev/null +++ b/crates/ethereum/primitives/src/receipt.rs @@ -0,0 +1,209 @@ +use alloc::vec::Vec; +use alloy_consensus::{ + Eip2718EncodableReceipt, Eip658Value, ReceiptWithBloom, RlpDecodableReceipt, + RlpEncodableReceipt, TxReceipt, TxType, Typed2718, +}; +use alloy_primitives::{Bloom, Log}; +use alloy_rlp::{BufMut, Decodable, Encodable, Header}; +use reth_primitives_traits::InMemorySize; +use serde::{Deserialize, Serialize}; + +/// Typed ethereum transaction receipt. +/// Receipt containing result of transaction execution. +#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +#[cfg_attr(feature = "reth-codec", derive(reth_codecs::CompactZstd))] +#[cfg_attr(feature = "reth-codec", reth_codecs::add_arbitrary_tests)] +#[cfg_attr(feature = "reth-codec", reth_zstd( + compressor = reth_zstd_compressors::RECEIPT_COMPRESSOR, + decompressor = reth_zstd_compressors::RECEIPT_DECOMPRESSOR +))] +pub struct Receipt { + /// Receipt type. + #[serde(with = "tx_type_serde")] + pub tx_type: TxType, + /// If transaction is executed successfully. + /// + /// This is the `statusCode` + pub success: bool, + /// Gas used + pub cumulative_gas_used: u64, + /// Log send from contracts. + pub logs: Vec, +} + +impl Receipt { + /// Returns length of RLP-encoded receipt fields with the given [`Bloom`] without an RLP header. + pub fn rlp_encoded_fields_length(&self, bloom: &Bloom) -> usize { + self.success.length() + + self.cumulative_gas_used.length() + + bloom.length() + + self.logs.length() + } + + /// RLP-encodes receipt fields with the given [`Bloom`] without an RLP header. + pub fn rlp_encode_fields(&self, bloom: &Bloom, out: &mut dyn BufMut) { + self.success.encode(out); + self.cumulative_gas_used.encode(out); + bloom.encode(out); + self.logs.encode(out); + } + + /// Returns RLP header for inner encoding. + pub fn rlp_header_inner(&self, bloom: &Bloom) -> Header { + Header { list: true, payload_length: self.rlp_encoded_fields_length(bloom) } + } + + /// RLP-decodes the receipt from the provided buffer. This does not expect a type byte or + /// network header. + pub fn rlp_decode_inner( + buf: &mut &[u8], + tx_type: TxType, + ) -> alloy_rlp::Result> { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + + let remaining = buf.len(); + + let success = Decodable::decode(buf)?; + let cumulative_gas_used = Decodable::decode(buf)?; + let logs_bloom = Decodable::decode(buf)?; + let logs = Decodable::decode(buf)?; + + if buf.len() + header.payload_length != remaining { + return Err(alloy_rlp::Error::UnexpectedLength); + } + + Ok(ReceiptWithBloom { + receipt: Self { cumulative_gas_used, tx_type, success, logs }, + logs_bloom, + }) + } +} + +impl Eip2718EncodableReceipt for Receipt { + fn eip2718_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize { + !self.tx_type.is_legacy() as usize + self.rlp_header_inner(bloom).length_with_payload() + } + + fn eip2718_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) { + if !self.tx_type.is_legacy() { + out.put_u8(self.tx_type as u8); + } + self.rlp_header_inner(bloom).encode(out); + self.rlp_encode_fields(bloom, out); + } +} + +impl RlpEncodableReceipt for Receipt { + fn rlp_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize { + let mut len = self.eip2718_encoded_length_with_bloom(bloom); + if !self.tx_type.is_legacy() { + len += Header { + list: false, + payload_length: self.eip2718_encoded_length_with_bloom(bloom), + } + .length(); + } + + len + } + + fn rlp_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) { + if !self.tx_type.is_legacy() { + Header { list: false, payload_length: self.eip2718_encoded_length_with_bloom(bloom) } + .encode(out); + } + self.eip2718_encode_with_bloom(bloom, out); + } +} + +impl RlpDecodableReceipt for Receipt { + fn rlp_decode_with_bloom(buf: &mut &[u8]) -> alloy_rlp::Result> { + let header_buf = &mut &**buf; + let header = Header::decode(header_buf)?; + + // Legacy receipt, reuse initial buffer without advancing + if header.list { + return Self::rlp_decode_inner(buf, TxType::Legacy) + } + + // Otherwise, advance the buffer and try decoding type flag followed by receipt + *buf = *header_buf; + + let remaining = buf.len(); + let tx_type = TxType::decode(buf)?; + let this = Self::rlp_decode_inner(buf, tx_type)?; + + if buf.len() + header.payload_length != remaining { + return Err(alloy_rlp::Error::UnexpectedLength); + } + + Ok(this) + } +} + +impl TxReceipt for Receipt { + type Log = Log; + + fn status_or_post_state(&self) -> Eip658Value { + self.success.into() + } + + fn status(&self) -> bool { + self.success + } + + fn bloom(&self) -> Bloom { + alloy_primitives::logs_bloom(self.logs()) + } + + fn cumulative_gas_used(&self) -> u128 { + self.cumulative_gas_used as u128 + } + + fn logs(&self) -> &[Log] { + &self.logs + } +} + +impl Typed2718 for Receipt { + fn ty(&self) -> u8 { + self.tx_type as u8 + } +} + +impl InMemorySize for Receipt { + fn size(&self) -> usize { + self.tx_type.size() + + core::mem::size_of::() + + core::mem::size_of::() + + self.logs.capacity() * core::mem::size_of::() + } +} + +impl reth_primitives_traits::Receipt for Receipt {} + +/// TODO: Remove once is released. +mod tx_type_serde { + use alloy_primitives::{U64, U8}; + + use super::*; + + pub(crate) fn serialize(tx_type: &TxType, serializer: S) -> Result + where + S: serde::Serializer, + { + let value: U8 = (*tx_type).into(); + value.serialize(serializer) + } + + pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + U64::deserialize(deserializer)?.try_into().map_err(serde::de::Error::custom) + } +} diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index cbdb2296bf62..f94e84b17307 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -25,7 +25,7 @@ use revm::db::BundleState; /// # Warning /// /// A chain of blocks should not be empty. -#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Chain { /// All blocks in this chain. @@ -43,6 +43,16 @@ pub struct Chain { trie_updates: Option, } +impl Default for Chain { + fn default() -> Self { + Self { + blocks: Default::default(), + execution_outcome: Default::default(), + trie_updates: Default::default(), + } + } +} + impl Chain { /// Create new Chain from blocks and state. /// diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 830508dc92dc..43c78a5d9c4f 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -2,7 +2,7 @@ use crate::BlockExecutionOutput; use alloy_eips::eip7685::Requests; use alloy_primitives::{logs_bloom, Address, BlockNumber, Bloom, Log, B256, U256}; use reth_primitives::Receipts; -use reth_primitives_traits::{receipt::ReceiptExt, Account, Bytecode, Receipt, StorageEntry}; +use reth_primitives_traits::{Account, Bytecode, Receipt, StorageEntry}; use reth_trie::{HashedPostState, KeyHasher}; use revm::{ db::{states::BundleState, BundleAccount}, @@ -32,7 +32,7 @@ impl ChangedAccount { /// /// The `ExecutionOutcome` structure aggregates the state changes over an arbitrary number of /// blocks, capturing the resulting state, receipts, and requests following the execution. -#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ExecutionOutcome { /// Bundle state with reverts. @@ -54,6 +54,17 @@ pub struct ExecutionOutcome { pub requests: Vec, } +impl Default for ExecutionOutcome { + fn default() -> Self { + Self { + bundle: Default::default(), + receipts: Default::default(), + first_block: Default::default(), + requests: Default::default(), + } + } +} + /// Type used to initialize revms bundle state. pub type BundleStateInit = HashMap, Option, HashMap)>; @@ -343,18 +354,17 @@ impl> ExecutionOutcome { pub fn block_logs_bloom(&self, block_number: BlockNumber) -> Option { Some(logs_bloom(self.logs(block_number)?)) } +} - /// Returns the receipt root for all recorded receipts. +impl ExecutionOutcome { + /// Returns the ethereum receipt root for all recorded receipts. + /// /// Note: this function calculated Bloom filters for every receipt and created merkle trees /// of receipt. This is a expensive operation. - pub fn receipts_root_slow(&self, _block_number: BlockNumber) -> Option - where - T: ReceiptExt, - { - #[cfg(feature = "optimism")] - panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); - #[cfg(not(feature = "optimism"))] - self.receipts.root_slow(self.block_number_to_index(_block_number)?, T::receipts_root) + pub fn ethereum_receipts_root(&self, _block_number: BlockNumber) -> Option { + self.receipts.root_slow(self.block_number_to_index(_block_number)?, |receipts| { + reth_primitives::proofs::calculate_receipt_root_no_memo(receipts) + }) } } diff --git a/crates/evm/src/builder.rs b/crates/evm/src/builder.rs index 4b7511494a37..b955e41a255a 100644 --- a/crates/evm/src/builder.rs +++ b/crates/evm/src/builder.rs @@ -45,7 +45,7 @@ where let mut builder = EvmBuilder::default().with_db(self.db).with_external_context(self.external_context); if let Some(env) = self.env { - builder = builder.with_spec_id(env.clone().spec_id()); + builder = builder.with_spec_id(env.spec_id()); builder = builder.with_env(env.env); } @@ -61,7 +61,7 @@ where let mut builder = EvmBuilder::default().with_db(self.db).with_external_context(self.external_context); if let Some(env) = self.env { - builder = builder.with_spec_id(env.clone().spec_id()); + builder = builder.with_spec_id(env.spec_id()); builder = builder.with_env(env.env); } builder diff --git a/crates/exex/exex/src/backfill/stream.rs b/crates/exex/exex/src/backfill/stream.rs index d88ca87e7acc..0e27954eb41d 100644 --- a/crates/exex/exex/src/backfill/stream.rs +++ b/crates/exex/exex/src/backfill/stream.rs @@ -1,10 +1,5 @@ +use super::job::BackfillJobResult; use crate::{BackfillJob, SingleBlockBackfillJob}; -use std::{ - ops::RangeInclusive, - pin::Pin, - task::{ready, Context, Poll}, -}; - use alloy_primitives::BlockNumber; use futures::{ stream::{FuturesOrdered, Stream}, @@ -17,10 +12,13 @@ use reth_provider::{BlockReader, Chain, HeaderProvider, StateProviderFactory}; use reth_prune_types::PruneModes; use reth_stages_api::ExecutionStageThresholds; use reth_tracing::tracing::debug; +use std::{ + ops::RangeInclusive, + pin::Pin, + task::{ready, Context, Poll}, +}; use tokio::task::JoinHandle; -use super::job::BackfillJobResult; - /// The default parallelism for active tasks in [`StreamBackfillJob`]. pub(crate) const DEFAULT_PARALLELISM: usize = 4; /// The default batch size for active tasks in [`StreamBackfillJob`]. @@ -157,33 +155,44 @@ where fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); - // Spawn new tasks only if we are below the parallelism configured. - while this.tasks.len() < this.parallelism { - // Take the next `batch_size` blocks from the range and calculate the range bounds - let mut range = this.range.by_ref().take(this.batch_size); - let start = range.next(); - let range_bounds = start.zip(range.last().or(start)); - - // Create the range from the range bounds. If it is empty, we are done. - let Some(range) = range_bounds.map(|(first, last)| first..=last) else { - debug!(target: "exex::backfill", tasks = %this.tasks.len(), range = ?this.range, "No more block batches to backfill"); - break; - }; - - // Spawn a new task for that range - debug!(target: "exex::backfill", tasks = %this.tasks.len(), ?range, "Spawning new block batch backfill task"); - let job = Box::new(BackfillJob { - executor: this.executor.clone(), - provider: this.provider.clone(), - prune_modes: this.prune_modes.clone(), - thresholds: this.thresholds.clone(), - range, - stream_parallelism: this.parallelism, - }) as BackfillTaskIterator<_>; - this.push_back(job); + loop { + // Spawn new tasks only if we are below the parallelism configured. + while this.tasks.len() < this.parallelism { + // Take the next `batch_size` blocks from the range and calculate the range bounds + let mut range = this.range.by_ref().take(this.batch_size); + let start = range.next(); + let range_bounds = start.zip(range.last().or(start)); + + // Create the range from the range bounds. If it is empty, we are done. + let Some(range) = range_bounds.map(|(first, last)| first..=last) else { + debug!(target: "exex::backfill", tasks = %this.tasks.len(), range = ?this.range, "No more block batches to backfill"); + break; + }; + + // Spawn a new task for that range + debug!(target: "exex::backfill", tasks = %this.tasks.len(), ?range, "Spawning new block batch backfill task"); + let job = Box::new(BackfillJob { + executor: this.executor.clone(), + provider: this.provider.clone(), + prune_modes: this.prune_modes.clone(), + thresholds: this.thresholds.clone(), + range, + stream_parallelism: this.parallelism, + }) as BackfillTaskIterator<_>; + this.push_back(job); + } + + let res = ready!(this.poll_next_task(cx)); + + if res.is_some() { + return Poll::Ready(res); + } + + if this.range.is_empty() { + // only terminate the stream if there are no more blocks to process + return Poll::Ready(None); + } } - - this.poll_next_task(cx) } } @@ -310,10 +319,9 @@ mod tests { blocks_and_execution_outcome(provider_factory, chain_spec, key_pair)?; // Backfill the same range - let factory = - BackfillJobFactory::new(executor.clone(), blockchain_db.clone()).with_thresholds( - ExecutionStageThresholds { max_blocks: Some(2), ..Default::default() }, - ); + let factory = BackfillJobFactory::new(executor.clone(), blockchain_db.clone()) + .with_thresholds(ExecutionStageThresholds { max_blocks: Some(2), ..Default::default() }) + .with_stream_parallelism(1); let mut backfill_stream = factory.backfill(1..=2).into_stream(); let mut chain = backfill_stream.next().await.unwrap().unwrap(); chain.execution_outcome_mut().state_mut().reverts.sort(); diff --git a/crates/net/network/src/transactions/mod.rs b/crates/net/network/src/transactions/mod.rs index 83674c96c511..7e87736cc49b 100644 --- a/crates/net/network/src/transactions/mod.rs +++ b/crates/net/network/src/transactions/mod.rs @@ -50,7 +50,7 @@ use reth_network_p2p::{ use reth_network_peers::PeerId; use reth_network_types::ReputationChangeKind; use reth_primitives::{transaction::SignedTransactionIntoRecoveredExt, TransactionSigned}; -use reth_primitives_traits::{SignedTransaction, TxType}; +use reth_primitives_traits::SignedTransaction; use reth_tokio_util::EventStream; use reth_transaction_pool::{ error::{PoolError, PoolResult}, @@ -1641,7 +1641,7 @@ impl FullTransactionsBuilder { /// /// If the transaction is unsuitable for broadcast or would exceed the softlimit, it is appended /// to list of pooled transactions, (e.g. 4844 transactions). - /// See also [`TxType::is_broadcastable_in_full`]. + /// See also [`SignedTransaction::is_broadcastable_in_full`]. fn push(&mut self, transaction: &PropagateTransaction) { // Do not send full 4844 transaction hashes to peers. // @@ -1651,7 +1651,7 @@ impl FullTransactionsBuilder { // via `GetPooledTransactions`. // // From: - if !transaction.transaction.tx_type().is_broadcastable_in_full() { + if !transaction.transaction.is_broadcastable_in_full() { self.pooled.push(transaction); return } @@ -1717,7 +1717,7 @@ impl PooledTransactionsHashesBuilder { Self::Eth68(msg) => { msg.hashes.push(*tx.tx_hash()); msg.sizes.push(tx.size); - msg.types.push(tx.transaction.tx_type().into()); + msg.types.push(tx.transaction.ty()); } } } diff --git a/crates/node/core/src/args/payload_builder.rs b/crates/node/core/src/args/payload_builder.rs index cd7ba7dccfb5..2bce2e8e700c 100644 --- a/crates/node/core/src/args/payload_builder.rs +++ b/crates/node/core/src/args/payload_builder.rs @@ -1,4 +1,4 @@ -use crate::{cli::config::PayloadBuilderConfig, version::default_extradata}; +use crate::{cli::config::PayloadBuilderConfig, version::default_extra_data}; use alloy_consensus::constants::MAXIMUM_EXTRA_DATA_SIZE; use alloy_eips::{eip1559::ETHEREUM_BLOCK_GAS_LIMIT, merge::SLOT_DURATION}; use clap::{ @@ -13,7 +13,7 @@ use std::{borrow::Cow, ffi::OsStr, time::Duration}; #[command(next_help_heading = "Builder")] pub struct PayloadBuilderArgs { /// Block extra data set by the payload builder. - #[arg(long = "builder.extradata", value_parser = ExtradataValueParser::default(), default_value_t = default_extradata())] + #[arg(long = "builder.extradata", value_parser = ExtradataValueParser::default(), default_value_t = default_extra_data())] pub extradata: String, /// Target gas ceiling for built blocks. @@ -40,7 +40,7 @@ pub struct PayloadBuilderArgs { impl Default for PayloadBuilderArgs { fn default() -> Self { Self { - extradata: default_extradata(), + extradata: default_extra_data(), max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, interval: Duration::from_secs(1), deadline: SLOT_DURATION, @@ -130,7 +130,7 @@ mod tests { #[test] fn test_default_extradata() { - let extradata = default_extradata(); + let extradata = default_extra_data(); let args = CommandParser::::parse_from([ "reth", "--builder.extradata", diff --git a/crates/node/core/src/version.rs b/crates/node/core/src/version.rs index 4bf2dc56f39b..ae729e7f2f04 100644 --- a/crates/node/core/src/version.rs +++ b/crates/node/core/src/version.rs @@ -1,4 +1,5 @@ //! Version information for reth. +use alloy_primitives::Bytes; use alloy_rpc_types_engine::ClientCode; use reth_db::ClientVersion; @@ -114,7 +115,7 @@ pub(crate) const P2P_CLIENT_VERSION: &str = const_format::concatcp!( env!("VERGEN_CARGO_TARGET_TRIPLE") ); -/// The default extradata used for payload building. +/// The default extra data used for payload building. /// /// - The latest version from Cargo.toml /// - The OS identifier @@ -124,10 +125,16 @@ pub(crate) const P2P_CLIENT_VERSION: &str = const_format::concatcp!( /// ```text /// reth/v{major}.{minor}.{patch}/{OS} /// ``` -pub fn default_extradata() -> String { +pub fn default_extra_data() -> String { format!("reth/v{}/{}", env!("CARGO_PKG_VERSION"), std::env::consts::OS) } +/// The default extra data in bytes. +/// See [`default_extra_data`]. +pub fn default_extra_data_bytes() -> Bytes { + Bytes::from(default_extra_data().as_bytes().to_vec()) +} + /// The default client version accessing the database. pub fn default_client_version() -> ClientVersion { ClientVersion { @@ -143,7 +150,7 @@ mod tests { #[test] fn assert_extradata_less_32bytes() { - let extradata = default_extradata(); + let extradata = default_extra_data(); assert!(extradata.len() <= 32, "extradata must be less than 32 bytes: {extradata}") } } diff --git a/crates/optimism/chainspec/src/base.rs b/crates/optimism/chainspec/src/base.rs index f43457ead432..ab24ecf16c40 100644 --- a/crates/optimism/chainspec/src/base.rs +++ b/crates/optimism/chainspec/src/base.rs @@ -29,8 +29,6 @@ pub static BASE_MAINNET: LazyLock> = LazyLock::new(|| { ] .into(), ), - max_gas_limit: crate::constants::BASE_MAINNET_MAX_GAS_LIMIT, - prune_delete_limit: 10000, ..Default::default() }, } diff --git a/crates/optimism/chainspec/src/base_sepolia.rs b/crates/optimism/chainspec/src/base_sepolia.rs index adcb9e2bc1f4..4ebf4d9a81e7 100644 --- a/crates/optimism/chainspec/src/base_sepolia.rs +++ b/crates/optimism/chainspec/src/base_sepolia.rs @@ -29,7 +29,6 @@ pub static BASE_SEPOLIA: LazyLock> = LazyLock::new(|| { ] .into(), ), - max_gas_limit: crate::constants::BASE_SEPOLIA_MAX_GAS_LIMIT, prune_delete_limit: 10000, ..Default::default() }, diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 907599fe2a29..a1a08dd3b09a 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -317,10 +317,6 @@ impl EthChainSpec for OpChainSpec { self.inner.genesis() } - fn max_gas_limit(&self) -> u64 { - self.inner.max_gas_limit() - } - fn bootnodes(&self) -> Option> { self.inner.bootnodes() } @@ -1079,7 +1075,6 @@ mod tests { paris_block_and_final_difficulty: Some((0, U256::from(0))), hardforks, base_fee_params: BASE_SEPOLIA.inner.base_fee_params.clone(), - max_gas_limit: crate::constants::BASE_SEPOLIA_MAX_GAS_LIMIT, prune_delete_limit: 10000, ..Default::default() }, diff --git a/crates/optimism/chainspec/src/op.rs b/crates/optimism/chainspec/src/op.rs index fcbe7dee7dda..20a2ac60e220 100644 --- a/crates/optimism/chainspec/src/op.rs +++ b/crates/optimism/chainspec/src/op.rs @@ -1,16 +1,13 @@ //! Chain specification for the Optimism Mainnet network. +use crate::{LazyLock, OpChainSpec}; use alloc::{sync::Arc, vec}; - use alloy_chains::Chain; -use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; use reth_optimism_forks::OpHardfork; -use crate::{LazyLock, OpChainSpec}; - /// The Optimism Mainnet spec pub static OP_MAINNET: LazyLock> = LazyLock::new(|| { OpChainSpec { @@ -32,7 +29,6 @@ pub static OP_MAINNET: LazyLock> = LazyLock::new(|| { ] .into(), ), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: 10000, ..Default::default() }, diff --git a/crates/optimism/chainspec/src/op_sepolia.rs b/crates/optimism/chainspec/src/op_sepolia.rs index 35466cb21548..3a60d49ed120 100644 --- a/crates/optimism/chainspec/src/op_sepolia.rs +++ b/crates/optimism/chainspec/src/op_sepolia.rs @@ -1,16 +1,13 @@ //! Chain specification for the Optimism Sepolia testnet network. +use crate::{LazyLock, OpChainSpec}; use alloc::{sync::Arc, vec}; - use alloy_chains::{Chain, NamedChain}; -use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT; use alloy_primitives::{b256, U256}; use reth_chainspec::{once_cell_set, BaseFeeParams, BaseFeeParamsKind, ChainSpec}; use reth_ethereum_forks::EthereumHardfork; use reth_optimism_forks::OpHardfork; -use crate::{LazyLock, OpChainSpec}; - /// The OP Sepolia spec pub static OP_SEPOLIA: LazyLock> = LazyLock::new(|| { OpChainSpec { @@ -30,7 +27,6 @@ pub static OP_SEPOLIA: LazyLock> = LazyLock::new(|| { ] .into(), ), - max_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, prune_delete_limit: 10000, ..Default::default() }, diff --git a/crates/optimism/node/src/engine.rs b/crates/optimism/node/src/engine.rs index 1db50b72ee80..f85219279bd1 100644 --- a/crates/optimism/node/src/engine.rs +++ b/crates/optimism/node/src/engine.rs @@ -212,7 +212,6 @@ mod test { .paris_block_and_final_difficulty, hardforks, base_fee_params: BASE_SEPOLIA.inner.base_fee_params.clone(), - max_gas_limit: BASE_SEPOLIA.inner.max_gas_limit, prune_delete_limit: 10000, ..Default::default() }, diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 27778da8f429..790da228cef3 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -195,11 +195,7 @@ where let (initialized_cfg, initialized_block_env) = self.cfg_and_block_env(&attributes, &parent).map_err(PayloadBuilderError::other)?; - let config = PayloadConfig { - parent_header: Arc::new(parent), - attributes, - extra_data: Default::default(), - }; + let config = PayloadConfig { parent_header: Arc::new(parent), attributes }; let ctx = OpPayloadBuilderCtx { evm_config: self.evm_config.clone(), chain_spec: client.chain_spec(), @@ -621,7 +617,7 @@ impl OpPayloadBuilderCtx { /// Returns the extra data for the block. /// - /// After holocene this extracts the extradata from the paylpad + /// After holocene this extracts the extra data from the payload pub fn extra_data(&self) -> Result { if self.is_holocene_active() { self.attributes() @@ -632,7 +628,7 @@ impl OpPayloadBuilderCtx { ) .map_err(PayloadBuilderError::other) } else { - Ok(self.config.extra_data.clone()) + Ok(Default::default()) } } diff --git a/crates/optimism/primitives/src/transaction/signed.rs b/crates/optimism/primitives/src/transaction/signed.rs index ee72c65eb5ec..5acf9b8a8ca7 100644 --- a/crates/optimism/primitives/src/transaction/signed.rs +++ b/crates/optimism/primitives/src/transaction/signed.rs @@ -54,7 +54,7 @@ impl OpTransactionSigned { /// Calculates hash of given transaction and signature and returns new instance. pub fn new(transaction: OpTypedTransaction, signature: Signature) -> Self { let signed_tx = Self::new_unhashed(transaction, signature); - if !matches!(signed_tx.tx_type(), OpTxType::Deposit) { + if signed_tx.ty() != OpTxType::Deposit { signed_tx.hash.get_or_init(|| signed_tx.recalculate_hash()); } @@ -70,8 +70,6 @@ impl OpTransactionSigned { } impl SignedTransaction for OpTransactionSigned { - type Type = OpTxType; - fn tx_hash(&self) -> &TxHash { self.hash.get_or_init(|| self.recalculate_hash()) } @@ -246,9 +244,10 @@ impl alloy_rlp::Decodable for OpTransactionSigned { impl Encodable2718 for OpTransactionSigned { fn type_flag(&self) -> Option { - match self.tx_type() { - op_alloy_consensus::OpTxType::Legacy => None, - tx_type => Some(tx_type as u8), + if Typed2718::is_legacy(self) { + None + } else { + Some(self.ty()) } } diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 8e9c06865d03..189b8a8c2f82 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -163,11 +163,7 @@ where .ok_or_else(|| PayloadBuilderError::MissingParentHeader(attributes.parent()))? }; - let config = PayloadConfig::new( - Arc::new(parent_header.clone()), - self.config.extradata.clone(), - attributes, - ); + let config = PayloadConfig::new(Arc::new(parent_header.clone()), attributes); let until = self.job_deadline(config.attributes.timestamp()); let deadline = Box::pin(tokio::time::sleep_until(until)); @@ -713,30 +709,17 @@ impl Drop for Cancelled { pub struct PayloadConfig { /// The parent header. pub parent_header: Arc, - /// Block extra data. - pub extra_data: Bytes, /// Requested attributes for the payload. pub attributes: Attributes, } -impl PayloadConfig { - /// Returns an owned instance of the [`PayloadConfig`]'s `extra_data` bytes. - pub fn extra_data(&self) -> Bytes { - self.extra_data.clone() - } -} - impl PayloadConfig where Attributes: PayloadBuilderAttributes, { /// Create new payload config. - pub const fn new( - parent_header: Arc, - extra_data: Bytes, - attributes: Attributes, - ) -> Self { - Self { parent_header, extra_data, attributes } + pub const fn new(parent_header: Arc, attributes: Attributes) -> Self { + Self { parent_header, attributes } } /// Returns the payload id. diff --git a/crates/payload/basic/src/stack.rs b/crates/payload/basic/src/stack.rs index 45a3f3b42448..77314d443912 100644 --- a/crates/payload/basic/src/stack.rs +++ b/crates/payload/basic/src/stack.rs @@ -204,7 +204,6 @@ where cached_reads: args.cached_reads.clone(), config: PayloadConfig { parent_header: args.config.parent_header.clone(), - extra_data: args.config.extra_data.clone(), attributes: left_attr.clone(), }, cancel: args.cancel.clone(), @@ -226,7 +225,6 @@ where cached_reads: args.cached_reads.clone(), config: PayloadConfig { parent_header: args.config.parent_header.clone(), - extra_data: args.config.extra_data.clone(), attributes: right_attr.clone(), }, cancel: args.cancel.clone(), @@ -252,16 +250,14 @@ where match config.attributes { Either::Left(left_attr) => { let left_config = PayloadConfig { - attributes: left_attr, parent_header: config.parent_header.clone(), - extra_data: config.extra_data.clone(), + attributes: left_attr, }; self.left.build_empty_payload(client, left_config).map(Either::Left) } Either::Right(right_attr) => { let right_config = PayloadConfig { parent_header: config.parent_header.clone(), - extra_data: config.extra_data.clone(), attributes: right_attr, }; self.right.build_empty_payload(client, right_config).map(Either::Right) diff --git a/crates/payload/validator/src/lib.rs b/crates/payload/validator/src/lib.rs index 0a872a68ddfa..57772de25879 100644 --- a/crates/payload/validator/src/lib.rs +++ b/crates/payload/validator/src/lib.rs @@ -144,7 +144,7 @@ impl ExecutionPayloadValidator { return Err(PayloadError::PostCancunWithoutCancunFields) } } else { - if sealed_block.has_blob_transactions() { + if sealed_block.has_eip4844_transactions() { // cancun not active but blob transactions present return Err(PayloadError::PreCancunBlockWithBlobTransactions) } diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 20f1cb9c159a..eecf3ee79dee 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -1,8 +1,7 @@ //! Block body abstraction. use crate::{ - BlockHeader, FullSignedTx, InMemorySize, MaybeArbitrary, MaybeSerde, MaybeSerdeBincodeCompat, - SignedTransaction, + BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, MaybeSerdeBincodeCompat, SignedTransaction, }; use alloc::{fmt, vec::Vec}; use alloy_consensus::Transaction; @@ -28,7 +27,6 @@ pub trait BlockBody: + alloy_rlp::Decodable + InMemorySize + MaybeSerde - + MaybeArbitrary + MaybeSerdeBincodeCompat + 'static { diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index e1406df49477..88f55bfa19f8 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -4,7 +4,7 @@ use core::{fmt, hash::Hash}; use alloy_primitives::Sealable; -use crate::{InMemorySize, MaybeArbitrary, MaybeCompact, MaybeSerde, MaybeSerdeBincodeCompat}; +use crate::{InMemorySize, MaybeCompact, MaybeSerde, MaybeSerdeBincodeCompat}; /// Helper trait that unifies all behaviour required by block header to support full node /// operations. @@ -29,7 +29,6 @@ pub trait BlockHeader: + Sealable + InMemorySize + MaybeSerde - + MaybeArbitrary + MaybeSerdeBincodeCompat + AsRef + 'static diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 1994075b9227..7354cba912c4 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -6,10 +6,7 @@ pub mod header; use alloc::fmt; use alloy_rlp::{Decodable, Encodable}; -use crate::{ - BlockBody, BlockHeader, FullBlockBody, FullBlockHeader, InMemorySize, MaybeArbitrary, - MaybeSerde, -}; +use crate::{BlockBody, BlockHeader, FullBlockBody, FullBlockHeader, InMemorySize, MaybeSerde}; /// Helper trait that unifies all behaviour required by block to support full node operations. pub trait FullBlock: @@ -42,7 +39,6 @@ pub trait Block: + Eq + InMemorySize + MaybeSerde - + MaybeArbitrary + Encodable + Decodable { diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index 04d02be0b7dd..b620bc535f90 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -27,7 +27,6 @@ pub mod transaction; pub use transaction::{ execute::FillTxEnv, signed::{FullSignedTx, SignedTransaction}, - tx_type::{FullTxType, TxType}, FullTransaction, Transaction, }; @@ -75,18 +74,6 @@ pub use size::InMemorySize; pub mod node; pub use node::{BodyTy, FullNodePrimitives, HeaderTy, NodePrimitives, ReceiptTy}; -/// Helper trait that requires arbitrary implementation if the feature is enabled. -#[cfg(any(feature = "test-utils", feature = "arbitrary"))] -pub trait MaybeArbitrary: for<'a> arbitrary::Arbitrary<'a> {} -/// Helper trait that requires arbitrary implementation if the feature is enabled. -#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))] -pub trait MaybeArbitrary {} - -#[cfg(any(feature = "test-utils", feature = "arbitrary"))] -impl MaybeArbitrary for T where T: for<'a> arbitrary::Arbitrary<'a> {} -#[cfg(not(any(feature = "test-utils", feature = "arbitrary")))] -impl MaybeArbitrary for T {} - /// Helper trait that requires de-/serialize implementation since `serde` feature is enabled. #[cfg(feature = "serde")] pub trait MaybeSerde: serde::Serialize + for<'de> serde::Deserialize<'de> {} diff --git a/crates/primitives-traits/src/node.rs b/crates/primitives-traits/src/node.rs index 5b3691d2fdf7..0d46141da0c6 100644 --- a/crates/primitives-traits/src/node.rs +++ b/crates/primitives-traits/src/node.rs @@ -1,6 +1,6 @@ use crate::{ Block, BlockBody, BlockHeader, FullBlock, FullBlockBody, FullBlockHeader, FullReceipt, - FullSignedTx, FullTxType, Receipt, SignedTransaction, TxType, + FullSignedTx, Receipt, SignedTransaction, }; use core::fmt; @@ -15,9 +15,7 @@ pub trait NodePrimitives: /// Block body primitive. type BlockBody: BlockBody; /// Signed version of the transaction type. - type SignedTx: SignedTransaction + 'static; - /// Transaction envelope type ID. - type TxType: TxType + 'static; + type SignedTx: SignedTransaction + 'static; /// A receipt. type Receipt: Receipt; } @@ -29,7 +27,6 @@ where BlockHeader: FullBlockHeader, BlockBody: FullBlockBody, SignedTx: FullSignedTx, - TxType: FullTxType, Receipt: FullReceipt, > + Send + Sync @@ -49,7 +46,6 @@ impl FullNodePrimitives for T where BlockHeader: FullBlockHeader, BlockBody: FullBlockBody, SignedTx: FullSignedTx, - TxType: FullTxType, Receipt: FullReceipt, > + Send + Sync diff --git a/crates/primitives-traits/src/receipt.rs b/crates/primitives-traits/src/receipt.rs index 1b5d2b698c8b..48ee1f21fb58 100644 --- a/crates/primitives-traits/src/receipt.rs +++ b/crates/primitives-traits/src/receipt.rs @@ -1,19 +1,16 @@ //! Receipt abstraction +use crate::{InMemorySize, MaybeCompact, MaybeSerde}; use alloc::vec::Vec; -use core::fmt; - use alloy_consensus::{ Eip2718EncodableReceipt, RlpDecodableReceipt, RlpEncodableReceipt, TxReceipt, Typed2718, }; -use alloy_primitives::B256; - -use crate::{InMemorySize, MaybeArbitrary, MaybeCompact, MaybeSerde}; +use core::fmt; /// Helper trait that unifies all behaviour required by receipt to support full node operations. pub trait FullReceipt: Receipt + MaybeCompact {} -impl FullReceipt for T where T: ReceiptExt + MaybeCompact {} +impl FullReceipt for T where T: Receipt + MaybeCompact {} /// Abstraction of a receipt. #[auto_impl::auto_impl(&, Arc)] @@ -22,7 +19,6 @@ pub trait Receipt: + Sync + Unpin + Clone - + Default + fmt::Debug + TxReceipt + RlpEncodableReceipt @@ -31,16 +27,9 @@ pub trait Receipt: + Typed2718 + MaybeSerde + InMemorySize - + MaybeArbitrary { } -/// Extension if [`Receipt`] used in block execution. -pub trait ReceiptExt: Receipt { - /// Calculates the receipts root of the given receipts. - fn receipts_root(receipts: &[&Self]) -> B256; -} - /// Retrieves gas spent by transactions as a vector of tuples (transaction index, gas used). pub fn gas_spent_by_transactions(receipts: I) -> Vec<(u64, u64)> where diff --git a/crates/primitives/src/transaction/error.rs b/crates/primitives-traits/src/transaction/error.rs similarity index 91% rename from crates/primitives/src/transaction/error.rs rename to crates/primitives-traits/src/transaction/error.rs index 78f6cf5e5fd3..15d1d44ac594 100644 --- a/crates/primitives/src/transaction/error.rs +++ b/crates/primitives-traits/src/transaction/error.rs @@ -1,8 +1,9 @@ +//! Various error variants that can happen when working with transactions. + use crate::GotExpectedBoxed; use alloy_primitives::U256; -/// Represents error variants that can happen when trying to validate a -/// [Transaction](crate::Transaction) +/// Represents error variants that can happen when trying to validate a transaction. #[derive(Debug, Clone, Eq, PartialEq, derive_more::Display)] pub enum InvalidTransactionError { /// The sender does not have enough funds to cover the transaction fees @@ -64,19 +65,17 @@ pub enum InvalidTransactionError { impl core::error::Error for InvalidTransactionError {} -/// Represents error variants that can happen when trying to convert a transaction to -/// [`PooledTransactionsElement`](crate::PooledTransactionsElement) +/// Represents error variants that can happen when trying to convert a transaction to pooled +/// transaction. #[derive(Debug, Clone, Eq, PartialEq, derive_more::Display, derive_more::Error)] pub enum TransactionConversionError { - /// This error variant is used when a transaction cannot be converted into a - /// [`PooledTransactionsElement`](crate::PooledTransactionsElement) because it is not supported - /// for P2P network. + /// This error variant is used when a transaction cannot be converted into a pooled transaction + /// because it is not supported for P2P network. #[display("Transaction is not supported for p2p")] UnsupportedForP2P, } -/// Represents error variants than can happen when trying to convert a -/// [`RecoveredTx`](crate::RecoveredTx) transaction. +/// Represents error variants than can happen when trying to convert a recovered transaction. #[derive(Debug, Clone, Eq, PartialEq, derive_more::Display)] pub enum TryFromRecoveredTransactionError { /// Thrown if the transaction type is unsupported. diff --git a/crates/primitives-traits/src/transaction/mod.rs b/crates/primitives-traits/src/transaction/mod.rs index b67e51024bf6..874fd494f13e 100644 --- a/crates/primitives-traits/src/transaction/mod.rs +++ b/crates/primitives-traits/src/transaction/mod.rs @@ -2,9 +2,10 @@ pub mod execute; pub mod signed; -pub mod tx_type; -use crate::{InMemorySize, MaybeArbitrary, MaybeCompact, MaybeSerde}; +pub mod error; + +use crate::{InMemorySize, MaybeCompact, MaybeSerde}; use core::{fmt, hash::Hash}; /// Helper trait that unifies all behaviour required by transaction to support full node operations. @@ -25,7 +26,6 @@ pub trait Transaction: + alloy_consensus::Transaction + InMemorySize + MaybeSerde - + MaybeArbitrary { } @@ -41,6 +41,5 @@ impl Transaction for T where + alloy_consensus::Transaction + InMemorySize + MaybeSerde - + MaybeArbitrary { } diff --git a/crates/primitives-traits/src/transaction/signed.rs b/crates/primitives-traits/src/transaction/signed.rs index 5e0a91b4da2b..4bc9a8418796 100644 --- a/crates/primitives-traits/src/transaction/signed.rs +++ b/crates/primitives-traits/src/transaction/signed.rs @@ -1,6 +1,6 @@ //! API of a signed transaction. -use crate::{FillTxEnv, InMemorySize, MaybeArbitrary, MaybeCompact, MaybeSerde, TxType}; +use crate::{FillTxEnv, InMemorySize, MaybeCompact, MaybeSerde}; use alloc::{fmt, vec::Vec}; use alloy_eips::eip2718::{Decodable2718, Encodable2718}; use alloy_primitives::{keccak256, Address, PrimitiveSignature, TxHash, B256}; @@ -28,23 +28,24 @@ pub trait SignedTransaction: + Decodable2718 + alloy_consensus::Transaction + MaybeSerde - + MaybeArbitrary + InMemorySize { - /// Transaction envelope type ID. - type Type: TxType; - - /// Returns the transaction type. - fn tx_type(&self) -> Self::Type { - Self::Type::try_from(self.ty()).expect("should decode tx type id") - } - /// Returns reference to transaction hash. fn tx_hash(&self) -> &TxHash; /// Returns reference to signature. fn signature(&self) -> &PrimitiveSignature; + /// Returns whether this transaction type can be __broadcasted__ as full transaction over the + /// network. + /// + /// Some transactions are not broadcastable as objects and only allowed to be broadcasted as + /// hashes, e.g. because they missing context (e.g. blob sidecar). + fn is_broadcastable_in_full(&self) -> bool { + // EIP-4844 transactions are not broadcastable in full, only hashes are allowed. + !self.is_eip4844() + } + /// Recover signer from signature and hash. /// /// Returns `None` if the transaction's signature is invalid following [EIP-2](https://eips.ethereum.org/EIPS/eip-2), see also `reth_primitives::transaction::recover_signer`. diff --git a/crates/primitives-traits/src/transaction/tx_type.rs b/crates/primitives-traits/src/transaction/tx_type.rs deleted file mode 100644 index c60cd9cb3af4..000000000000 --- a/crates/primitives-traits/src/transaction/tx_type.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! Abstraction of transaction envelope type ID. - -use crate::{InMemorySize, MaybeArbitrary, MaybeCompact}; -use alloy_consensus::Typed2718; -use alloy_primitives::{U64, U8}; -use core::fmt; - -/// Helper trait that unifies all behaviour required by transaction type ID to support full node -/// operations. -pub trait FullTxType: TxType + MaybeCompact {} - -impl FullTxType for T where T: TxType + MaybeCompact {} - -/// Trait representing the behavior of a transaction type. -pub trait TxType: - Send - + Sync - + Unpin - + Clone - + Copy - + Default - + fmt::Debug - + fmt::Display - + PartialEq - + Eq - + PartialEq - + Into - + Into - + TryFrom - + TryFrom - + TryFrom - + alloy_rlp::Encodable - + alloy_rlp::Decodable - + Typed2718 - + InMemorySize - + MaybeArbitrary -{ - /// Returns whether this transaction type can be __broadcasted__ as full transaction over the - /// network. - /// - /// Some transactions are not broadcastable as objects and only allowed to be broadcasted as - /// hashes, e.g. because they missing context (e.g. blob sidecar). - fn is_broadcastable_in_full(&self) -> bool { - // EIP-4844 transactions are not broadcastable in full, only hashes are allowed. - !self.is_eip4844() - } -} - -#[cfg(feature = "op")] -impl TxType for op_alloy_consensus::OpTxType {} - -impl TxType for alloy_consensus::TxType {} diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 767ba30286c7..777bb06e6f32 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -265,8 +265,8 @@ impl SealedBlock { impl SealedBlock { /// Returns whether or not the block contains any blob transactions. #[inline] - pub fn has_blob_transactions(&self) -> bool { - self.body.has_blob_transactions() + pub fn has_eip4844_transactions(&self) -> bool { + self.body.has_eip4844_transactions() } /// Returns whether or not the block contains any eip-7702 transactions. @@ -583,7 +583,7 @@ impl BlockBody { /// Returns an iterator over all blob versioned hashes from the block body. #[inline] pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { - self.blob_transactions_iter() + self.eip4844_transactions_iter() .filter_map(|tx| tx.as_eip4844().map(|blob_tx| &blob_tx.blob_versioned_hashes)) .flatten() } @@ -611,7 +611,7 @@ impl BlockBody { impl BlockBody { /// Returns whether or not the block body contains any blob transactions. #[inline] - pub fn has_blob_transactions(&self) -> bool { + pub fn has_eip4844_transactions(&self) -> bool { self.transactions.iter().any(|tx| tx.is_eip4844()) } @@ -623,15 +623,9 @@ impl BlockBody { /// Returns an iterator over all blob transactions of the block #[inline] - pub fn blob_transactions_iter(&self) -> impl Iterator + '_ { + pub fn eip4844_transactions_iter(&self) -> impl Iterator + '_ { self.transactions.iter().filter(|tx| tx.is_eip4844()) } - - /// Returns only the blob transactions, if any, from the block body. - #[inline] - pub fn blob_transactions(&self) -> Vec<&T> { - self.blob_transactions_iter().collect() - } } impl InMemorySize for BlockBody { diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 18fe1498b8a8..ab796d734abd 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -86,6 +86,5 @@ impl reth_primitives_traits::NodePrimitives for EthPrimitives { type BlockHeader = alloy_consensus::Header; type BlockBody = crate::BlockBody; type SignedTx = crate::TransactionSigned; - type TxType = crate::TxType; type Receipt = crate::Receipt; } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 62c664e22a46..037b31e023c4 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -9,7 +9,6 @@ use alloy_primitives::{Bloom, Log, B256}; use alloy_rlp::{Decodable, Encodable, Header, RlpDecodable, RlpEncodable}; use bytes::BufMut; use derive_more::{DerefMut, From, IntoIterator}; -use reth_primitives_traits::receipt::ReceiptExt; use serde::{Deserialize, Serialize}; use crate::TxType; @@ -25,6 +24,10 @@ pub use reth_primitives_traits::receipt::gas_spent_by_transactions; )] #[cfg_attr(any(test, feature = "reth-codec"), derive(reth_codecs::CompactZstd))] #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests)] +#[cfg_attr(any(test, feature = "reth-codec"), reth_zstd( + compressor = reth_zstd_compressors::RECEIPT_COMPRESSOR, + decompressor = reth_zstd_compressors::RECEIPT_DECOMPRESSOR +))] #[rlp(trailing)] pub struct Receipt { /// Receipt type. @@ -267,15 +270,6 @@ impl Typed2718 for Receipt { impl reth_primitives_traits::Receipt for Receipt {} -impl ReceiptExt for Receipt { - fn receipts_root(_receipts: &[&Self]) -> B256 { - #[cfg(feature = "optimism")] - panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); - #[cfg(not(feature = "optimism"))] - crate::proofs::calculate_receipt_root_no_memo(_receipts) - } -} - impl InMemorySize for Receipt { /// Calculates a heuristic for the in-memory size of the [Receipt]. #[inline] diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 4732ba8024c3..4431d1f9cdea 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -32,12 +32,14 @@ use signature::decode_with_eip155_chain_id; use std::sync::{LazyLock, OnceLock}; pub use compat::FillTxEnv; -pub use error::{ - InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, -}; pub use meta::TransactionMeta; pub use pooled::{PooledTransactionsElement, PooledTransactionsElementEcRecovered}; -pub use reth_primitives_traits::WithEncoded; +pub use reth_primitives_traits::{ + transaction::error::{ + InvalidTransactionError, TransactionConversionError, TryFromRecoveredTransactionError, + }, + WithEncoded, +}; pub use sidecar::BlobTransaction; pub use signature::{recover_signer, recover_signer_unchecked}; pub use tx_type::TxType; @@ -49,7 +51,6 @@ pub mod util; pub(crate) mod access_list; mod compat; -mod error; mod meta; mod pooled; mod sidecar; @@ -1030,8 +1031,6 @@ impl TransactionSigned { } impl SignedTransaction for TransactionSigned { - type Type = TxType; - fn tx_hash(&self) -> &TxHash { self.hash.get_or_init(|| self.recalculate_hash()) } @@ -1921,13 +1920,12 @@ mod tests { // Test vector from https://sepolia.etherscan.io/tx/0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 // Blobscan: https://sepolia.blobscan.com/tx/0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 fn test_decode_recover_sepolia_4844_tx() { - use crate::TxType; use alloy_primitives::{address, b256}; // https://sepolia.etherscan.io/getRawTx?tx=0x9a22ccb0029bc8b0ddd073be1a1d923b7ae2b2ea52100bae0db4424f9107e9c0 let raw_tx = alloy_primitives::hex::decode("0x03f9011d83aa36a7820fa28477359400852e90edd0008252089411e9ca82a3a762b4b5bd264d4173a242e7a770648080c08504a817c800f8a5a0012ec3d6f66766bedb002a190126b3549fce0047de0d4c25cffce0dc1c57921aa00152d8e24762ff22b1cfd9f8c0683786a7ca63ba49973818b3d1e9512cd2cec4a0013b98c6c83e066d5b14af2b85199e3d4fc7d1e778dd53130d180f5077e2d1c7a001148b495d6e859114e670ca54fb6e2657f0cbae5b08063605093a4b3dc9f8f1a0011ac212f13c5dff2b2c6b600a79635103d6f580a4221079951181b25c7e654901a0c8de4cced43169f9aa3d36506363b2d2c44f6c49fc1fd91ea114c86f3757077ea01e11fdd0d1934eda0492606ee0bb80a7bf8f35cc5f86ec60fe5031ba48bfd544").unwrap(); let decoded = TransactionSigned::decode_2718(&mut raw_tx.as_slice()).unwrap(); - assert_eq!(decoded.tx_type(), TxType::Eip4844); + assert!(decoded.is_eip4844()); let from = decoded.recover_signer(); assert_eq!(from, Some(address!("A83C816D4f9b2783761a22BA6FADB0eB0606D7B2"))); diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index b4790d028290..ffcffef4f6e6 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -2,10 +2,9 @@ //! response to `GetPooledTransactions`. use super::{ - error::TransactionConversionError, recover_signer_unchecked, signature::recover_signer, - TxEip7702, + recover_signer_unchecked, signature::recover_signer, TransactionConversionError, TxEip7702, }; -use crate::{BlobTransaction, RecoveredTx, Transaction, TransactionSigned, TxType}; +use crate::{BlobTransaction, RecoveredTx, Transaction, TransactionSigned}; use alloc::vec::Vec; use alloy_consensus::{ constants::EIP4844_TX_TYPE_ID, @@ -568,8 +567,6 @@ impl alloy_consensus::Transaction for PooledTransactionsElement { } impl SignedTransaction for PooledTransactionsElement { - type Type = TxType; - fn tx_hash(&self) -> &TxHash { match self { Self::Legacy(tx) => tx.hash(), diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index d0a4786dcf16..83f954387692 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -97,8 +97,6 @@ impl Typed2718 for TxType { } } -impl reth_primitives_traits::TxType for TxType {} - impl InMemorySize for TxType { /// Calculates a heuristic for the in-memory size of the [`TxType`]. #[inline] @@ -259,16 +257,8 @@ mod tests { use super::*; use alloy_primitives::hex; use reth_codecs::Compact; - use reth_primitives_traits::TxType as _; use rstest::rstest; - #[test] - fn is_broadcastable() { - assert!(TxType::Legacy.is_broadcastable_in_full()); - assert!(TxType::Eip1559.is_broadcastable_in_full()); - assert!(!TxType::Eip4844.is_broadcastable_in_full()); - } - #[rstest] #[case(U64::from(LEGACY_TX_TYPE_ID), Ok(TxType::Legacy))] #[case(U64::from(EIP2930_TX_TYPE_ID), Ok(TxType::Eip2930))] diff --git a/crates/prune/types/Cargo.toml b/crates/prune/types/Cargo.toml index 5446d6f76ff5..75093511310d 100644 --- a/crates/prune/types/Cargo.toml +++ b/crates/prune/types/Cargo.toml @@ -15,7 +15,6 @@ workspace = true reth-codecs.workspace = true alloy-primitives.workspace = true -bytes.workspace = true derive_more.workspace = true modular-bitfield.workspace = true serde.workspace = true diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs index f9d62855be12..2951aad0acfa 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -5,8 +5,8 @@ use crate::{AsEthApiError, FromEthApiError, IntoEthApiError}; use alloy_primitives::U256; use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId}; use futures::Future; -use reth_chainspec::{EthChainSpec, MIN_TRANSACTION_GAS}; -use reth_provider::{ChainSpecProvider, StateProvider}; +use reth_chainspec::MIN_TRANSACTION_GAS; +use reth_provider::StateProvider; use reth_revm::{ database::StateProviderDatabase, db::CacheDB, @@ -116,9 +116,7 @@ pub trait EstimateCall: Call { } // We can now normalize the highest gas limit to a u64 - let mut highest_gas_limit: u64 = highest_gas_limit - .try_into() - .unwrap_or_else(|_| self.provider().chain_spec().max_gas_limit()); + let mut highest_gas_limit = highest_gas_limit.saturating_to::(); // If the provided gas limit is less than computed cap, use that env.tx.gas_limit = env.tx.gas_limit.min(highest_gas_limit); diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index c6e0e0c5939c..af05eeaef041 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -16,7 +16,7 @@ use reth_evm::{ ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes, }; use reth_primitives::{BlockExt, InvalidTransactionError, SealedBlockWithSenders}; -use reth_primitives_traits::receipt::ReceiptExt; +use reth_primitives_traits::Receipt; use reth_provider::{ BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderBlock, ProviderError, ProviderHeader, ProviderReceipt, ProviderTx, ReceiptProvider, StateProviderFactory, @@ -47,7 +47,7 @@ pub trait LoadPendingBlock: HeaderResponse = alloy_rpc_types_eth::Header>, >, > + RpcNodeCore< - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt + EvmEnvProvider> + ChainSpecProvider + StateProviderFactory, diff --git a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs index 253aac91d8b9..cb35d7f5df58 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/transaction.rs @@ -17,10 +17,7 @@ use reth_provider::{ BlockNumReader, BlockReaderIdExt, ProviderBlock, ProviderReceipt, ProviderTx, ReceiptProvider, TransactionsProvider, }; -use reth_rpc_eth_types::{ - utils::{binary_search, recover_raw_transaction}, - EthApiError, SignError, TransactionSource, -}; +use reth_rpc_eth_types::{utils::binary_search, EthApiError, SignError, TransactionSource}; use reth_rpc_types_compat::transaction::{from_recovered, from_recovered_with_block_context}; use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; use std::sync::Arc; @@ -61,6 +58,14 @@ pub trait EthTransactions: LoadTransaction { #[expect(clippy::type_complexity)] fn signers(&self) -> &parking_lot::RwLock>>>>; + /// Decodes and recovers the transaction and submits it to the pool. + /// + /// Returns the hash of the transaction. + fn send_raw_transaction( + &self, + tx: Bytes, + ) -> impl Future> + Send; + /// Returns the transaction by hash. /// /// Checks the pool and state. @@ -333,29 +338,6 @@ pub trait EthTransactions: LoadTransaction { } } - /// Decodes and recovers the transaction and submits it to the pool. - /// - /// Returns the hash of the transaction. - fn send_raw_transaction( - &self, - tx: Bytes, - ) -> impl Future> + Send { - async move { - let recovered = recover_raw_transaction(&tx)?; - let pool_transaction = - ::Transaction::from_pooled(recovered); - - // submit the transaction to the pool with a `Local` origin - let hash = self - .pool() - .add_transaction(TransactionOrigin::Local, pool_transaction) - .await - .map_err(Self::Error::from_eth_err)?; - - Ok(hash) - } - } - /// Signs transaction with a matching signer, if any and submits the transaction to the pool. /// Returns the hash of the signed transaction. fn send_transaction( diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index a6ea5c4b7881..f18232b8952e 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -204,7 +204,7 @@ where calls.push(call); } - let block = BlockWithSenders { block, senders }; + let block = BlockWithSenders::new_unchecked(block, senders); let txs_kind = if full_transactions { BlockTransactionsKind::Full } else { BlockTransactionsKind::Hashes }; diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index 1fe08d1c57f8..8341742e4d17 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_network::Ethereum; -use alloy_primitives::U256; +use alloy_primitives::{Bytes, U256}; use derive_more::Deref; use reth_primitives::NodePrimitives; use reth_provider::{ @@ -26,10 +26,12 @@ use reth_tasks::{ pool::{BlockingTaskGuard, BlockingTaskPool}, TaskSpawner, TokioTaskExecutor, }; -use tokio::sync::Mutex; +use tokio::sync::{broadcast, Mutex}; use crate::eth::EthTxBuilder; +const DEFAULT_BROADCAST_CAPACITY: usize = 2000; + /// `Eth` API implementation. /// /// This type provides the functionality for handling `eth_` related requests. @@ -270,6 +272,9 @@ pub struct EthApiInner { /// Guard for getproof calls blocking_task_guard: BlockingTaskGuard, + + /// Transaction broadcast channel + raw_tx_sender: broadcast::Sender, } impl EthApiInner @@ -304,6 +309,8 @@ where .unwrap_or_default(), ); + let (raw_tx_sender, _) = broadcast::channel(DEFAULT_BROADCAST_CAPACITY); + Self { provider, pool, @@ -321,6 +328,7 @@ where fee_history_cache, evm_config, blocking_task_guard: BlockingTaskGuard::new(proof_permits), + raw_tx_sender, } } } @@ -428,16 +436,29 @@ where pub const fn blocking_task_guard(&self) -> &BlockingTaskGuard { &self.blocking_task_guard } + + /// Returns [`broadcast::Receiver`] of new raw transactions + #[inline] + pub fn subscribe_to_raw_transactions(&self) -> broadcast::Receiver { + self.raw_tx_sender.subscribe() + } + + /// Broadcasts raw transaction if there are active subscribers. + #[inline] + pub fn broadcast_raw_transaction(&self, raw_tx: Bytes) { + let _ = self.raw_tx_sender.send(raw_tx); + } } #[cfg(test)] mod tests { + use crate::EthApi; use alloy_consensus::Header; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{PrimitiveSignature as Signature, B256, U64}; use alloy_rpc_types::FeeHistory; use jsonrpsee_types::error::INVALID_PARAMS_CODE; - use reth_chainspec::{BaseFeeParams, ChainSpec, EthChainSpec}; + use reth_chainspec::{BaseFeeParams, ChainSpec}; use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; use reth_primitives::{Block, BlockBody, TransactionSigned}; @@ -447,7 +468,7 @@ mod tests { }; use reth_rpc_eth_api::EthApiServer; use reth_rpc_eth_types::{ - EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, GasPriceOracle, + EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, GasCap, GasPriceOracle, }; use reth_rpc_server_types::constants::{ DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_SIMULATE_BLOCKS, DEFAULT_PROOF_PERMITS, @@ -456,8 +477,6 @@ mod tests { use reth_testing_utils::{generators, generators::Rng}; use reth_transaction_pool::test_utils::{testing_pool, TestPool}; - use crate::EthApi; - fn build_test_eth_api< P: BlockReaderIdExt< Block = reth_primitives::Block, @@ -477,14 +496,13 @@ mod tests { let cache = EthStateCache::spawn(provider.clone(), Default::default()); let fee_history_cache = FeeHistoryCache::new(FeeHistoryCacheConfig::default()); - let gas_cap = provider.chain_spec().max_gas_limit(); EthApi::new( provider.clone(), testing_pool(), NoopNetwork::default(), cache.clone(), GasPriceOracle::new(provider, Default::default(), cache), - gas_cap, + GasCap::default(), DEFAULT_MAX_SIMULATE_BLOCKS, DEFAULT_ETH_PROOF_WINDOW, BlockingTaskPool::build().expect("failed to build tracing pool"), diff --git a/crates/rpc/rpc/src/eth/helpers/transaction.rs b/crates/rpc/rpc/src/eth/helpers/transaction.rs index 04ed812fab2f..3fcdfb3f0681 100644 --- a/crates/rpc/rpc/src/eth/helpers/transaction.rs +++ b/crates/rpc/rpc/src/eth/helpers/transaction.rs @@ -1,13 +1,14 @@ //! Contains RPC handler implementations specific to transactions +use crate::EthApi; +use alloy_primitives::{Bytes, B256}; use reth_provider::{BlockReader, BlockReaderIdExt, ProviderTx, TransactionsProvider}; use reth_rpc_eth_api::{ helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking}, - FullEthApiTypes, RpcNodeCoreExt, + FromEthApiError, FullEthApiTypes, RpcNodeCore, RpcNodeCoreExt, }; -use reth_transaction_pool::TransactionPool; - -use crate::EthApi; +use reth_rpc_eth_types::utils::recover_raw_transaction; +use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool}; impl EthTransactions for EthApi @@ -19,6 +20,27 @@ where fn signers(&self) -> &parking_lot::RwLock>>>> { self.inner.signers() } + + /// Decodes and recovers the transaction and submits it to the pool. + /// + /// Returns the hash of the transaction. + async fn send_raw_transaction(&self, tx: Bytes) -> Result { + let recovered = recover_raw_transaction(&tx)?; + + // broadcast raw transaction to subscribers if there is any. + self.broadcast_raw_transaction(tx); + + let pool_transaction = ::Transaction::from_pooled(recovered); + + // submit the transaction to the pool with a `Local` origin + let hash = self + .pool() + .add_transaction(TransactionOrigin::Local, pool_transaction) + .await + .map_err(Self::Error::from_eth_err)?; + + Ok(hash) + } } impl LoadTransaction diff --git a/crates/static-file/static-file/src/segments/receipts.rs b/crates/static-file/static-file/src/segments/receipts.rs index bd808b4d839b..1490fb152241 100644 --- a/crates/static-file/static-file/src/segments/receipts.rs +++ b/crates/static-file/static-file/src/segments/receipts.rs @@ -1,7 +1,9 @@ use crate::segments::Segment; use alloy_primitives::BlockNumber; -use reth_db::tables; +use reth_codecs::Compact; +use reth_db::{table::Value, tables}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; +use reth_primitives_traits::NodePrimitives; use reth_provider::{ providers::StaticFileWriter, BlockReader, DBProvider, StaticFileProviderFactory, }; @@ -13,8 +15,11 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Receipts; -impl Segment - for Receipts +impl Segment for Receipts +where + Provider: StaticFileProviderFactory> + + DBProvider + + BlockReader, { fn segment(&self) -> StaticFileSegment { StaticFileSegment::Receipts @@ -36,7 +41,10 @@ impl Segment()?; + let mut receipts_cursor = provider + .tx_ref() + .cursor_read::::Receipt>>( + )?; let receipts_walker = receipts_cursor.walk_range(block_body_indices.tx_num_range())?; static_file_writer.append_receipts( 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 30a72561b235..66b01235a5d8 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -90,7 +90,11 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives< + SignedTx: Value + Compact, + BlockHeader: Value + Compact, + Receipt: Value + Compact, + >, > + StageCheckpointReader + BlockReader, >, diff --git a/crates/storage/codecs/derive/src/compact/generator.rs b/crates/storage/codecs/derive/src/compact/generator.rs index 63fef05ad705..a84913f59e81 100644 --- a/crates/storage/codecs/derive/src/compact/generator.rs +++ b/crates/storage/codecs/derive/src/compact/generator.rs @@ -1,6 +1,7 @@ //! Code generator for the `Compact` trait. use super::*; +use crate::ZstdConfig; use convert_case::{Case, Casing}; use syn::{Attribute, LitStr}; @@ -10,20 +11,20 @@ pub fn generate_from_to( attrs: &[Attribute], has_lifetime: bool, fields: &FieldList, - is_zstd: bool, + zstd: Option, ) -> TokenStream2 { let flags = format_ident!("{ident}Flags"); - let to_compact = generate_to_compact(fields, ident, is_zstd); - let from_compact = generate_from_compact(fields, ident, is_zstd); + let reth_codecs = parse_reth_codecs_path(attrs).unwrap(); + + let to_compact = generate_to_compact(fields, ident, zstd.clone(), &reth_codecs); + let from_compact = generate_from_compact(fields, ident, zstd); let snake_case_ident = ident.to_string().to_case(Case::Snake); let fuzz = format_ident!("fuzz_test_{snake_case_ident}"); let test = format_ident!("fuzz_{snake_case_ident}"); - let reth_codecs = parse_reth_codecs_path(attrs).unwrap(); - let lifetime = if has_lifetime { quote! { 'a } } else { @@ -77,7 +78,7 @@ pub fn generate_from_to( #fuzz_tests #impl_compact { - fn to_compact(&self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> { + fn to_compact(&self, buf: &mut B) -> usize where B: #reth_codecs::__private::bytes::BufMut + AsMut<[u8]> { let mut flags = #flags::default(); let mut total_length = 0; #(#to_compact)* @@ -92,7 +93,11 @@ pub fn generate_from_to( } /// Generates code to implement the `Compact` trait method `to_compact`. -fn generate_from_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> TokenStream2 { +fn generate_from_compact( + fields: &FieldList, + ident: &Ident, + zstd: Option, +) -> TokenStream2 { let mut lines = vec![]; let mut known_types = vec!["B256", "Address", "Bloom", "Vec", "TxHash", "BlockHash", "FixedBytes"]; @@ -147,38 +152,41 @@ fn generate_from_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> To // If the type has compression support, then check the `__zstd` flag. Otherwise, use the default // code branch. However, even if it's a type with compression support, not all values are // to be compressed (thus the zstd flag). Ideally only the bigger ones. - is_zstd - .then(|| { - let decompressor = format_ident!("{}_DECOMPRESSOR", ident.to_string().to_uppercase()); - quote! { - if flags.__zstd() != 0 { - #decompressor.with(|decompressor| { - let decompressor = &mut decompressor.borrow_mut(); - let decompressed = decompressor.decompress(buf); - let mut original_buf = buf; - - let mut buf: &[u8] = decompressed; - #(#lines)* - (obj, original_buf) - }) - } else { + if let Some(zstd) = zstd { + let decompressor = zstd.decompressor; + quote! { + if flags.__zstd() != 0 { + #decompressor.with(|decompressor| { + let decompressor = &mut decompressor.borrow_mut(); + let decompressed = decompressor.decompress(buf); + let mut original_buf = buf; + + let mut buf: &[u8] = decompressed; #(#lines)* - (obj, buf) - } - } - }) - .unwrap_or_else(|| { - quote! { + (obj, original_buf) + }) + } else { #(#lines)* (obj, buf) } - }) + } + } else { + quote! { + #(#lines)* + (obj, buf) + } + } } /// Generates code to implement the `Compact` trait method `from_compact`. -fn generate_to_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> Vec { +fn generate_to_compact( + fields: &FieldList, + ident: &Ident, + zstd: Option, + reth_codecs: &syn::Path, +) -> Vec { let mut lines = vec![quote! { - let mut buffer = bytes::BytesMut::new(); + let mut buffer = #reth_codecs::__private::bytes::BytesMut::new(); }]; let is_enum = fields.iter().any(|field| matches!(field, FieldTypes::EnumVariant(_))); @@ -198,7 +206,7 @@ fn generate_to_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> Vec< // Just because a type supports compression, doesn't mean all its values are to be compressed. // We skip the smaller ones, and thus require a flag` __zstd` to specify if this value is // compressed or not. - if is_zstd { + if zstd.is_some() { lines.push(quote! { let mut zstd = buffer.len() > 7; if zstd { @@ -214,9 +222,8 @@ fn generate_to_compact(fields: &FieldList, ident: &Ident, is_zstd: bool) -> Vec< buf.put_slice(&flags); }); - if is_zstd { - let compressor = format_ident!("{}_COMPRESSOR", ident.to_string().to_uppercase()); - + if let Some(zstd) = zstd { + let compressor = zstd.compressor; lines.push(quote! { if zstd { #compressor.with(|compressor| { diff --git a/crates/storage/codecs/derive/src/compact/mod.rs b/crates/storage/codecs/derive/src/compact/mod.rs index 1c1723d2ec94..ab9ed78e164e 100644 --- a/crates/storage/codecs/derive/src/compact/mod.rs +++ b/crates/storage/codecs/derive/src/compact/mod.rs @@ -1,7 +1,7 @@ use proc_macro::TokenStream; use proc_macro2::{Ident, TokenStream as TokenStream2}; use quote::{format_ident, quote}; -use syn::{parse_macro_input, Data, DeriveInput, Generics}; +use syn::{Data, DeriveInput, Generics}; mod generator; use generator::*; @@ -15,6 +15,8 @@ use flags::*; mod structs; use structs::*; +use crate::ZstdConfig; + // Helper Alias type type IsCompact = bool; // Helper Alias type @@ -40,16 +42,16 @@ pub enum FieldTypes { } /// Derives the `Compact` trait and its from/to implementations. -pub fn derive(input: TokenStream, is_zstd: bool) -> TokenStream { +pub fn derive(input: DeriveInput, zstd: Option) -> TokenStream { let mut output = quote! {}; - let DeriveInput { ident, data, generics, attrs, .. } = parse_macro_input!(input); + let DeriveInput { ident, data, generics, attrs, .. } = input; let has_lifetime = has_lifetime(&generics); let fields = get_fields(&data); - output.extend(generate_flag_struct(&ident, &attrs, has_lifetime, &fields, is_zstd)); - output.extend(generate_from_to(&ident, &attrs, has_lifetime, &fields, is_zstd)); + output.extend(generate_flag_struct(&ident, &attrs, has_lifetime, &fields, zstd.is_some())); + output.extend(generate_from_to(&ident, &attrs, has_lifetime, &fields, zstd)); output.into() } @@ -236,7 +238,7 @@ mod tests { let DeriveInput { ident, data, attrs, .. } = parse2(f_struct).unwrap(); let fields = get_fields(&data); output.extend(generate_flag_struct(&ident, &attrs, false, &fields, false)); - output.extend(generate_from_to(&ident, &attrs, false, &fields, false)); + output.extend(generate_from_to(&ident, &attrs, false, &fields, None)); // Expected output in a TokenStream format. Commas matter! let should_output = quote! { @@ -298,10 +300,10 @@ mod tests { fuzz_test_test_struct(TestStruct::default()) } impl reth_codecs::Compact for TestStruct { - fn to_compact(&self, buf: &mut B) -> usize where B: bytes::BufMut + AsMut<[u8]> { + fn to_compact(&self, buf: &mut B) -> usize where B: reth_codecs::__private::bytes::BufMut + AsMut<[u8]> { let mut flags = TestStructFlags::default(); let mut total_length = 0; - let mut buffer = bytes::BytesMut::new(); + let mut buffer = reth_codecs::__private::bytes::BytesMut::new(); let f_u64_len = self.f_u64.to_compact(&mut buffer); flags.set_f_u64_len(f_u64_len as u8); let f_u256_len = self.f_u256.to_compact(&mut buffer); diff --git a/crates/storage/codecs/derive/src/lib.rs b/crates/storage/codecs/derive/src/lib.rs index 0b4015830f5d..a835e8fab3c2 100644 --- a/crates/storage/codecs/derive/src/lib.rs +++ b/crates/storage/codecs/derive/src/lib.rs @@ -20,6 +20,12 @@ use syn::{ mod arbitrary; mod compact; +#[derive(Clone)] +pub(crate) struct ZstdConfig { + compressor: syn::Path, + decompressor: syn::Path, +} + /// Derives the `Compact` trait for custom structs, optimizing serialization with a possible /// bitflag struct. /// @@ -51,15 +57,46 @@ mod compact; /// efficient decoding. #[proc_macro_derive(Compact, attributes(maybe_zero, reth_codecs))] pub fn derive(input: TokenStream) -> TokenStream { - let is_zstd = false; - compact::derive(input, is_zstd) + compact::derive(parse_macro_input!(input as DeriveInput), None) } /// Adds `zstd` compression to derived [`Compact`]. -#[proc_macro_derive(CompactZstd, attributes(maybe_zero, reth_codecs))] +#[proc_macro_derive(CompactZstd, attributes(maybe_zero, reth_codecs, reth_zstd))] pub fn derive_zstd(input: TokenStream) -> TokenStream { - let is_zstd = true; - compact::derive(input, is_zstd) + let input = parse_macro_input!(input as DeriveInput); + + let mut compressor = None; + let mut decompressor = None; + + for attr in &input.attrs { + if attr.path().is_ident("reth_zstd") { + if let Err(err) = attr.parse_nested_meta(|meta| { + if meta.path.is_ident("compressor") { + let value = meta.value()?; + let path: syn::Path = value.parse()?; + compressor = Some(path); + } else if meta.path.is_ident("decompressor") { + let value = meta.value()?; + let path: syn::Path = value.parse()?; + decompressor = Some(path); + } else { + return Err(meta.error("unsupported attribute")) + } + Ok(()) + }) { + return err.to_compile_error().into() + } + } + } + + let (Some(compressor), Some(decompressor)) = (compressor, decompressor) else { + return quote! { + compile_error!("missing compressor or decompressor attribute"); + } + .into() + }; + + compact::derive(input, Some(ZstdConfig { compressor, decompressor })) } /// Generates tests for given type. diff --git a/crates/storage/codecs/src/private.rs b/crates/storage/codecs/src/private.rs index 6f54d9c9ca82..440310ffd3df 100644 --- a/crates/storage/codecs/src/private.rs +++ b/crates/storage/codecs/src/private.rs @@ -1,3 +1,3 @@ pub use modular_bitfield; -pub use bytes::Buf; +pub use bytes::{self, Buf}; diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index d02c59278666..9e9e1d16fe0e 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -1,3 +1,5 @@ +use core::fmt; + use crate::{ AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, BlockchainTreePendingStateProvider, CanonStateNotifications, @@ -124,7 +126,6 @@ impl TreeNodeTypes for T where T: ProviderNodeTypes + NodeTypesForTree {} /// This type serves as the main entry point for interacting with the blockchain and provides data /// from database storage and from the blockchain tree (pending state etc.) It is a simple wrapper /// type that holds an instance of the database and the blockchain tree. -#[allow(missing_debug_implementations)] pub struct BlockchainProvider { /// Provider type used to access the database. database: ProviderFactory, @@ -964,3 +965,9 @@ impl AccountReader for BlockchainProvider { self.database.provider()?.basic_account(address) } } + +impl fmt::Debug for BlockchainProvider { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BlockchainProvider").finish_non_exhaustive() + } +} diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index b7f60c164423..3939e8b89456 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -11,7 +11,7 @@ use reth_nippy_jar::{NippyJar, NippyJarError, NippyJarWriter}; use reth_node_types::NodePrimitives; use reth_primitives::{ static_file::{SegmentHeader, SegmentRangeInclusive}, - Receipt, StaticFileSegment, + StaticFileSegment, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ @@ -615,7 +615,8 @@ impl StaticFileProviderRW { pub fn append_receipts(&mut self, receipts: I) -> ProviderResult> where I: Iterator>, - R: Borrow, + R: Borrow, + N::Receipt: Compact, { debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Receipts); diff --git a/crates/transaction-pool/src/blobstore/tracker.rs b/crates/transaction-pool/src/blobstore/tracker.rs index 817114fcf259..c359dcc7cf00 100644 --- a/crates/transaction-pool/src/blobstore/tracker.rs +++ b/crates/transaction-pool/src/blobstore/tracker.rs @@ -49,7 +49,7 @@ impl BlobStoreCanonTracker { .body .transactions() .iter() - .filter(|tx| tx.tx_type().is_eip4844()) + .filter(|tx| tx.is_eip4844()) .map(|tx| tx.trie_hash()); (*num, iter) }); diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index a0d4d40983e4..4dfa0bcc08fc 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -7,7 +7,7 @@ use crate::{ }; use alloy_consensus::{ constants::{EIP1559_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}, - Transaction as _, + Transaction as _, Typed2718, }; use alloy_eips::{ eip2718::Encodable2718, @@ -1368,7 +1368,7 @@ impl PoolTransaction for EthPooledTransaction { /// Returns the transaction type fn tx_type(&self) -> u8 { - self.transaction.tx_type().into() + self.transaction.ty() } /// Returns the length of the rlp encoded object @@ -1444,7 +1444,7 @@ impl TryFrom for EthPooledTransaction { fn try_from(tx: RecoveredTx) -> Result { // ensure we can handle the transaction type and its format - match tx.tx_type() as u8 { + match tx.ty() { 0..=EIP1559_TX_TYPE_ID | EIP7702_TX_TYPE_ID => { // supported } diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index bc26014f4083..1092a2702f7e 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -18,7 +18,10 @@ use alloy_consensus::{ }, BlockHeader, }; -use alloy_eips::eip4844::{env_settings::EnvKzgSettings, MAX_BLOBS_PER_BLOCK}; +use alloy_eips::{ + eip1559::ETHEREUM_BLOCK_GAS_LIMIT, + eip4844::{env_settings::EnvKzgSettings, MAX_BLOBS_PER_BLOCK}, +}; use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_primitives::{InvalidTransactionError, SealedBlock}; use reth_primitives_traits::GotExpected; @@ -530,7 +533,7 @@ impl EthTransactionValidatorBuilder { /// - EIP-4844 pub fn new(chain_spec: Arc) -> Self { Self { - block_gas_limit: chain_spec.max_gas_limit, + block_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, chain_spec, minimum_priority_fee: None, additional_tasks: 1, diff --git a/crates/trie/parallel/src/proof.rs b/crates/trie/parallel/src/proof.rs index 0f1a4b2624dd..6dd4a9a0138a 100644 --- a/crates/trie/parallel/src/proof.rs +++ b/crates/trie/parallel/src/proof.rs @@ -1,5 +1,8 @@ use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets}; -use alloy_primitives::{map::HashMap, B256}; +use alloy_primitives::{ + map::{B256HashMap, HashMap}, + B256, +}; use alloy_rlp::{BufMut, Encodable}; use itertools::Itertools; use reth_db::DatabaseError; @@ -15,7 +18,7 @@ use reth_trie::{ proof::StorageProof, trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory}, walker::TrieWalker, - HashBuilder, MultiProof, MultiProofTargets, Nibbles, TrieAccount, TrieInput, + HashBuilder, MultiProof, MultiProofTargets, Nibbles, StorageMultiProof, TrieAccount, TrieInput, TRIE_ACCOUNT_RLP_MAX_SIZE, }; use reth_trie_common::proof::ProofRetainer; @@ -101,7 +104,8 @@ where // Pre-calculate storage roots for accounts which were changed. tracker.set_precomputed_storage_roots(storage_root_targets.len() as u64); debug!(target: "trie::parallel_state_root", len = storage_root_targets.len(), "pre-generating storage proofs"); - let mut storage_proofs = HashMap::with_capacity(storage_root_targets.len()); + let mut storage_proofs = + B256HashMap::with_capacity_and_hasher(storage_root_targets.len(), Default::default()); for (hashed_address, prefix_set) in storage_root_targets.into_iter().sorted_unstable_by_key(|(address, _)| *address) { @@ -165,7 +169,10 @@ where .with_proof_retainer(retainer) .with_updates(self.collect_branch_node_hash_masks); - let mut storages = HashMap::default(); + // Initialize all storage multiproofs as empty. + // Storage multiproofs for non empty tries will be overwritten if necessary. + let mut storages: B256HashMap<_> = + targets.keys().map(|key| (*key, StorageMultiProof::empty())).collect(); let mut account_rlp = Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE); let mut account_node_iter = TrieNodeIter::new( walker, diff --git a/crates/trie/sparse/src/blinded.rs b/crates/trie/sparse/src/blinded.rs index 22471cf99ffd..a9f0e89c29c1 100644 --- a/crates/trie/sparse/src/blinded.rs +++ b/crates/trie/sparse/src/blinded.rs @@ -24,7 +24,7 @@ pub trait BlindedProvider { type Error: Into; /// Retrieve blinded node by path. - fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error>; + fn blinded_node(&mut self, path: &Nibbles) -> Result, Self::Error>; } /// Default blinded node provider factory that creates [`DefaultBlindedProvider`]. @@ -51,7 +51,7 @@ pub struct DefaultBlindedProvider; impl BlindedProvider for DefaultBlindedProvider { type Error = SparseTrieError; - fn blinded_node(&mut self, _path: Nibbles) -> Result, Self::Error> { + fn blinded_node(&mut self, _path: &Nibbles) -> Result, Self::Error> { Ok(None) } } diff --git a/crates/trie/sparse/src/trie.rs b/crates/trie/sparse/src/trie.rs index dd5acc639c63..3f2d6f58bd2e 100644 --- a/crates/trie/sparse/src/trie.rs +++ b/crates/trie/sparse/src/trie.rs @@ -878,7 +878,7 @@ where if self.updates.is_some() { // Check if the extension node child is a hash that needs to be revealed if self.nodes.get(¤t).unwrap().is_hash() { - if let Some(node) = self.provider.blinded_node(current.clone())? { + if let Some(node) = self.provider.blinded_node(¤t)? { let decoded = TrieNode::decode(&mut &node[..])?; trace!(target: "trie::sparse", ?current, ?decoded, "Revealing extension node child"); // We'll never have to update the revealed child node, only @@ -1031,7 +1031,7 @@ where if self.nodes.get(&child_path).unwrap().is_hash() { trace!(target: "trie::sparse", ?child_path, "Retrieving remaining blinded branch child"); - if let Some(node) = self.provider.blinded_node(child_path.clone())? { + if let Some(node) = self.provider.blinded_node(&child_path)? { let decoded = TrieNode::decode(&mut &node[..])?; trace!(target: "trie::sparse", ?child_path, ?decoded, "Revealing remaining blinded branch child"); // We'll never have to update the revealed branch node, only remove diff --git a/crates/trie/trie/src/proof/blinded.rs b/crates/trie/trie/src/proof/blinded.rs index 1383453f344d..33a1a43b579b 100644 --- a/crates/trie/trie/src/proof/blinded.rs +++ b/crates/trie/trie/src/proof/blinded.rs @@ -33,8 +33,8 @@ impl ProofBlindedProviderFactory { impl BlindedProviderFactory for ProofBlindedProviderFactory where - T: TrieCursorFactory + Clone, - H: HashedCursorFactory + Clone, + T: TrieCursorFactory + Clone + Send + Sync, + H: HashedCursorFactory + Clone + Send + Sync, { type AccountNodeProvider = ProofBlindedAccountProvider; type StorageNodeProvider = ProofBlindedStorageProvider; @@ -81,20 +81,20 @@ impl ProofBlindedAccountProvider { impl BlindedProvider for ProofBlindedAccountProvider where - T: TrieCursorFactory + Clone, - H: HashedCursorFactory + Clone, + T: TrieCursorFactory + Clone + Send + Sync, + H: HashedCursorFactory + Clone + Send + Sync, { type Error = SparseTrieError; - fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error> { - let targets = HashMap::from_iter([(pad_path_to_key(&path), HashSet::default())]); + fn blinded_node(&mut self, path: &Nibbles) -> Result, Self::Error> { + let targets = HashMap::from_iter([(pad_path_to_key(path), HashSet::default())]); let proof = Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone()) .with_prefix_sets_mut(self.prefix_sets.as_ref().clone()) .multiproof(targets) .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?; - Ok(proof.account_subtree.into_inner().remove(&path)) + Ok(proof.account_subtree.into_inner().remove(path)) } } @@ -125,13 +125,13 @@ impl ProofBlindedStorageProvider { impl BlindedProvider for ProofBlindedStorageProvider where - T: TrieCursorFactory + Clone, - H: HashedCursorFactory + Clone, + T: TrieCursorFactory + Clone + Send + Sync, + H: HashedCursorFactory + Clone + Send + Sync, { type Error = SparseTrieError; - fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error> { - let targets = HashSet::from_iter([pad_path_to_key(&path)]); + fn blinded_node(&mut self, path: &Nibbles) -> Result, Self::Error> { + let targets = HashSet::from_iter([pad_path_to_key(path)]); let storage_prefix_set = self.prefix_sets.storage_prefix_sets.get(&self.account).cloned().unwrap_or_default(); let proof = StorageProof::new_hashed( @@ -143,6 +143,6 @@ where .storage_multiproof(targets) .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?; - Ok(proof.subtree.into_inner().remove(&path)) + Ok(proof.subtree.into_inner().remove(path)) } } diff --git a/crates/trie/trie/src/witness.rs b/crates/trie/trie/src/witness.rs index 5e56cbf21c71..f48815d9ba9c 100644 --- a/crates/trie/trie/src/witness.rs +++ b/crates/trie/trie/src/witness.rs @@ -75,8 +75,8 @@ impl TrieWitness { impl TrieWitness where - T: TrieCursorFactory + Clone, - H: HashedCursorFactory + Clone, + T: TrieCursorFactory + Clone + Send + Sync, + H: HashedCursorFactory + Clone + Send + Sync, { /// Compute the state transition witness for the trie. Gather all required nodes /// to apply `state` on top of the current trie state. @@ -249,7 +249,7 @@ where { type Error = P::Error; - fn blinded_node(&mut self, path: Nibbles) -> Result, Self::Error> { + fn blinded_node(&mut self, path: &Nibbles) -> Result, Self::Error> { let maybe_node = self.provider.blinded_node(path)?; if let Some(node) = &maybe_node { self.tx diff --git a/examples/bsc-p2p/src/chainspec.rs b/examples/bsc-p2p/src/chainspec.rs index 8a47a604e726..588175734ff9 100644 --- a/examples/bsc-p2p/src/chainspec.rs +++ b/examples/bsc-p2p/src/chainspec.rs @@ -23,7 +23,6 @@ pub(crate) fn bsc_chain_spec() -> Arc { )]), deposit_contract: None, base_fee_params: reth_chainspec::BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: 140_000_000, prune_delete_limit: 0, } .into() diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index f30956d8f5cf..8437cf8d3c4d 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -46,12 +46,14 @@ use reth::{ }, tasks::TaskManager, transaction_pool::{PoolTransaction, TransactionPool}, + version::default_extra_data_bytes, }; use reth_basic_payload_builder::{ BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig, BuildArguments, BuildOutcome, PayloadBuilder, PayloadConfig, }; use reth_chainspec::{Chain, ChainSpec, ChainSpecProvider}; +use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_node_api::{ payload::{EngineApiMessageVersion, EngineObjectValidationError, PayloadOrAttributes}, validate_version_specific_fields, AddOnsContext, EngineTypes, EngineValidator, @@ -398,20 +400,21 @@ where args: BuildArguments, ) -> Result, PayloadBuilderError> { let BuildArguments { client, pool, cached_reads, config, cancel, best_payload } = args; - let PayloadConfig { parent_header, extra_data, attributes } = config; + let PayloadConfig { parent_header, attributes } = config; let chain_spec = client.chain_spec(); // This reuses the default EthereumPayloadBuilder to build the payload // but any custom logic can be implemented here - reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new( - chain_spec.clone(), - )) + reth_ethereum_payload_builder::EthereumPayloadBuilder::new( + EthEvmConfig::new(chain_spec.clone()), + EthereumBuilderConfig::new(default_extra_data_bytes()), + ) .try_build(BuildArguments { client, pool, cached_reads, - config: PayloadConfig { parent_header, extra_data, attributes: attributes.0 }, + config: PayloadConfig { parent_header, attributes: attributes.0 }, cancel, best_payload, }) @@ -422,10 +425,16 @@ where client: &Client, config: PayloadConfig, ) -> Result { - let PayloadConfig { parent_header, extra_data, attributes } = config; + let PayloadConfig { parent_header, attributes } = config; let chain_spec = client.chain_spec(); - >::build_empty_payload(&reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new(chain_spec.clone())),client, - PayloadConfig { parent_header, extra_data, attributes: attributes.0}) + >::build_empty_payload( + &reth_ethereum_payload_builder::EthereumPayloadBuilder::new( + EthEvmConfig::new(chain_spec.clone()), + EthereumBuilderConfig::new(default_extra_data_bytes()) + ), + client, + PayloadConfig { parent_header, attributes: attributes.0} + ) } } diff --git a/examples/custom-payload-builder/src/generator.rs b/examples/custom-payload-builder/src/generator.rs index da48a0754f9c..6620170fe897 100644 --- a/examples/custom-payload-builder/src/generator.rs +++ b/examples/custom-payload-builder/src/generator.rs @@ -1,6 +1,5 @@ use crate::job::EmptyBlockPayloadJob; use alloy_eips::BlockNumberOrTag; -use alloy_primitives::Bytes; use reth::{ providers::{BlockReaderIdExt, BlockSource, StateProviderFactory}, tasks::TaskSpawner, @@ -85,7 +84,7 @@ where let hash = parent_block.hash(); let header = SealedHeader::new(parent_block.header().clone(), hash); - let config = PayloadConfig::new(Arc::new(header), Bytes::default(), attributes); + let config = PayloadConfig::new(Arc::new(header), attributes); Ok(EmptyBlockPayloadJob { client: self.client.clone(), _pool: self.pool.clone(), diff --git a/examples/custom-payload-builder/src/main.rs b/examples/custom-payload-builder/src/main.rs index d7c42e341b59..6ae920378294 100644 --- a/examples/custom-payload-builder/src/main.rs +++ b/examples/custom-payload-builder/src/main.rs @@ -18,9 +18,11 @@ use reth::{ payload::PayloadBuilderHandle, providers::CanonStateSubscriptions, transaction_pool::{PoolTransaction, TransactionPool}, + version::default_extra_data_bytes, }; use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig; use reth_chainspec::ChainSpec; +use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_node_api::NodeTypesWithEngine; use reth_node_ethereum::{node::EthereumAddOns, EthEngineTypes, EthEvmConfig, EthereumNode}; use reth_payload_builder::PayloadBuilderService; @@ -65,9 +67,10 @@ where pool, ctx.task_executor().clone(), payload_job_config, - reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new( - ctx.chain_spec(), - )), + reth_ethereum_payload_builder::EthereumPayloadBuilder::new( + EthEvmConfig::new(ctx.chain_spec()), + EthereumBuilderConfig::new(default_extra_data_bytes()), + ), ); let (payload_service, payload_builder) = diff --git a/examples/polygon-p2p/src/chain_cfg.rs b/examples/polygon-p2p/src/chain_cfg.rs index 84bfac8f209f..229e4301b8c2 100644 --- a/examples/polygon-p2p/src/chain_cfg.rs +++ b/examples/polygon-p2p/src/chain_cfg.rs @@ -29,7 +29,6 @@ pub(crate) fn polygon_chain_spec() -> Arc { ]), deposit_contract: None, base_fee_params: reth_chainspec::BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - max_gas_limit: 30_000_000, prune_delete_limit: 0, } .into()