diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 76e9bfcaaa2..d17ebe3c176 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -76,7 +76,7 @@ body: id: terms attributes: label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/paradigmxyz/reth/blob/main/CONTRIBUTING.md#code-of-conduct) + description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/foundry-rs/reth/blob/main/CODE_OF_CONDUCT.md) options: - label: I agree to follow the Code of Conduct required: true diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index db26044dfa5..cd5b3f54d6a 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -5,6 +5,7 @@ on: branches: [main] env: + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always concurrency: diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml deleted file mode 100644 index e731a7a5692..00000000000 --- a/.github/workflows/dependencies.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Automatically run `cargo update` periodically - -name: Update Dependencies - -on: - schedule: - # Run weekly - - cron: "0 0 * * SUN" - workflow_dispatch: - # Needed so we can run it manually - -env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: cargo-update - TITLE: "chore(deps): weekly `cargo update`" - BODY: | - Automation to keep dependencies in `Cargo.lock` current. - -
cargo update log -

- - ```log - $cargo_update_log - ``` - -

-
- -jobs: - update: - name: Update - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@nightly - - - name: cargo update - # Remove first line that always just says "Updating crates.io index" - run: cargo update --color never 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - - name: craft commit message and PR body - id: msg - run: | - export cargo_update_log="$(cat cargo_update.log)" - - echo "commit_message<> $GITHUB_OUTPUT - printf "$TITLE\n\n$cargo_update_log\n" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - echo "body<> $GITHUB_OUTPUT - echo "$BODY" | envsubst >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v5 - with: - add-paths: ./Cargo.lock - commit-message: ${{ steps.msg.outputs.commit_message }} - title: ${{ env.TITLE }} - body: ${{ steps.msg.outputs.body }} - branch: ${{ env.BRANCH }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 476d9c82100..06dbff26f2d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -9,6 +9,7 @@ on: env: REPO_NAME: ${{ github.repository_owner }}/reth IMAGE_NAME: ${{ github.repository_owner }}/reth + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/reth DOCKER_USERNAME: ${{ github.actor }} diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 07a31797afb..ebe22fedc72 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -5,6 +5,7 @@ on: branches: [main] env: + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always concurrency: diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index fbc598b95ac..b564803e4e4 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -4,6 +4,7 @@ on: - cron: '0 0 * * *' env: + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always concurrency: diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index e45643ae55a..20886b9e4ba 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -5,6 +5,7 @@ on: branches: [main] env: + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always GETH_BUILD: 1.12.0-e501b3b0 SEED: rustethereumethereumrust diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1417695755f..5a5bedaaf7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,7 @@ on: env: REPO_NAME: ${{ github.repository_owner }}/reth IMAGE_NAME: ${{ github.repository_owner }}/reth + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always jobs: diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 6c89dca7160..e46f5a112f2 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -5,6 +5,7 @@ on: branches: [main] env: + RUSTFLAGS: -D warnings CARGO_TERM_COLOR: always SEED: rustethereumethereumrust diff --git a/Cargo.lock b/Cargo.lock index 5ba8118176f..1d5a1f6b229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "gimli", ] @@ -51,12 +51,12 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", - "cipher 0.4.4", + "cipher 0.4.3", "cpufeatures", ] @@ -80,7 +80,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", "once_cell", "version_check", ] @@ -92,7 +92,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.10", + "getrandom 0.2.9", "once_cell", "version_check", ] @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -151,72 +151,22 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "anstream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is-terminal", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", -] - [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "759d98a5db12e9c9d98ef2b92f794ae5c7ded6ec18d21c3fa485c9c65bec237d" dependencies = [ - "include_dir", "itertools 0.10.5", "proc-macro-error", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -229,20 +179,11 @@ dependencies = [ "derive_arbitrary", ] -[[package]] -name = "array-init" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" -dependencies = [ - "nodrop", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "assert_matches" @@ -252,9 +193,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.1" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" dependencies = [ "brotli", "flate2", @@ -262,8 +203,8 @@ dependencies = [ "memchr", "pin-project-lite", "tokio", - "zstd", - "zstd-safe", + "zstd 0.11.2+zstd.1.5.2", + "zstd-safe 5.0.2+zstd.1.5.2", ] [[package]] @@ -277,13 +218,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -308,9 +249,9 @@ dependencies = [ [[package]] name = "atomic-polyfill" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" dependencies = [ "critical-section", ] @@ -335,7 +276,7 @@ checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" dependencies = [ "proc-macro-error", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -347,21 +288,21 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backon" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a6197b2120bb2185a267f6515038558b019e92b832bb0320e96d66268dcf9" +checksum = "f34fac4d7cdaefa2deded0eda2d5d59dbfd43370ff3f856209e72340ae84c294" dependencies = [ - "fastrand 1.9.0", - "futures-core", + "futures", "pin-project", + "rand 0.8.5", "tokio", ] [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", @@ -386,9 +327,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "base64ct" @@ -398,9 +345,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "basic-toml" -version = "0.1.4" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" +checksum = "2e819b667739967cd44d308b8c7b71305d8bb0729ac44a248aa08f33d01950b4" dependencies = [ "serde", ] @@ -442,7 +389,7 @@ dependencies = [ "lazycell", "peeking_take_while", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "regex", "rustc-hash", "shlex", @@ -463,11 +410,11 @@ dependencies = [ "peeking_take_while", "prettyplease", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "regex", "rustc-hash", "shlex", - "syn 2.0.27", + "syn 2.0.26", ] [[package]] @@ -540,9 +487,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +checksum = "0a90ec2df9600c28a01c56c4784c9207a96d2451833aeceb8cc97e4c9548bb78" dependencies = [ "generic-array", ] @@ -550,7 +497,7 @@ dependencies = [ [[package]] name = "boa_ast" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "bitflags 2.3.3", "boa_interner", @@ -563,7 +510,7 @@ dependencies = [ [[package]] name = "boa_engine" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "bitflags 2.3.3", "boa_ast", @@ -601,7 +548,7 @@ dependencies = [ [[package]] name = "boa_gc" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "boa_macros", "boa_profiler", @@ -611,7 +558,7 @@ dependencies = [ [[package]] name = "boa_icu_provider" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "icu_collections", "icu_normalizer", @@ -624,7 +571,7 @@ dependencies = [ [[package]] name = "boa_interner" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "boa_gc", "boa_macros", @@ -639,18 +586,18 @@ dependencies = [ [[package]] name = "boa_macros" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", "synstructure 0.13.0", ] [[package]] name = "boa_parser" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" dependencies = [ "bitflags 2.3.3", "boa_ast", @@ -670,7 +617,7 @@ dependencies = [ [[package]] name = "boa_profiler" version = "0.17.0" -source = "git+https://github.com/boa-dev/boa#d459ff1b444ac119fe58e46c4e32e874a8135ce3" +source = "git+https://github.com/boa-dev/boa#b51e7cfb84fd6a4dc474d103e5654efedfe94a4e" [[package]] name = "brotli" @@ -710,14 +657,14 @@ checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", - "regex-automata 0.1.10", + "regex-automata", ] [[package]] name = "bstr" -version = "1.6.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1" dependencies = [ "memchr", "serde", @@ -725,9 +672,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" @@ -758,18 +705,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "6031a462f977dd38968b6f23378356512feeace69cef817e1a4475108093cec3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ "serde", ] @@ -839,9 +786,9 @@ dependencies = [ [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" dependencies = [ "ciborium-io", "ciborium-ll", @@ -850,15 +797,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" dependencies = [ "ciborium-io", "half", @@ -875,9 +822,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ "crypto-common", "inout", @@ -885,9 +832,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" dependencies = [ "glob", "libc", @@ -896,44 +843,40 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.19" +version = "4.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" dependencies = [ - "clap_builder", + "bitflags 1.3.2", "clap_derive", - "once_cell", -] - -[[package]] -name = "clap_builder" -version = "4.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" -dependencies = [ - "anstream", - "anstyle", "clap_lex", + "is-terminal", + "once_cell", "strsim 0.10.0", + "termcolor", ] [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" dependencies = [ "heck", + "proc-macro-error", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" +dependencies = [ + "os_str_bytes", +] [[package]] name = "cobs" @@ -948,9 +891,19 @@ dependencies = [ "convert_case 0.6.0", "parity-scale-codec", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "serde", - "syn 2.0.27", + "syn 2.0.26", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", ] [[package]] @@ -962,13 +915,13 @@ dependencies = [ "bincode", "bs58", "coins-core", - "digest 0.10.7", - "getrandom 0.2.10", + "digest 0.10.6", + "getrandom 0.2.9", "hmac", "k256", "lazy_static", "serde", - "sha2 0.10.7", + "sha2 0.10.6", "thiserror", ] @@ -980,12 +933,12 @@ checksum = "84f4d04ee18e58356accd644896aeb2094ddeafb6a713e056cef0c0a8e468c15" dependencies = [ "bitvec 0.17.4", "coins-bip32", - "getrandom 0.2.10", + "getrandom 0.2.9", "hmac", "once_cell", - "pbkdf2 0.12.2", + "pbkdf2 0.12.1", "rand 0.8.5", - "sha2 0.10.7", + "sha2 0.10.6", "thiserror", ] @@ -995,26 +948,20 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b949a1c63fb7eb591eb7ba438746326aedf0ae843e51ec92ba6bec5bb382c4f" dependencies = [ - "base64 0.21.2", + "base64 0.21.0", "bech32", "bs58", - "digest 0.10.7", + "digest 0.10.6", "generic-array", "hex", "ripemd", "serde", "serde_derive", - "sha2 0.10.7", + "sha2 0.10.6", "sha3", "thiserror", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "comfy-table" version = "7.0.1" @@ -1053,9 +1000,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "const-str" @@ -1090,9 +1037,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpp_demangle" @@ -1105,9 +1052,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] @@ -1181,9 +1128,9 @@ checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1202,9 +1149,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", @@ -1215,9 +1162,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -1271,9 +1218,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1291,6 +1238,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote 1.0.31", + "syn 1.0.109", +] + [[package]] name = "ctr" version = "0.8.0" @@ -1306,35 +1263,66 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.4", + "cipher 0.4.3", ] [[package]] name = "curve25519-dalek" -version = "4.0.0-rc.3" +version = "4.0.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ace70fc06e06f7f689d2624dc4e2f0ea666efb5aa704215f7249ae6e047a7" +checksum = "03d928d978dbec61a1167414f5ec534f24bea0d7a0d24dd9b6233d3d8223e585" dependencies = [ "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", + "digest 0.10.6", "fiat-crypto", + "packed_simd_2", "platforms", - "rustc_version", "subtle", "zeroize", ] [[package]] -name = "curve25519-dalek-derive" -version = "0.1.0" +name = "cxx" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" dependencies = [ + "cc", + "codespan-reporting", + "once_cell", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "scratch", + "syn 1.0.109", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.31", + "syn 1.0.109", ] [[package]] @@ -1349,12 +1337,22 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.14.3", + "darling_macro 0.14.3", +] + +[[package]] +name = "darling" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +dependencies = [ + "darling_core 0.20.1", + "darling_macro 0.20.1", ] [[package]] @@ -1366,23 +1364,37 @@ dependencies = [ "fnv", "ident_case", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "strsim 0.9.3", "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.3" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.66", + "quote 1.0.31", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "strsim 0.10.0", - "syn 2.0.27", + "syn 2.0.26", ] [[package]] @@ -1392,19 +1404,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ "darling_core 0.10.2", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ - "darling_core 0.20.3", - "quote 1.0.32", - "syn 2.0.27", + "darling_core 0.14.3", + "quote 1.0.31", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +dependencies = [ + "darling_core 0.20.1", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -1422,9 +1445,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "debugid" @@ -1432,7 +1455,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ - "uuid 1.4.1", + "uuid 1.3.0", ] [[package]] @@ -1447,9 +1470,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.7" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "82b10af9f9f9f2134a42d3f8aa74658660f2e0234b0eb81bd171df8aa32779ed" dependencies = [ "const-oid", "zeroize", @@ -1457,13 +1480,13 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", ] [[package]] @@ -1475,7 +1498,7 @@ dependencies = [ "darling 0.10.2", "derive_builder_core", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -1487,7 +1510,7 @@ checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" dependencies = [ "darling 0.10.2", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -1499,7 +1522,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case 0.4.0", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "rustc_version", "syn 1.0.109", ] @@ -1527,9 +1550,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.7" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.4", "const-oid", @@ -1543,16 +1566,16 @@ version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" dependencies = [ - "dirs-sys 0.3.7", + "dirs-sys", ] [[package]] name = "dirs" -version = "5.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -1576,18 +1599,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1601,14 +1612,14 @@ dependencies = [ [[package]] name = "discv5" -version = "0.3.1" -source = "git+https://github.com/sigp/discv5#a9f1e99321aec746fb9d6e8df889aa515a5e1254" +version = "0.3.0" +source = "git+https://github.com/sigp/discv5#f78d538ef8f3c3b3981cfbb8ce2ba3179295eeab" dependencies = [ "aes 0.7.5", "aes-gcm", "arrayvec", "delay_map", - "enr 0.9.0", + "enr", "fnv", "futures", "hashlink", @@ -1620,8 +1631,8 @@ dependencies = [ "parking_lot 0.11.2", "rand 0.8.5", "rlp", - "smallvec 1.11.0", - "socket2 0.4.9", + "smallvec", + "socket2", "tokio", "tracing", "tracing-subscriber", @@ -1636,8 +1647,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -1648,7 +1659,7 @@ checksum = "53ecafc952c4528d9b51a458d1a8904b81783feff9fde08ab6ed2545ff396872" dependencies = [ "cfg-if", "libc", - "socket2 0.4.9", + "socket2", "winapi", ] @@ -1660,28 +1671,27 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" [[package]] name = "dyn-clone" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" dependencies = [ "der", - "digest 0.10.7", + "digest 0.10.6", "elliptic-curve", "rfc6979", "signature", - "spki", ] [[package]] @@ -1696,27 +1706,27 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0-rc.3" +version = "2.0.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa8e9049d5d72bfc12acbc05914731b5322f79b5e2f195e9f2d705fca22ab4c" +checksum = "798f704d128510932661a3489b08e3f4c934a01d61c5def59ae7b8e48f19665a" dependencies = [ "curve25519-dalek", "ed25519", "rand_core 0.6.4", "serde", - "sha2 0.10.7", + "sha2 0.10.6", "zeroize", ] [[package]] name = "educe" -version = "0.4.22" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079044df30bb07de7d846d41a184c4b00e66ebdac93ee459253474f3a47e50ae" +checksum = "cb0188e3c3ba8df5753894d54461f0e39bc91741dc5b22e1c46999ec2c71f4e4" dependencies = [ "enum-ordinalize", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -1732,6 +1742,7 @@ dependencies = [ "reth-rlp", "reth-stages", "serde", + "serde_bytes", "serde_json", "thiserror", "tokio", @@ -1740,19 +1751,19 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest 0.10.6", "ff", "generic-array", "group", @@ -1792,33 +1803,14 @@ checksum = "cf56acd72bb22d2824e66ae8e9e5ada4d0de17a69c7fd35569dde2ada8ec9116" dependencies = [ "base64 0.13.1", "bytes", - "hex", - "k256", - "log", - "rand 0.8.5", - "rlp", - "secp256k1", - "serde", - "sha3", - "zeroize", -] - -[[package]] -name = "enr" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" -dependencies = [ - "base64 0.21.2", - "bytes", "ed25519-dalek", "hex", "k256", "log", "rand 0.8.5", "rlp", + "secp256k1", "serde", - "serde-hex", "sha3", "zeroize", ] @@ -1831,7 +1823,7 @@ checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" dependencies = [ "heck", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -1843,39 +1835,40 @@ checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ "heck", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] [[package]] name = "enum-ordinalize" -version = "3.1.13" +version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f76552f53cefc9a7f64987c3701b99d982f7690606fd67de1d09712fbf52f1" +checksum = "a62bb1df8b45ecb7ffa78dca1c17a438fb193eb083db0b1b494d2a61bcb5096a" dependencies = [ "num-bigint", "num-traits", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "rustc_version", + "syn 1.0.109", ] [[package]] name = "enumn" -version = "0.1.11" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b893c4eb2dc092c811165f84dc7447fae16fb66521717968c34c509b39b1a5c5" +checksum = "48016319042fb7c87b78d2993084a831793a897a5cd1a2a67cab9d1eeb4b7d76" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" [[package]] name = "errno" @@ -1915,9 +1908,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ - "aes 0.8.3", + "aes 0.8.2", "ctr 0.9.2", - "digest 0.10.7", + "digest 0.10.6", "hex", "hmac", "pbkdf2 0.11.0", @@ -1925,7 +1918,7 @@ dependencies = [ "scrypt", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.6", "sha3", "thiserror", "uuid 0.8.2", @@ -2012,12 +2005,12 @@ dependencies = [ "hex", "prettyplease", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "regex", "serde", "serde_json", - "syn 2.0.27", - "toml 0.7.6", + "syn 2.0.26", + "toml 0.7.5", "walkdir", ] @@ -2032,9 +2025,9 @@ dependencies = [ "ethers-core", "hex", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "serde_json", - "syn 2.0.27", + "syn 2.0.26", ] [[package]] @@ -2060,7 +2053,7 @@ dependencies = [ "serde", "serde_json", "strum 0.25.0", - "syn 2.0.27", + "syn 2.0.26", "tempfile", "thiserror", "tiny-keccak", @@ -2117,9 +2110,9 @@ checksum = "b411b119f1cf0efb69e2190883dee731251882bb21270f893ee9513b3a697c48" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.2", + "base64 0.21.0", "bytes", - "enr 0.8.1", + "enr", "ethers-core", "futures-channel", "futures-core", @@ -2160,7 +2153,7 @@ dependencies = [ "ethers-core", "hex", "rand 0.8.5", - "sha2 0.10.7", + "sha2 0.10.6", "thiserror", "tracing", ] @@ -2224,12 +2217,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - [[package]] name = "fdlimit" version = "0.2.1" @@ -2281,9 +2268,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "miniz_oxide", @@ -2306,9 +2293,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ "percent-encoding", ] @@ -2390,8 +2377,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -2467,9 +2454,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "js-sys", @@ -2490,9 +2477,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "glob" @@ -2502,12 +2489,12 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ - "aho-corasick 1.0.2", - "bstr 1.6.0", + "aho-corasick 0.7.20", + "bstr 1.3.0", "fnv", "log", "regex", @@ -2515,15 +2502,14 @@ dependencies = [ [[package]] name = "gloo-net" -version = "0.3.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" dependencies = [ "futures-channel", "futures-core", "futures-sink", "gloo-utils", - "http", "js-sys", "pin-project", "serde", @@ -2548,9 +2534,9 @@ dependencies = [ [[package]] name = "gloo-utils" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" dependencies = [ "js-sys", "serde", @@ -2572,9 +2558,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.20" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -2694,9 +2680,18 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "hex" @@ -2734,16 +2729,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", ] [[package]] name = "home" -version = "0.5.5" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408" dependencies = [ - "windows-sys 0.48.0", + "winapi", ] [[package]] @@ -2781,9 +2776,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" [[package]] name = "httparse" @@ -2799,9 +2794,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "human_bytes" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27e2b089f28ad15597b48d8c0a8fe94eeb1c1cb26ca99b6f66ac9582ae10c5e6" +checksum = "39b528196c838e8b3da8b665e08c30958a6f2ede91d79f2ffcd0d4664b9c64eb" [[package]] name = "humantime" @@ -2821,9 +2816,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" dependencies = [ "bytes", "futures-channel", @@ -2836,7 +2831,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -2845,11 +2840,10 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" dependencies = [ - "futures-util", "http", "hyper", "log", @@ -2881,25 +2875,26 @@ checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "winapi", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" dependencies = [ - "cc", + "cxx", + "cxx-build", ] [[package]] @@ -2936,7 +2931,7 @@ dependencies = [ "icu_collections", "icu_properties", "icu_provider", - "smallvec 1.11.0", + "smallvec", "utf16_iter", "utf8_iter", "write16", @@ -2980,7 +2975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b728b9421e93eff1d9f8681101b78fa745e0748c95c655c83f337044a7e10" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -3003,9 +2998,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3068,29 +3063,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] -[[package]] -name = "include_dir" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" -dependencies = [ - "include_dir_macros", -] - -[[package]] -name = "include_dir_macros" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" -dependencies = [ - "proc-macro2 1.0.66", - "quote 1.0.32", -] - [[package]] name = "indenter" version = "0.3.3" @@ -3157,32 +3133,32 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.11" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.1", "libc", "windows-sys 0.48.0", ] [[package]] name = "ipconfig" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" dependencies = [ - "socket2 0.5.3", + "socket2", "widestring", - "windows-sys 0.48.0", - "winreg 0.50.0", + "winapi", + "winreg", ] [[package]] name = "ipnet" -version = "2.8.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "iri-string" @@ -3196,12 +3172,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi", - "rustix 0.38.4", + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix 0.37.11", "windows-sys 0.48.0", ] @@ -3225,15 +3202,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jemalloc-ctl" -version = "0.5.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cffc705424a344c054e135d12ee591402f4539245e8bbd64e6c9eaa9458b63c" +checksum = "c1891c671f3db85d8ea8525dd43ab147f9977041911d24a03e5a36187a7bfde9" dependencies = [ "jemalloc-sys", "libc", @@ -3242,9 +3219,9 @@ dependencies = [ [[package]] name = "jemalloc-sys" -version = "0.5.4+5.3.0-patched" +version = "0.5.3+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" +checksum = "f9bd5d616ea7ed58b571b2e209a65759664d7fb021a0819d7a790afc67e47ca1" dependencies = [ "cc", "libc", @@ -3252,9 +3229,9 @@ dependencies = [ [[package]] name = "jemallocator" -version = "0.5.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" +checksum = "16c2514137880c52b0b4822b563fadd38257c1f380858addb74a400889696ea6" dependencies = [ "jemalloc-sys", "libc", @@ -3271,18 +3248,18 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonrpsee" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f3783308bddc49d0218307f66a09330c106fbd792c58bac5c8dc294fdd0f98" +checksum = "1822d18e4384a5e79d94dc9e4d1239cfa9fad24e55b44d2efeff5b394c9fece4" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -3297,9 +3274,9 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abc5630e4fa0096f00ec7b44d520701fda4504170cb85e22dca603ae5d7ad0d7" +checksum = "11aa5766d5c430b89cb26a99b88f3245eb91534be8126102cea9e45ee3891b22" dependencies = [ "futures-channel", "futures-util", @@ -3319,9 +3296,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa4c4d5fb801dcc316d81f76422db259809037a86b3194ae538dd026b05ed7" +checksum = "64c6832a55f662b5a6ecc844db24b8b9c387453f923de863062c60ce33d62b81" dependencies = [ "anyhow", "async-lock", @@ -3347,9 +3324,9 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa7165efcbfbc951d180162ff28fe91b657ed81925e37a35e4a396ce12109f96" +checksum = "1705c65069729e3dccff6fd91ee431d5d31cabcf00ce68a62a2c6435ac713af9" dependencies = [ "async-trait", "hyper", @@ -3366,22 +3343,22 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc12b1d4f16a86e8c522823c4fab219c88c03eb7c924ec0501a64bf12e058b" +checksum = "c6027ac0b197ce9543097d02a290f550ce1d9432bf301524b013053c0b75cc94" dependencies = [ "heck", "proc-macro-crate", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] [[package]] name = "jsonrpsee-server" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e79d78cfd5abd8394da10753723093c3ff64391602941c9c4b1d80a3414fd53" +checksum = "4f06661d1a6b6e5b85469dc9c29acfbb9b3bb613797a6fd10a3ebb8a70754057" dependencies = [ "futures-util", "hyper", @@ -3399,9 +3376,9 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00aa7cc87bc42e04e26c8ac3e7186142f7fd2949c763d9b6a7e64a69672d8fb2" +checksum = "6e5bf6c75ce2a4217421154adfc65a24d2b46e77286e59bba5d9fa6544ccc8f4" dependencies = [ "anyhow", "beef", @@ -3413,9 +3390,9 @@ dependencies = [ [[package]] name = "jsonrpsee-wasm-client" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe953c2801356f214d3f4051f786b3d11134512a46763ee8c39a9e3fa2cc1c0" +checksum = "34e6ea7c6d862e60f8baebd946c037b70c6808a4e4e31e792a4029184e3ce13a" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -3424,9 +3401,9 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.19.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71b2597ec1c958c6d5bc94bb61b44d74eb28e69dc421731ab0035706f13882" +checksum = "a64b2589680ba1ad7863f279cd2d5083c1dc0a7c0ea959d22924553050f8ab9f" dependencies = [ "http", "jsonrpsee-client-transport", @@ -3436,11 +3413,11 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "8.3.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +checksum = "09f4f04699947111ec1733e71778d763555737579e44b85844cae8e1940a1828" dependencies = [ - "base64 0.21.2", + "base64 0.13.1", "pem", "ring", "serde", @@ -3458,15 +3435,15 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", + "sha2 0.10.6", "signature", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" dependencies = [ "cpufeatures", ] @@ -3504,9 +3481,15 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.7" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "libproc" @@ -3528,6 +3511,15 @@ dependencies = [ "bytes", ] +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3551,9 +3543,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "litemap" @@ -3588,9 +3580,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "03f1160296536f10c833a82dca22267d5486734230d47bf00bf435885814ba1e" dependencies = [ "hashbrown 0.13.2", ] @@ -3634,7 +3626,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -3643,12 +3635,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" version = "2.5.0" @@ -3666,33 +3652,22 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "metrics" -version = "0.20.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b9b8653cec6897f73b519a43fba5ee3d50f62fe9af80b428accdcc093b4a849" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ - "ahash 0.7.6", - "metrics-macros 0.6.0", - "portable-atomic 0.3.20", + "autocfg", ] [[package]] name = "metrics" -version = "0.21.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +checksum = "7b9b8653cec6897f73b519a43fba5ee3d50f62fe9af80b428accdcc093b4a849" dependencies = [ - "ahash 0.8.3", - "metrics-macros 0.7.0", - "portable-atomic 1.4.2", + "ahash 0.7.6", + "metrics-macros", + "portable-atomic", ] [[package]] @@ -3704,10 +3679,10 @@ dependencies = [ "hyper", "indexmap 1.9.3", "ipnet", - "metrics 0.20.1", + "metrics", "metrics-util", "parking_lot 0.12.1", - "portable-atomic 0.3.20", + "portable-atomic", "quanta", "thiserror", "tokio", @@ -3721,30 +3696,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "731f8ecebd9f3a4aa847dfe75455e4757a45da40a7793d2f0b1f9b6ed18b23f3" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] -[[package]] -name = "metrics-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" -dependencies = [ - "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", -] - [[package]] name = "metrics-process" -version = "1.0.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006271a8019ad7a9a28cfac2cc40e3ee104d54be763c4a0901e228a63f49d706" +checksum = "99eab79be9f7c18565e889d6eaed6f1ebdafb2b6a88aef446d2fee5e7796ed10" dependencies = [ "libproc", "mach2", - "metrics 0.21.1", + "metrics", "once_cell", "procfs", "rlimit", @@ -3762,11 +3726,11 @@ dependencies = [ "crossbeam-utils", "hashbrown 0.12.3", "indexmap 1.9.3", - "metrics 0.20.1", + "metrics", "num_cpus", "ordered-float", "parking_lot 0.12.1", - "portable-atomic 0.3.20", + "portable-atomic", "quanta", "radix_trie", "sketches-ddsketch", @@ -3774,9 +3738,9 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.17" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mime_guess" @@ -3796,9 +3760,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] @@ -3817,9 +3781,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.11.4" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" dependencies = [ "cfg-if", "downcast", @@ -3832,13 +3796,13 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.11.4" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" dependencies = [ "cfg-if", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -3859,7 +3823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -3875,7 +3839,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" dependencies = [ - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -3890,12 +3854,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nom" version = "7.1.3" @@ -3924,9 +3882,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" dependencies = [ "num-bigint", "num-complex", @@ -4002,21 +3960,21 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", - "libm", + "libm 0.2.6", ] [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -4037,24 +3995,15 @@ checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] name = "object" -version = "0.31.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -4065,7 +4014,7 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" dependencies = [ - "atomic-polyfill 1.0.3", + "atomic-polyfill 1.0.2", "critical-section", ] @@ -4102,7 +4051,7 @@ checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -4112,12 +4061,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "ordered-float" version = "2.10.0" @@ -4127,12 +4070,37 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "output_vt100" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" +dependencies = [ + "winapi", +] + [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm 0.1.4", +] + [[package]] name = "page_size" version = "0.4.2" @@ -4145,9 +4113,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" dependencies = [ "arrayvec", "bitvec 1.0.1", @@ -4160,13 +4128,13 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -4215,7 +4183,7 @@ dependencies = [ "instant", "libc", "redox_syscall 0.2.16", - "smallvec 1.11.0", + "smallvec", "winapi", ] @@ -4228,15 +4196,15 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.3.5", - "smallvec 1.11.0", + "smallvec", "windows-targets 0.48.1", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "pbkdf2" @@ -4244,16 +4212,16 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", ] [[package]] name = "pbkdf2" -version = "0.12.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", "hmac", ] @@ -4274,9 +4242,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pharos" @@ -4300,9 +4268,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ "phf_shared", "rand 0.8.5", @@ -4317,8 +4285,8 @@ dependencies = [ "phf_generator", "phf_shared", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -4332,22 +4300,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -4374,9 +4342,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "plain_hasher" @@ -4395,9 +4363,9 @@ checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -4408,15 +4376,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -4441,24 +4409,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e30165d31df606f5726b090ec7592c308a0eaf61721ff64c9a3018e344a8753e" -dependencies = [ - "portable-atomic 1.4.2", -] - -[[package]] -name = "portable-atomic" -version = "1.4.2" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" [[package]] name = "postcard" -version = "1.0.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb" +checksum = "cfa512cd0d087cc9f99ad30a1bf64795b67871edbead083ffc3a4dfafa59aa00" dependencies = [ "cobs", "heapless", @@ -4467,9 +4426,9 @@ dependencies = [ [[package]] name = "pprof" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978385d59daf9269189d052ca8a84c1acfd0715c0599a5d5188d4acc078ca46a" +checksum = "6b90f8560ad8bd57b207b8293bc5226e48e89039a6e590c12a297d91b84c7e60" dependencies = [ "backtrace", "cfg-if", @@ -4481,7 +4440,7 @@ dependencies = [ "nix", "once_cell", "parking_lot 0.12.1", - "smallvec 1.11.0", + "smallvec", "symbolic-demangle", "tempfile", "thiserror", @@ -4509,15 +4468,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" dependencies = [ "predicates-core", "termtree", @@ -4525,22 +4484,24 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" dependencies = [ + "ctor", "diff", + "output_vt100", "yansi", ] [[package]] name = "prettyplease" -version = "0.2.12" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058" dependencies = [ "proc-macro2 1.0.66", - "syn 2.0.27", + "syn 2.0.26", ] [[package]] @@ -4575,7 +4536,7 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", "version_check", ] @@ -4587,7 +4548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "version_check", ] @@ -4619,20 +4580,21 @@ dependencies = [ "byteorder", "hex", "lazy_static", - "rustix 0.36.15", + "rustix 0.36.11", ] [[package]] name = "proptest" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" dependencies = [ "bit-set", "bitflags 1.3.2", "byteorder", "lazy_static", "num-traits", + "quick-error 2.0.1", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", @@ -4696,6 +4658,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.26.0" @@ -4716,9 +4684,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2 1.0.66", ] @@ -4804,7 +4772,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", ] [[package]] @@ -4880,21 +4848,20 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.9.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick 1.0.1", "memchr", - "regex-automata 0.3.4", - "regex-syntax 0.7.4", + "regex-syntax 0.7.1", ] [[package]] @@ -4906,17 +4873,6 @@ dependencies = [ "regex-syntax 0.6.29", ] -[[package]] -name = "regex-automata" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" -dependencies = [ - "aho-corasick 1.0.2", - "memchr", - "regex-syntax 0.7.4", -] - [[package]] name = "regex-syntax" version = "0.6.29" @@ -4925,9 +4881,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "regress" @@ -4945,7 +4901,7 @@ version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.2", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -4970,7 +4926,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.10.1", + "winreg", ] [[package]] @@ -4980,7 +4936,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", - "quick-error", + "quick-error 1.2.3", ] [[package]] @@ -5014,7 +4970,6 @@ dependencies = [ "reth-beacon-consensus", "reth-blockchain-tree", "reth-config", - "reth-consensus-common", "reth-db", "reth-discv4", "reth-downloaders", @@ -5037,7 +4992,6 @@ dependencies = [ "reth-tasks", "reth-tracing", "reth-transaction-pool", - "reth-trie", "secp256k1", "serde", "serde_json", @@ -5045,7 +4999,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml 0.7.6", + "toml 0.7.5", "tracing", "tui", "vergen", @@ -5122,7 +5076,7 @@ dependencies = [ "aquamarine", "assert_matches", "linked_hash_set", - "lru 0.10.1", + "lru 0.10.0", "parking_lot 0.12.1", "reth-db", "reth-interfaces", @@ -5223,7 +5177,7 @@ name = "reth-discv4" version = "0.1.0-alpha.4" dependencies = [ "discv5", - "enr 0.8.1", + "enr", "generic-array", "hex", "rand 0.8.5", @@ -5247,7 +5201,7 @@ version = "0.1.0-alpha.4" dependencies = [ "async-trait", "data-encoding", - "enr 0.8.1", + "enr", "linked_hash_set", "parking_lot 0.12.1", "reth-net-common", @@ -5272,7 +5226,7 @@ dependencies = [ "assert_matches", "futures", "futures-util", - "itertools 0.11.0", + "itertools 0.10.5", "pin-project", "rayon", "reth-db", @@ -5294,12 +5248,12 @@ dependencies = [ name = "reth-ecies" version = "0.1.0-alpha.4" dependencies = [ - "aes 0.8.3", + "aes 0.8.2", "block-padding", "byteorder", - "cipher 0.4.4", + "cipher 0.4.3", "ctr 0.9.2", - "digest 0.10.7", + "digest 0.10.6", "educe", "futures", "generic-array", @@ -5311,7 +5265,7 @@ dependencies = [ "reth-primitives", "reth-rlp", "secp256k1", - "sha2 0.10.7", + "sha2 0.10.6", "sha3", "thiserror", "tokio", @@ -5435,7 +5389,7 @@ name = "reth-metrics" version = "0.1.0-alpha.4" dependencies = [ "futures", - "metrics 0.20.1", + "metrics", "reth-metrics-derive", "tokio", ] @@ -5444,13 +5398,13 @@ dependencies = [ name = "reth-metrics-derive" version = "0.1.0-alpha.4" dependencies = [ - "metrics 0.20.1", + "metrics", "once_cell", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "regex", "serial_test 0.10.0", - "syn 2.0.27", + "syn 2.0.26", "trybuild", ] @@ -5484,7 +5438,7 @@ dependencies = [ "aquamarine", "async-trait", "auto_impl", - "enr 0.8.1", + "enr", "ethers-core", "ethers-middleware", "ethers-providers", @@ -5552,7 +5506,7 @@ dependencies = [ "reth-rlp", "reth-rpc-types", "revm-primitives", - "sha2 0.10.7", + "sha2 0.10.6", "thiserror", "tokio", "tokio-stream", @@ -5600,11 +5554,11 @@ dependencies = [ "tiny-keccak", "tokio", "tokio-stream", - "toml 0.7.6", + "toml 0.7.5", "tracing", "triehash", "url", - "zstd", + "zstd 0.12.3+zstd.1.5.2", ] [[package]] @@ -5613,7 +5567,7 @@ version = "0.1.0-alpha.4" dependencies = [ "auto_impl", "derive_more", - "itertools 0.11.0", + "itertools 0.10.5", "parking_lot 0.12.1", "pin-project", "reth-db", @@ -5633,7 +5587,7 @@ name = "reth-prune" version = "0.1.0-alpha.4" dependencies = [ "assert_matches", - "itertools 0.11.0", + "itertools 0.10.5", "rayon", "reth-db", "reth-interfaces", @@ -5707,8 +5661,8 @@ name = "reth-rlp-derive" version = "0.1.0-alpha.4" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -5728,7 +5682,6 @@ dependencies = [ "jsonwebtoken", "pin-project", "rand 0.8.5", - "rayon", "reth-consensus-common", "reth-interfaces", "reth-metrics", @@ -5788,6 +5741,8 @@ version = "0.1.0-alpha.4" dependencies = [ "hyper", "jsonrpsee", + "pin-project", + "rayon", "reth-beacon-consensus", "reth-interfaces", "reth-ipc", @@ -5826,7 +5781,6 @@ dependencies = [ "reth-payload-builder", "reth-primitives", "reth-provider", - "reth-rlp", "reth-rpc-api", "reth-rpc-types", "reth-tasks", @@ -5839,9 +5793,10 @@ dependencies = [ name = "reth-rpc-types" version = "0.1.0-alpha.4" dependencies = [ - "itertools 0.11.0", + "assert_matches", "jsonrpsee-types", "rand 0.8.5", + "reth-interfaces", "reth-primitives", "reth-rlp", "serde", @@ -5859,7 +5814,7 @@ dependencies = [ "async-trait", "criterion", "futures-util", - "itertools 0.11.0", + "itertools 0.10.5", "num-traits", "paste", "pin-project", @@ -5917,12 +5872,10 @@ dependencies = [ "async-trait", "auto_impl", "bitflags 1.3.2", - "criterion", "fnv", "futures-util", "parking_lot 0.12.1", "paste", - "proptest", "rand 0.8.5", "reth-interfaces", "reth-metrics", @@ -5989,7 +5942,7 @@ dependencies = [ "revm-primitives", "ripemd", "secp256k1", - "sha2 0.10.7", + "sha2 0.10.6", "sha3", "substrate-bn", ] @@ -6058,7 +6011,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", ] [[package]] @@ -6088,7 +6041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -6115,9 +6068,9 @@ checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc-hash" @@ -6142,12 +6095,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.15" +version = "0.36.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" +checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" dependencies = [ "bitflags 1.3.2", - "errno 0.3.1", + "errno 0.2.8", "io-lifetimes", "libc", "linux-raw-sys 0.1.4", @@ -6156,22 +6109,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.4" +version = "0.37.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" dependencies = [ - "bitflags 2.3.3", + "bitflags 1.3.2", "errno 0.3.1", + "io-lifetimes", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys 0.3.1", "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.5" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" dependencies = [ "log", "ring", @@ -6181,9 +6135,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -6193,18 +6147,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64 0.21.2", + "base64 0.21.0", ] [[package]] name = "rustls-webpki" -version = "0.101.2" +version = "0.100.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" dependencies = [ "ring", "untrusted", @@ -6223,16 +6177,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ "fnv", - "quick-error", + "quick-error 1.2.3", "tempfile", "wait-timeout", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "ryu-js" @@ -6246,7 +6200,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" dependencies = [ - "cipher 0.4.4", + "cipher 0.4.3", ] [[package]] @@ -6260,9 +6214,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "0cfdffd972d76b22f3d7f81c8be34b2296afd3a25e0a547bd9abe340a4dbbe97" dependencies = [ "cfg-if", "derive_more", @@ -6272,23 +6226,23 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "61fa974aea2d63dd18a4ec3a49d59af9f34178c73a4f56d2f18205628d00681e" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.42.0", ] [[package]] @@ -6304,9 +6258,15 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.2.0" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "5d5e082f6ea090deaf0e6dd04b68360fd5cddb152af6ce8927c9d25db299f98c" [[package]] name = "scrypt" @@ -6317,7 +6277,7 @@ dependencies = [ "hmac", "pbkdf2 0.11.0", "salsa20", - "sha2 0.10.7", + "sha2 0.10.6", ] [[package]] @@ -6332,9 +6292,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct", "der", @@ -6366,9 +6326,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -6379,9 +6339,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -6389,9 +6349,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ "serde", ] @@ -6410,40 +6370,38 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.178" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] -name = "serde-hex" -version = "0.1.0" +name = "serde_bytes" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca37e3e4d1b39afd7ff11ee4e947efae85adfddf4841787bfa47c470e96dc26d" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ - "array-init", "serde", - "smallvec 0.6.14", ] [[package]] name = "serde_derive" -version = "1.0.178" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -6473,9 +6431,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c" dependencies = [ "base64 0.13.1", "chrono", @@ -6489,14 +6447,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e" dependencies = [ - "darling 0.20.3", + "darling 0.14.3", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", ] [[package]] @@ -6534,7 +6492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b64f9e531ce97c88b4778aad0ceee079216071cffec6ac9b904277f8f92e7fe3" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", ] @@ -6545,8 +6503,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -6570,7 +6528,7 @@ checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest 0.10.6", ] [[package]] @@ -6581,7 +6539,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest 0.10.6", ] [[package]] @@ -6599,22 +6557,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest 0.10.6", ] [[package]] name = "sha3" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", "keccak", ] @@ -6629,9 +6587,9 @@ dependencies = [ [[package]] name = "shellexpand" -version = "3.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +checksum = "dd1c7ddea665294d484c39fd0c0d2b7e35bbfe10035c5fe1854741a57f6880e1" dependencies = [ "dirs", ] @@ -6644,9 +6602,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "b824b6e687aff278cdbf3b36f07aa52d4bd4099699324d5da86a2ebce3aa00b3" dependencies = [ "libc", "signal-hook-registry", @@ -6678,7 +6636,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.7", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -6722,9 +6680,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "sketches-ddsketch" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a406c1882ed7f29cd5e248c9848a80e7cb6ae0fea82346d2746f2f941c07e1" +checksum = "ceb945e54128e09c43d8e4f1277851bd5044c6fc540bbaa2ad888f60b3da9ae7" [[package]] name = "slab" @@ -6735,15 +6693,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.11.0" @@ -6775,16 +6724,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "socket2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "soketto" version = "0.7.1" @@ -6818,9 +6757,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" dependencies = [ "base64ct", "der", @@ -6885,7 +6824,7 @@ checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "rustversion", "syn 1.0.109", ] @@ -6898,9 +6837,9 @@ checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" dependencies = [ "heck", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "rustversion", - "syn 2.0.27", + "syn 2.0.26", ] [[package]] @@ -6943,21 +6882,21 @@ dependencies = [ [[package]] name = "symbolic-common" -version = "12.3.0" +version = "12.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167a4ffd7c35c143fd1030aa3c2caf76ba42220bd5a6b5f4781896434723b8c3" +checksum = "38f7afd8bcd36190409e6b71d89928f7f09d918a7aa3460d847bc49a538d672e" dependencies = [ "debugid", "memmap2", "stable_deref_trait", - "uuid 1.4.1", + "uuid 1.3.0", ] [[package]] name = "symbolic-demangle" -version = "12.3.0" +version = "12.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e378c50e80686c1c5c205674e1f86a2858bec3d2a7dfdd690331a8a19330f293" +checksum = "ec64922563a36e3fe686b6d99f06f25dacad2a202ac7502ed642930a188fb20a" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -6982,18 +6921,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.27" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "unicode-ident", ] @@ -7004,7 +6943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", "unicode-xid 0.2.4", ] @@ -7016,8 +6955,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", "unicode-xid 0.2.4", ] @@ -7029,15 +6968,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.7.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", - "fastrand 2.0.0", + "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.4", - "windows-sys 0.48.0", + "rustix 0.37.11", + "windows-sys 0.45.0", ] [[package]] @@ -7051,15 +6990,15 @@ dependencies = [ [[package]] name = "termtree" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" [[package]] name = "test-fuzz" -version = "4.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954c28be70cafa409ddf615dd3c14a62478d38b44a94ade29469e82258cd5229" +checksum = "a7bb2f404d5d20140588fb209481f5841920a7e29c36124f3d1ac1041eb1842c" dependencies = [ "serde", "test-fuzz-internal", @@ -7069,40 +7008,40 @@ dependencies = [ [[package]] name = "test-fuzz-internal" -version = "4.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0528a7ad0bc85f826aa831434a37833aea622a5ae155f5b5dd431b25244213" +checksum = "385624eb0031d550fe1bf99c08af79b838605fc4fcec2c4d55e229a2c342fdd0" dependencies = [ "cargo_metadata", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "serde", - "strum_macros 0.25.1", + "strum_macros 0.24.3", ] [[package]] name = "test-fuzz-macro" -version = "4.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "646c4ee44c47ae7888e88fb8441c857bc21136fa2c7d6a0a766b0caf609b35e8" +checksum = "69247423e2d89bd51160e42200f6f45f921a23e5b44a0e5b57b888a378334037" dependencies = [ - "darling 0.20.3", + "darling 0.20.1", "if_chain", "itertools 0.10.5", "lazy_static", "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "subprocess", - "syn 2.0.27", + "syn 2.0.26", "test-fuzz-internal", "toolchain_find", ] [[package]] name = "test-fuzz-runtime" -version = "4.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491cf4aba9f04a5fa35cd2f69f73e4f390779c864d20a96c357c3be16eb7d501" +checksum = "f5054a92d02b1a95a0120155d20aef49b5c5673ba8a65d6f4ce667c2a6f3146c" dependencies = [ "bincode", "hex", @@ -7120,22 +7059,22 @@ checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -7150,13 +7089,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" dependencies = [ "itoa", - "libc", - "num_threads", "serde", "time-core", "time-macros", @@ -7164,15 +7101,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" dependencies = [ "time-core", ] @@ -7223,12 +7160,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", - "backtrace", "bytes", "libc", "mio", @@ -7236,7 +7172,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -7248,15 +7184,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" dependencies = [ "rustls", "tokio", @@ -7264,9 +7200,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite", @@ -7288,9 +7224,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", @@ -7313,9 +7249,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" dependencies = [ "serde", "serde_spanned", @@ -7334,9 +7270,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" dependencies = [ "indexmap 2.0.0", "serde", @@ -7381,13 +7317,13 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658" dependencies = [ "async-compression", - "base64 0.21.2", - "bitflags 2.3.3", + "base64 0.20.0", + "bitflags 1.3.2", "bytes", "futures-core", "futures-util", @@ -7406,7 +7342,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "uuid 1.4.1", + "uuid 1.3.0", ] [[package]] @@ -7447,20 +7383,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -7502,16 +7438,16 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex", "sharded-slab", - "smallvec 1.11.0", + "smallvec", "thread_local", "tracing", "tracing-core", @@ -7566,7 +7502,7 @@ dependencies = [ "lazy_static", "log", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "thiserror", "tinyvec", "tokio", @@ -7590,7 +7526,7 @@ dependencies = [ "ipnet", "lazy_static", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "thiserror", "tinyvec", "tokio", @@ -7611,7 +7547,7 @@ dependencies = [ "lru-cache", "parking_lot 0.12.1", "resolv-conf", - "smallvec 1.11.0", + "smallvec", "thiserror", "tokio", "tracing", @@ -7626,9 +7562,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "trybuild" -version = "1.0.82" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84e0202ea606ba5ebee8507ab2bfbe89b98551ed9b8f0be198109275cff284b" +checksum = "223fc354447478d08231355617eb8c37affad0e83d33aeac30a8c275786b905a" dependencies = [ "basic-toml", "glob", @@ -7706,9 +7642,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -7767,12 +7703,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.3.0", "percent-encoding", ] @@ -7794,29 +7730,23 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a8922555b9500e3d865caed19330172cd67cbf82203f1a3311d8c305cc9f33" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", "serde", ] [[package]] name = "uuid" -version = "1.4.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.9", ] [[package]] @@ -7827,9 +7757,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vergen" -version = "8.2.4" +version = "8.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc5ad0d9d26b2c49a5ab7da76c3e79d3ee37e7821799f8223fcb8f2f391a2e7" +checksum = "6e03272e388fb78fc79481a493424f78d77be1d55f21bcd314b5a6716e195afe" dependencies = [ "anyhow", "rustversion", @@ -7863,10 +7793,11 @@ dependencies = [ [[package]] name = "want" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ + "log", "try-lock", ] @@ -7890,9 +7821,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -7900,24 +7831,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -7927,38 +7858,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ - "quote 1.0.32", + "quote 1.0.31", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -7966,18 +7897,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.24.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" +checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" dependencies = [ "rustls-webpki", ] [[package]] name = "widestring" -version = "1.0.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" [[package]] name = "wildmatch" @@ -8025,6 +7956,21 @@ dependencies = [ "windows-targets 0.48.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -8159,9 +8105,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.1" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" +checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" dependencies = [ "memchr", ] @@ -8175,16 +8121,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "write16" version = "1.0.0" @@ -8227,9 +8163,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.16" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1" +checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c" [[package]] name = "xmltree" @@ -8265,7 +8201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af46c169923ed7516eef0aa32b56d2651b229f57458ebe46b49ddd6efef5b7a2" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", "synstructure 0.12.6", ] @@ -8286,7 +8222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4eae7c1f7d4b8eafce526bc0771449ddc2f250881ae31c50d22c032b5a1c499" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", "synstructure 0.12.6", ] @@ -8307,8 +8243,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", - "syn 2.0.27", + "quote 1.0.31", + "syn 2.0.26", ] [[package]] @@ -8329,25 +8265,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486558732d5dde10d0f8cb2936507c1bb21bc539d924c949baf5f36a58e51bac" dependencies = [ "proc-macro2 1.0.66", - "quote 1.0.32", + "quote 1.0.31", "syn 1.0.109", "synstructure 0.12.6", ] [[package]] name = "zstd" -version = "0.12.4" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.3+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" dependencies = [ - "zstd-safe", + "zstd-safe 6.0.5+zstd.1.5.4", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", ] [[package]] name = "zstd-safe" -version = "6.0.6" +version = "6.0.5+zstd.1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" dependencies = [ "libc", "zstd-sys", diff --git a/Cargo.toml b/Cargo.toml index 738636e6b42..ff1fe7c89ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,14 +110,12 @@ ethers-middleware = { version = "2.0.8", default-features = false } ## misc bytes = "1.4" tracing = "0.1.0" -tracing-appender = "0.2" thiserror = "1.0.37" serde_json = "1.0.94" serde = { version = "1.0", default-features = false } rand = "0.8.5" strum = "0.25" rayon = "1.7" -itertools = "0.11" ### proc-macros proc-macro2 = "1.0" @@ -134,10 +132,5 @@ futures = "0.3.26" pin-project = "1.0.12" futures-util = "0.3.25" -## json -jsonrpsee = { version = "0.19" } -jsonrpsee-core = { version = "0.19" } -jsonrpsee-types = { version = "0.19" } - ## crypto secp256k1 = { version = "0.27.0", default-features = false, features = ["global-context", "rand-std", "recovery"] } diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 6382057fc1f..89c76a5496e 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -21,7 +21,6 @@ reth-interfaces = { workspace = true, features = ["test-utils", "clap"] } reth-transaction-pool.workspace = true reth-beacon-consensus = { path = "../../crates/consensus/beacon" } reth-auto-seal-consensus = { path = "../../crates/consensus/auto-seal" } -reth-consensus-common = { path = "../../crates/consensus/common" } reth-blockchain-tree = { path = "../../crates/blockchain-tree" } reth-rpc-engine-api = { path = "../../crates/rpc/rpc-engine-api" } reth-rpc-builder = { path = "../../crates/rpc/rpc-builder" } @@ -38,7 +37,6 @@ reth-basic-payload-builder = { path = "../../crates/payload/basic" } reth-discv4 = { path = "../../crates/net/discv4" } reth-metrics.workspace = true reth-prune = { path = "../../crates/prune" } -reth-trie = { path = "../../crates/trie" } # crypto secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] } diff --git a/bin/reth/src/args/rpc_server_args.rs b/bin/reth/src/args/rpc_server_args.rs index 13e9f201673..d05ce42b431 100644 --- a/bin/reth/src/args/rpc_server_args.rs +++ b/bin/reth/src/args/rpc_server_args.rs @@ -1,9 +1,6 @@ //! clap [Args](clap::Args) for RPC related arguments. -use crate::{ - args::GasPriceOracleArgs, - cli::ext::{NoopArgsExt, RethRpcConfig, RethRpcServerArgsExt}, -}; +use crate::args::GasPriceOracleArgs; use clap::{ builder::{PossibleValue, RangedU64ValueParser, TypedValueParser}, Arg, Args, Command, @@ -55,20 +52,20 @@ pub(crate) const RPC_DEFAULT_MAX_CONNECTIONS: u32 = 100; pub(crate) const RPC_DEFAULT_MAX_TRACING_REQUESTS: u32 = 25; /// Parameters for configuring the rpc more granularity via CLI -#[derive(Debug, Args)] +#[derive(Debug, Args, PartialEq, Eq, Default)] #[command(next_help_heading = "RPC")] -pub struct RpcServerArgs { +pub struct RpcServerArgs { /// Enable the HTTP-RPC server #[arg(long, default_value_if("dev", "true", "true"))] pub http: bool, /// Http server address to listen on - #[arg(long = "http.addr", default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))] - pub http_addr: IpAddr, + #[arg(long = "http.addr")] + pub http_addr: Option, /// Http server port to listen on - #[arg(long = "http.port", default_value_t = constants::DEFAULT_HTTP_RPC_PORT)] - pub http_port: u16, + #[arg(long = "http.port")] + pub http_port: Option, /// Rpc Modules to be configured for the HTTP server #[arg(long = "http.api", value_parser = RpcModuleSelectionValueParser::default())] @@ -83,12 +80,12 @@ pub struct RpcServerArgs { pub ws: bool, /// Ws server address to listen on - #[arg(long = "ws.addr", default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))] - pub ws_addr: IpAddr, + #[arg(long = "ws.addr")] + pub ws_addr: Option, /// Ws server port to listen on - #[arg(long = "ws.port", default_value_t = constants::DEFAULT_WS_RPC_PORT)] - pub ws_port: u16, + #[arg(long = "ws.port")] + pub ws_port: Option, /// Origins from which to accept WebSocket requests #[arg(long = "ws.origins", name = "ws.origins")] @@ -107,12 +104,12 @@ pub struct RpcServerArgs { pub ipcpath: Option, /// Auth server address to listen on - #[arg(long = "authrpc.addr", default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))] - pub auth_addr: IpAddr, + #[arg(long = "authrpc.addr")] + pub auth_addr: Option, /// Auth server port to listen on - #[arg(long = "authrpc.port", default_value_t = constants::DEFAULT_AUTH_PORT)] - pub auth_port: u16, + #[arg(long = "authrpc.port")] + pub auth_port: Option, /// Path to a JWT secret to use for authenticated RPC endpoints #[arg(long = "authrpc.jwtsecret", value_name = "PATH", global = true, required = false)] @@ -163,13 +160,9 @@ pub struct RpcServerArgs { /// Maximum number of env cache entries. #[arg(long, default_value_t = DEFAULT_ENV_CACHE_MAX_LEN)] pub env_cache_len: u32, - - /// Additional arguments for rpc. - #[clap(flatten)] - pub ext: Ext, } -impl RpcServerArgs { +impl RpcServerArgs { /// Returns the max request size in bytes. pub fn rpc_max_request_size_bytes(&self) -> u32 { self.rpc_max_request_size * 1024 * 1024 @@ -190,6 +183,21 @@ impl RpcServerArgs { ) } + /// Extracts the [EthConfig] from the args. + pub fn eth_config(&self) -> EthConfig { + EthConfig::default() + .max_tracing_requests(self.rpc_max_tracing_requests) + .rpc_gas_cap(self.rpc_gas_cap) + .gpo_config(self.gas_price_oracle_config()) + } + + /// Convenience function that returns whether ipc is enabled + /// + /// By default IPC is enabled therefor it is enabled if the `ipcdisable` is false. + fn is_ipc_enabled(&self) -> bool { + !self.ipcdisable + } + /// The execution layer and consensus layer clients SHOULD accept a configuration parameter: /// jwt-secret, which designates a file containing the hex-encoded 256 bit secret key to be used /// for verifying/generating JWT tokens. @@ -236,7 +244,7 @@ impl RpcServerArgs { events: Events, engine_api: Engine, jwt_secret: JwtSecret, - ) -> eyre::Result<(RpcServerHandle, AuthServerHandle)> + ) -> Result<(RpcServerHandle, AuthServerHandle), RpcError> where Provider: BlockReaderIdExt + HeaderProvider @@ -258,7 +266,7 @@ impl RpcServerArgs { let module_config = self.transport_rpc_module_config(); debug!(target: "reth::cli", http=?module_config.http(), ws=?module_config.ws(), "Using RPC module config"); - let (mut rpc_modules, auth_module, mut registry) = RpcModuleBuilder::default() + let (rpc_modules, auth_module) = RpcModuleBuilder::default() .with_provider(provider) .with_pool(pool) .with_network(network) @@ -266,9 +274,6 @@ impl RpcServerArgs { .with_executor(executor) .build_with_auth_server(module_config, engine_api); - // apply configured customization - self.ext.extend_rpc_modules(self, &mut registry, &mut rpc_modules)?; - let server_config = self.rpc_server_config(); let launch_rpc = rpc_modules.start_server(server_config).map_ok(|handle| { if let Some(url) = handle.ipc_endpoint() { @@ -290,7 +295,7 @@ impl RpcServerArgs { }); // launch servers concurrently - Ok(futures::future::try_join(launch_rpc, launch_auth).await?) + futures::future::try_join(launch_rpc, launch_auth).await } /// Convenience function for starting a rpc server with configs which extracted from cli args. @@ -351,7 +356,10 @@ impl RpcServerArgs { Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, { - let socket_address = SocketAddr::new(self.auth_addr, self.auth_port); + let socket_address = SocketAddr::new( + self.auth_addr.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)), + self.auth_port.unwrap_or(constants::DEFAULT_AUTH_PORT), + ); reth_rpc_builder::auth::launch( provider, @@ -419,7 +427,10 @@ impl RpcServerArgs { let mut config = RpcServerConfig::default(); if self.http { - let socket_address = SocketAddr::new(self.http_addr, self.http_port); + let socket_address = SocketAddr::new( + self.http_addr.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)), + self.http_port.unwrap_or(constants::DEFAULT_HTTP_RPC_PORT), + ); config = config .with_http_address(socket_address) .with_http(self.http_ws_server_builder()) @@ -428,7 +439,10 @@ impl RpcServerArgs { } if self.ws { - let socket_address = SocketAddr::new(self.ws_addr, self.ws_port); + let socket_address = SocketAddr::new( + self.ws_addr.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)), + self.ws_port.unwrap_or(constants::DEFAULT_WS_RPC_PORT), + ); config = config.with_ws_address(socket_address).with_ws(self.http_ws_server_builder()); } @@ -443,26 +457,15 @@ impl RpcServerArgs { /// Creates the [AuthServerConfig] from cli args. fn auth_server_config(&self, jwt_secret: JwtSecret) -> Result { - let address = SocketAddr::new(self.auth_addr, self.auth_port); + let address = SocketAddr::new( + self.auth_addr.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)), + self.auth_port.unwrap_or(constants::DEFAULT_AUTH_PORT), + ); Ok(AuthServerConfig::builder(jwt_secret).socket_addr(address).build()) } } -impl RethRpcConfig for RpcServerArgs { - fn is_ipc_enabled(&self) -> bool { - // By default IPC is enabled therefor it is enabled if the `ipcdisable` is false. - !self.ipcdisable - } - - fn eth_config(&self) -> EthConfig { - EthConfig::default() - .max_tracing_requests(self.rpc_max_tracing_requests) - .rpc_gas_cap(self.rpc_gas_cap) - .gpo_config(self.gas_price_oracle_config()) - } -} - /// clap value parser for [RpcModuleSelection]. #[derive(Clone, Debug, Default)] #[non_exhaustive] diff --git a/bin/reth/src/args/txpool_args.rs b/bin/reth/src/args/txpool_args.rs index 2edfb20af69..d1bd2326b69 100644 --- a/bin/reth/src/args/txpool_args.rs +++ b/bin/reth/src/args/txpool_args.rs @@ -2,7 +2,7 @@ use clap::Args; use reth_transaction_pool::{ - PoolConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + PoolConfig, SubPoolLimit, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }; @@ -33,10 +33,6 @@ pub struct TxPoolArgs { /// Max number of executable transaction slots guaranteed per account #[arg(long = "txpool.max_account_slots", help_heading = "TxPool", default_value_t = TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER)] pub max_account_slots: usize, - - /// Price bump (in %) for the transaction pool underpriced check. - #[arg(long = "txpool.price_bump", help_heading = "TxPool", default_value_t = DEFAULT_PRICE_BUMP)] - pub price_bump: u128, } impl TxPoolArgs { @@ -56,7 +52,6 @@ impl TxPoolArgs { max_size: self.queued_max_size * 1024 * 1024, }, max_account_slots: self.max_account_slots, - price_bump: self.price_bump, } } } diff --git a/bin/reth/src/cli/mod.rs b/bin/reth/src/cli.rs similarity index 58% rename from bin/reth/src/cli/mod.rs rename to bin/reth/src/cli.rs index 79a1f7b9241..c32b1ae17ed 100644 --- a/bin/reth/src/cli/mod.rs +++ b/bin/reth/src/cli.rs @@ -1,9 +1,6 @@ //! CLI definition and entrypoint to executable use crate::{ - args::utils::genesis_value_parser, - chain, - cli::ext::RethCliExt, - config, db, debug_cmd, + chain, config, db, debug_cmd, dirs::{LogsDir, PlatformPath}, node, p2p, runner::CliRunner, @@ -11,102 +8,45 @@ use crate::{ version::{LONG_VERSION, SHORT_VERSION}, }; use clap::{ArgAction, Args, Parser, Subcommand}; -use reth_primitives::ChainSpec; use reth_tracing::{ tracing::{metadata::LevelFilter, Level, Subscriber}, tracing_subscriber::{filter::Directive, registry::LookupSpan, EnvFilter}, BoxedLayer, FileWorkerGuard, }; -use std::sync::Arc; -pub mod ext; - -/// The main reth cli interface. -/// -/// This is the entrypoint to the executable. -#[derive(Debug, Parser)] -#[command(author, version = SHORT_VERSION, long_version = LONG_VERSION, about = "Reth", long_about = None)] -pub struct Cli { - /// The command to run - #[clap(subcommand)] - command: Commands, - - /// The chain this node is running. - /// - /// Possible values are either a built-in chain or the path to a chain specification file. - /// - /// Built-in chains: - /// - mainnet - /// - goerli - /// - sepolia - #[arg( - long, - value_name = "CHAIN_OR_PATH", - global = true, - verbatim_doc_comment, - default_value = "mainnet", - value_parser = genesis_value_parser, - global = true, - )] - chain: Arc, - - #[clap(flatten)] - logs: Logs, - - #[clap(flatten)] - verbosity: Verbosity, -} - -impl Cli { - /// Execute the configured cli command. - pub fn run(mut self) -> eyre::Result<()> { - // add network name to logs dir - self.logs.log_directory = self.logs.log_directory.join(self.chain.chain.to_string()); - - let _guard = self.init_tracing()?; - - let runner = CliRunner::default(); - match self.command { - Commands::Node(command) => runner.run_command_until_exit(|ctx| command.execute(ctx)), - Commands::Init(command) => runner.run_blocking_until_ctrl_c(command.execute()), - Commands::Import(command) => runner.run_blocking_until_ctrl_c(command.execute()), - Commands::Db(command) => runner.run_blocking_until_ctrl_c(command.execute()), - Commands::Stage(command) => runner.run_blocking_until_ctrl_c(command.execute()), - Commands::P2P(command) => runner.run_until_ctrl_c(command.execute()), - Commands::TestVectors(command) => runner.run_until_ctrl_c(command.execute()), - Commands::Config(command) => runner.run_until_ctrl_c(command.execute()), - Commands::Debug(command) => runner.run_command_until_exit(|ctx| command.execute(ctx)), - } - } - - /// Initializes tracing with the configured options. - /// - /// If file logging is enabled, this function returns a guard that must be kept alive to ensure - /// that all logs are flushed to disk. - pub fn init_tracing(&self) -> eyre::Result> { - let mut layers = vec![reth_tracing::stdout(self.verbosity.directive())]; - let guard = self.logs.layer()?.map(|(layer, guard)| { - layers.push(layer); - guard - }); - - reth_tracing::init(layers); - Ok(guard.flatten()) - } -} - -/// Convenience function for parsing CLI options, set up logging and run the chosen command. -#[inline] +/// Parse CLI options, set up logging and run the chosen command. pub fn run() -> eyre::Result<()> { - Cli::parse().run() + let opt = Cli::parse(); + + let mut layers = vec![reth_tracing::stdout(opt.verbosity.directive())]; + let _guard = opt.logs.layer()?.map(|(layer, guard)| { + layers.push(layer); + guard + }); + + reth_tracing::init(layers); + + let runner = CliRunner::default(); + + match opt.command { + Commands::Node(command) => runner.run_command_until_exit(|ctx| command.execute(ctx)), + Commands::Init(command) => runner.run_blocking_until_ctrl_c(command.execute()), + Commands::Import(command) => runner.run_blocking_until_ctrl_c(command.execute()), + Commands::Db(command) => runner.run_blocking_until_ctrl_c(command.execute()), + Commands::Stage(command) => runner.run_blocking_until_ctrl_c(command.execute()), + Commands::P2P(command) => runner.run_until_ctrl_c(command.execute()), + Commands::TestVectors(command) => runner.run_until_ctrl_c(command.execute()), + Commands::Config(command) => runner.run_until_ctrl_c(command.execute()), + Commands::Debug(command) => runner.run_command_until_exit(|ctx| command.execute(ctx)), + } } /// Commands to be executed #[derive(Debug, Subcommand)] -pub enum Commands { +pub enum Commands { /// Start the node #[command(name = "node")] - Node(node::Command), + Node(node::Command), /// Initialize the database from a genesis file. #[command(name = "init")] Init(chain::InitCommand), @@ -133,6 +73,20 @@ pub enum Commands { Debug(debug_cmd::Command), } +#[derive(Debug, Parser)] +#[command(author, version = SHORT_VERSION, long_version = LONG_VERSION, about = "Reth", long_about = None)] +struct Cli { + /// The command to run + #[clap(subcommand)] + command: Commands, + + #[clap(flatten)] + logs: Logs, + + #[clap(flatten)] + verbosity: Verbosity, +} + /// The log configuration. #[derive(Debug, Args)] #[command(next_help_heading = "Logging")] @@ -229,9 +183,9 @@ mod tests { /// runtime #[test] fn test_parse_help_all_subcommands() { - let reth = Cli::<()>::command(); + let reth = Cli::command(); for sub_command in reth.get_subcommands() { - let err = Cli::<()>::try_parse_from(["reth", sub_command.get_name(), "--help"]) + let err = Cli::try_parse_from(["reth", sub_command.get_name(), "--help"]) .err() .unwrap_or_else(|| { panic!("Failed to parse help message {}", sub_command.get_name()) @@ -242,21 +196,4 @@ mod tests { assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); } } - - /// Tests that the log directory is parsed correctly. It's always tied to the specific chain's - /// name - #[test] - fn parse_logs_path() { - let mut reth = Cli::<()>::try_parse_from(["reth", "node", "--log.persistent"]).unwrap(); - reth.logs.log_directory = reth.logs.log_directory.join(reth.chain.chain.to_string()); - let log_dir = reth.logs.log_directory; - assert!(log_dir.as_ref().ends_with("reth/logs/mainnet"), "{:?}", log_dir); - - let mut reth = - Cli::<()>::try_parse_from(["reth", "node", "--chain", "sepolia", "--log.persistent"]) - .unwrap(); - reth.logs.log_directory = reth.logs.log_directory.join(reth.chain.chain.to_string()); - let log_dir = reth.logs.log_directory; - assert!(log_dir.as_ref().ends_with("reth/logs/sepolia"), "{:?}", log_dir); - } } diff --git a/bin/reth/src/cli/ext.rs b/bin/reth/src/cli/ext.rs deleted file mode 100644 index 11db2ca347d..00000000000 --- a/bin/reth/src/cli/ext.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! Support for integrating customizations into the CLI. - -use clap::Args; -use reth_network_api::{NetworkInfo, Peers}; -use reth_provider::{ - BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, - StateProviderFactory, -}; -use reth_rpc_builder::{EthConfig, RethModuleRegistry, TransportRpcModules}; -use reth_tasks::TaskSpawner; -use reth_transaction_pool::TransactionPool; -use std::fmt; - -/// A trait that allows for extending parts of the CLI with additional functionality. -pub trait RethCliExt { - /// Extends the rpc arguments for the node - type RpcExt: RethRpcServerArgsExt; -} - -impl RethCliExt for () { - type RpcExt = NoopArgsExt; -} - -/// An [Args] extension that does nothing. -#[derive(Debug, Clone, Copy, Default, Args)] -pub struct NoopArgsExt; - -/// A trait that provides configured RPC server. -/// -/// This provides all basic config values for the RPC server and is implemented by the -/// [RpcServerArgs](crate::args::RpcServerArgs) type. -pub trait RethRpcConfig { - /// Returns whether ipc is enabled. - fn is_ipc_enabled(&self) -> bool; - - /// The configured ethereum RPC settings. - fn eth_config(&self) -> EthConfig; - - // TODO extract more functions from RpcServerArgs -} - -/// A trait that allows further customization of the RPC server via CLI. -pub trait RethRpcServerArgsExt: fmt::Debug + clap::Args { - /// Allows for registering additional RPC modules for the transports. - /// - /// This is expected to call the merge functions of [TransportRpcModules], for example - /// [TransportRpcModules::merge_configured] - fn extend_rpc_modules( - &self, - config: &Conf, - registry: &mut RethModuleRegistry, - modules: &mut TransportRpcModules<()>, - ) -> eyre::Result<()> - where - Conf: RethRpcConfig, - Provider: BlockReaderIdExt - + StateProviderFactory - + EvmEnvProvider - + ChainSpecProvider - + ChangeSetReader - + Clone - + Unpin - + 'static, - Pool: TransactionPool + Clone + 'static, - Network: NetworkInfo + Peers + Clone + 'static, - Tasks: TaskSpawner + Clone + 'static, - Events: CanonStateSubscriptions + Clone + 'static; -} - -impl RethRpcServerArgsExt for NoopArgsExt { - fn extend_rpc_modules( - &self, - _config: &Conf, - _registry: &mut RethModuleRegistry, - _modules: &mut TransportRpcModules<()>, - ) -> eyre::Result<()> - where - Conf: RethRpcConfig, - Provider: BlockReaderIdExt - + StateProviderFactory - + EvmEnvProvider - + ChainSpecProvider - + ChangeSetReader - + Clone - + Unpin - + 'static, - Pool: TransactionPool + Clone + 'static, - Network: NetworkInfo + Peers + Clone + 'static, - Tasks: TaskSpawner + Clone + 'static, - Events: CanonStateSubscriptions + Clone + 'static, - { - Ok(()) - } -} diff --git a/bin/reth/src/db/clear.rs b/bin/reth/src/db/clear.rs deleted file mode 100644 index 0bd816db8b4..00000000000 --- a/bin/reth/src/db/clear.rs +++ /dev/null @@ -1,41 +0,0 @@ -use clap::Parser; - -use reth_db::{ - database::Database, - table::Table, - transaction::{DbTx, DbTxMut}, - TableViewer, Tables, -}; - -/// The arguments for the `reth db clear` command -#[derive(Parser, Debug)] -pub struct Command { - /// Table name - #[arg()] - pub table: Tables, -} - -impl Command { - /// Execute `db clear` command - pub fn execute(self, db: &DB) -> eyre::Result<()> { - self.table.view(&ClearViewer { db })?; - - Ok(()) - } -} - -struct ClearViewer<'a, DB: Database> { - db: &'a DB, -} - -impl TableViewer<()> for ClearViewer<'_, DB> { - type Error = eyre::Report; - - fn view(&self) -> Result<(), Self::Error> { - let tx = self.db.tx_mut()?; - tx.clear::()?; - tx.commit()?; - - Ok(()) - } -} diff --git a/bin/reth/src/db/diff.rs b/bin/reth/src/db/diff.rs deleted file mode 100644 index b7527b0ab18..00000000000 --- a/bin/reth/src/db/diff.rs +++ /dev/null @@ -1,410 +0,0 @@ -use std::{ - collections::HashMap, - fmt::Debug, - fs::{self, File}, - hash::Hash, - io::Write, - path::{Path, PathBuf}, -}; - -use crate::{ - args::DatabaseArgs, - dirs::{DataDirPath, PlatformPath}, - utils::DbTool, -}; -use clap::Parser; - -use reth_db::{ - cursor::DbCursorRO, database::Database, open_db_read_only, table::Table, transaction::DbTx, - AccountChangeSet, AccountHistory, AccountsTrie, BlockBodyIndices, BlockOmmers, - BlockWithdrawals, Bytecodes, CanonicalHeaders, DatabaseEnvRO, HashedAccount, HashedStorage, - HeaderNumbers, HeaderTD, Headers, PlainAccountState, PlainStorageState, PruneCheckpoints, - Receipts, StorageChangeSet, StorageHistory, StoragesTrie, SyncStage, SyncStageProgress, Tables, - TransactionBlock, Transactions, TxHashNumber, TxSenders, -}; -use tracing::info; - -#[derive(Parser, Debug)] -/// The arguments for the `reth db diff` command -pub struct Command { - /// The path to the data dir for all reth files and subdirectories. - #[arg(long, verbatim_doc_comment)] - secondary_datadir: PlatformPath, - - /// Arguments for the second database - #[clap(flatten)] - second_db: DatabaseArgs, - - /// The table name to diff. If not specified, all tables are diffed. - #[arg(long, verbatim_doc_comment)] - table: Option, - - /// The output directory for the diff report. - #[arg(long, verbatim_doc_comment)] - output: PlatformPath, -} - -impl Command { - /// Execute the `db diff` command. - /// - /// This first opens the `db/` folder from the secondary datadir, where the second database is - /// opened read-only. - /// - /// The tool will then iterate through all key-value pairs for the primary and secondary - /// databases. The value for each key will be compared with its corresponding value in the - /// other database. If the values are different, a discrepancy will be recorded in-memory. If - /// one key is present in one database but not the other, this will be recorded as an "extra - /// element" for that database. - /// - /// The discrepancies and extra elements, along with a brief summary of the diff results are - /// then written to a file in the output directory. - pub fn execute(self, tool: &DbTool<'_, DatabaseEnvRO>) -> eyre::Result<()> { - // open second db - let second_db_path: PathBuf = self.secondary_datadir.join("db").into(); - let second_db = open_db_read_only(&second_db_path, self.second_db.log_level)?; - - let tables = match self.table { - Some(table) => vec![table], - None => Tables::ALL.to_vec(), - }; - - for table in tables { - let primary_tx = tool.db.tx()?; - let secondary_tx = second_db.tx()?; - - let output_dir = self.output.clone(); - match table { - Tables::CanonicalHeaders => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HeaderTD => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::HeaderNumbers => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Headers => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::BlockBodyIndices => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::BlockOmmers => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::BlockWithdrawals => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TransactionBlock => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Transactions => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TxHashNumber => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Receipts => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::PlainAccountState => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::PlainStorageState => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Bytecodes => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::AccountHistory => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StorageHistory => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::AccountChangeSet => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StorageChangeSet => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HashedAccount => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HashedStorage => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::AccountsTrie => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StoragesTrie => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TxSenders => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::SyncStage => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::SyncStageProgress => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::PruneCheckpoints => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - }; - } - - Ok(()) - } -} - -/// Find diffs for a table, then analyzing the result -fn find_diffs<'a, T: Table>( - primary_tx: impl DbTx<'a>, - secondary_tx: impl DbTx<'a>, - output_dir: impl AsRef, -) -> eyre::Result<()> -where - T::Key: Hash, - T::Value: PartialEq, -{ - let table_name = T::NAME; - - info!("Analyzing table {table_name}..."); - let result = find_diffs_advanced::(&primary_tx, &secondary_tx)?; - info!("Done analyzing table {table_name}!"); - - // Pretty info summary header: newline then header - info!(""); - info!("Diff results for {table_name}:"); - - // create directory and open file - fs::create_dir_all(output_dir.as_ref())?; - let file_name = format!("{table_name}.txt"); - let mut file = File::create(output_dir.as_ref().join(file_name.clone()))?; - - // analyze the result and print some stats - let discrepancies = result.discrepancies.len(); - let extra_elements = result.extra_elements.len(); - - // Make a pretty summary header for the table - writeln!(file, "Diff results for {table_name}")?; - - if discrepancies > 0 { - // write to file - writeln!(file, "Found {discrepancies} discrepancies in table {table_name}")?; - - // also print to info - info!("Found {discrepancies} discrepancies in table {table_name}"); - } else { - // write to file - writeln!(file, "No discrepancies found in table {table_name}")?; - - // also print to info - info!("No discrepancies found in table {table_name}"); - } - - if extra_elements > 0 { - // write to file - writeln!(file, "Found {extra_elements} extra elements in table {table_name}")?; - - // also print to info - info!("Found {extra_elements} extra elements in table {table_name}"); - } else { - writeln!(file, "No extra elements found in table {table_name}")?; - - // also print to info - info!("No extra elements found in table {table_name}"); - } - - info!("Writing diff results for {table_name} to {file_name}..."); - - if discrepancies > 0 { - writeln!(file, "Discrepancies:")?; - } - - for discrepancy in result.discrepancies.values() { - writeln!(file, "{discrepancy:?}")?; - } - - if extra_elements > 0 { - writeln!(file, "Extra elements:")?; - } - - for extra_element in result.extra_elements.values() { - writeln!(file, "{extra_element:?}")?; - } - - let full_file_name = output_dir.as_ref().join(file_name); - info!("Done writing diff results for {table_name} to {}", full_file_name.display()); - Ok(()) -} - -/// This diff algorithm is slightly different, it will walk _each_ table, cross-checking for the -/// element in the other table. -fn find_diffs_advanced<'a, T: Table>( - primary_tx: &impl DbTx<'a>, - secondary_tx: &impl DbTx<'a>, -) -> eyre::Result> -where - T::Value: PartialEq, - T::Key: Hash, -{ - // initialize the zipped walker - let mut primary_zip_cursor = - primary_tx.cursor_read::().expect("Was not able to obtain a cursor."); - let primary_walker = primary_zip_cursor.walk(None)?; - - let mut secondary_zip_cursor = - secondary_tx.cursor_read::().expect("Was not able to obtain a cursor."); - let secondary_walker = secondary_zip_cursor.walk(None)?; - let zipped_cursor = primary_walker.zip(secondary_walker); - - // initialize the cursors for seeking when we are cross checking elements - let mut primary_cursor = - primary_tx.cursor_read::().expect("Was not able to obtain a cursor."); - - let mut secondary_cursor = - secondary_tx.cursor_read::().expect("Was not able to obtain a cursor."); - - let mut result = TableDiffResult::::default(); - - // this loop will walk both tables, cross-checking for the element in the other table. - // it basically just loops through both tables at the same time. if the keys are different, it - // will check each key in the other table. if the keys are the same, it will compare the - // values - for (primary_entry, secondary_entry) in zipped_cursor { - let (primary_key, primary_value) = primary_entry?; - let (secondary_key, secondary_value) = secondary_entry?; - - if primary_key != secondary_key { - // if the keys are different, we need to check if the key is in the other table - let crossed_secondary = - secondary_cursor.seek_exact(primary_key.clone())?.map(|(_, value)| value); - result.try_push_discrepancy( - primary_key.clone(), - Some(primary_value), - crossed_secondary, - ); - - // now do the same for the primary table - let crossed_primary = - primary_cursor.seek_exact(secondary_key.clone())?.map(|(_, value)| value); - result.try_push_discrepancy( - secondary_key.clone(), - crossed_primary, - Some(secondary_value), - ); - } else { - // the keys are the same, so we need to compare the values - result.try_push_discrepancy(primary_key, Some(primary_value), Some(secondary_value)); - } - } - - Ok(result) -} - -/// Includes a table element between two databases with the same key, but different values -#[derive(Debug)] -struct TableDiffElement { - /// The key for the element - key: T::Key, - - /// The element from the first table - #[allow(dead_code)] - first: T::Value, - - /// The element from the second table - #[allow(dead_code)] - second: T::Value, -} - -/// The diff result for an entire table. If the tables had the same number of elements, there will -/// be no extra elements. -struct TableDiffResult -where - T::Key: Hash, -{ - /// All elements of the database that are different - discrepancies: HashMap>, - - /// Any extra elements, and the table they are in - extra_elements: HashMap>, -} - -impl Default for TableDiffResult -where - T: Table, - T::Key: Hash, -{ - fn default() -> Self { - Self { discrepancies: HashMap::new(), extra_elements: HashMap::new() } - } -} - -impl TableDiffResult -where - T::Key: Hash, -{ - /// Push a diff result into the discrepancies set. - fn push_discrepancy(&mut self, discrepancy: TableDiffElement) { - self.discrepancies.insert(discrepancy.key.clone(), discrepancy); - } - - /// Push an extra element into the extra elements set. - fn push_extra_element(&mut self, element: ExtraTableElement) { - self.extra_elements.insert(element.key().clone(), element); - } -} - -impl TableDiffResult -where - T: Table, - T::Key: Hash, - T::Value: PartialEq, -{ - /// Try to push a diff result into the discrepancy set, only pushing if the given elements are - /// different, and the discrepancy does not exist anywhere already. - fn try_push_discrepancy( - &mut self, - key: T::Key, - first: Option, - second: Option, - ) { - // do not bother comparing if the key is already in the discrepancies map - if self.discrepancies.contains_key(&key) { - return - } - - // do not bother comparing if the key is already in the extra elements map - if self.extra_elements.contains_key(&key) { - return - } - - match (first, second) { - (Some(first), Some(second)) => { - if first != second { - self.push_discrepancy(TableDiffElement { key, first, second }); - } - } - (Some(first), None) => { - self.push_extra_element(ExtraTableElement::First { key, value: first }); - } - (None, Some(second)) => { - self.push_extra_element(ExtraTableElement::Second { key, value: second }); - } - (None, None) => {} - } - } -} - -/// A single extra element from a table -#[derive(Debug)] -enum ExtraTableElement { - /// The extra element that is in the first table - #[allow(dead_code)] - First { key: T::Key, value: T::Value }, - - /// The extra element that is in the second table - #[allow(dead_code)] - Second { key: T::Key, value: T::Value }, -} - -impl ExtraTableElement { - /// Return the key for the extra element - fn key(&self) -> &T::Key { - match self { - Self::First { key, .. } => key, - Self::Second { key, .. } => key, - } - } -} diff --git a/bin/reth/src/db/mod.rs b/bin/reth/src/db/mod.rs index a56ff9d9a1f..4670683c43d 100644 --- a/bin/reth/src/db/mod.rs +++ b/bin/reth/src/db/mod.rs @@ -17,8 +17,6 @@ use reth_db::{ use reth_primitives::ChainSpec; use std::sync::Arc; -mod clear; -mod diff; mod get; mod list; /// DB List TUI @@ -69,14 +67,10 @@ pub enum Subcommands { Stats, /// Lists the contents of a table List(list::Command), - /// Create a diff between two database tables or two entire databases. - Diff(diff::Command), /// Gets the content of a table for the given key Get(get::Command), /// Deletes all database entries Drop, - /// Deletes all table entries - Clear(clear::Command), /// Lists current and local database versions Version, /// Returns the full database path @@ -168,11 +162,6 @@ impl Command { let tool = DbTool::new(&db, self.chain.clone())?; command.execute(&tool)?; } - Subcommands::Diff(command) => { - let db = open_db_read_only(&db_path, self.db.log_level)?; - let tool = DbTool::new(&db, self.chain.clone())?; - command.execute(&tool)?; - } Subcommands::Get(command) => { let db = open_db_read_only(&db_path, self.db.log_level)?; let tool = DbTool::new(&db, self.chain.clone())?; @@ -183,10 +172,6 @@ impl Command { let mut tool = DbTool::new(&db, self.chain.clone())?; tool.drop(db_path)?; } - Subcommands::Clear(command) => { - let db = open_db(&db_path, self.db.log_level)?; - command.execute(&db)?; - } Subcommands::Version => { let local_db_version = match get_db_version(&db_path) { Ok(version) => Some(version), diff --git a/bin/reth/src/debug_cmd/execution.rs b/bin/reth/src/debug_cmd/execution.rs index 82de9e055f4..88481b1cc14 100644 --- a/bin/reth/src/debug_cmd/execution.rs +++ b/bin/reth/src/debug_cmd/execution.rs @@ -42,7 +42,7 @@ use std::{ use tokio::sync::watch; use tracing::*; -/// `reth debug execution` command +/// `reth execution-debug` command #[derive(Debug, Parser)] pub struct Command { /// The path to the data dir for all reth files and subdirectories. diff --git a/bin/reth/src/debug_cmd/in_memory_merkle.rs b/bin/reth/src/debug_cmd/in_memory_merkle.rs deleted file mode 100644 index 701b2196fa5..00000000000 --- a/bin/reth/src/debug_cmd/in_memory_merkle.rs +++ /dev/null @@ -1,257 +0,0 @@ -//! Command for debugging in-memory merkle trie calculation. -use crate::{ - args::{get_secret_key, utils::genesis_value_parser, DatabaseArgs, NetworkArgs}, - dirs::{DataDirPath, MaybePlatformPath}, - runner::CliContext, - utils::{get_single_body, get_single_header}, -}; -use backon::{ConstantBuilder, Retryable}; -use clap::Parser; -use reth_config::Config; -use reth_db::{init_db, DatabaseEnv}; -use reth_discv4::DEFAULT_DISCOVERY_PORT; -use reth_network::NetworkHandle; -use reth_network_api::NetworkInfo; -use reth_primitives::{fs, stage::StageId, BlockHashOrNumber, ChainSpec}; -use reth_provider::{ - AccountExtReader, BlockExecutor, BlockWriter, ExecutorFactory, HashingWriter, HeaderProvider, - LatestStateProviderRef, ProviderFactory, StageCheckpointReader, StorageReader, -}; -use reth_tasks::TaskExecutor; -use reth_trie::{hashed_cursor::HashedPostStateCursorFactory, updates::TrieKey, StateRoot}; -use std::{ - net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - path::PathBuf, - sync::Arc, -}; -use tracing::*; - -/// `reth debug in-memory-merkle` command -/// This debug routine requires that the node is positioned at the block before the target. -/// The script will then download the block from p2p network and attempt to calculate and verify -/// merkle root for it. -#[derive(Debug, Parser)] -pub struct Command { - /// The path to the data dir for all reth files and subdirectories. - /// - /// Defaults to the OS-specific data directory: - /// - /// - Linux: `$XDG_DATA_HOME/reth/` or `$HOME/.local/share/reth/` - /// - Windows: `{FOLDERID_RoamingAppData}/reth/` - /// - macOS: `$HOME/Library/Application Support/reth/` - #[arg(long, value_name = "DATA_DIR", verbatim_doc_comment, default_value_t)] - datadir: MaybePlatformPath, - - /// The chain this node is running. - /// - /// Possible values are either a built-in chain or the path to a chain specification file. - /// - /// Built-in chains: - /// - mainnet - /// - goerli - /// - sepolia - #[arg( - long, - value_name = "CHAIN_OR_PATH", - verbatim_doc_comment, - default_value = "mainnet", - value_parser = genesis_value_parser - )] - chain: Arc, - - #[clap(flatten)] - db: DatabaseArgs, - - #[clap(flatten)] - network: NetworkArgs, - - /// The number of retries per request - #[arg(long, default_value = "5")] - retries: usize, - - /// The depth after which we should start comparing branch nodes - #[arg(long)] - skip_node_depth: Option, -} - -impl Command { - async fn build_network( - &self, - config: &Config, - task_executor: TaskExecutor, - db: Arc, - network_secret_path: PathBuf, - default_peers_path: PathBuf, - ) -> eyre::Result { - let secret_key = get_secret_key(&network_secret_path)?; - let network = self - .network - .network_config(config, self.chain.clone(), secret_key, default_peers_path) - .with_task_executor(Box::new(task_executor)) - .listener_addr(SocketAddr::V4(SocketAddrV4::new( - Ipv4Addr::UNSPECIFIED, - self.network.port.unwrap_or(DEFAULT_DISCOVERY_PORT), - ))) - .discovery_addr(SocketAddr::V4(SocketAddrV4::new( - Ipv4Addr::UNSPECIFIED, - self.network.discovery.port.unwrap_or(DEFAULT_DISCOVERY_PORT), - ))) - .build(ProviderFactory::new(db, self.chain.clone())) - .start_network() - .await?; - info!(target: "reth::cli", peer_id = %network.peer_id(), local_addr = %network.local_addr(), "Connected to P2P network"); - debug!(target: "reth::cli", peer_id = ?network.peer_id(), "Full peer ID"); - Ok(network) - } - - /// Execute `debug in-memory-merkle` command - pub async fn execute(self, ctx: CliContext) -> eyre::Result<()> { - let config = Config::default(); - - // add network name to data dir - let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain); - let db_path = data_dir.db_path(); - fs::create_dir_all(&db_path)?; - - // initialize the database - let db = Arc::new(init_db(db_path, self.db.log_level)?); - let factory = ProviderFactory::new(&db, self.chain.clone()); - let provider = factory.provider()?; - - // Look up merkle checkpoint - let merkle_checkpoint = provider - .get_stage_checkpoint(StageId::MerkleExecute)? - .expect("merkle checkpoint exists"); - - let merkle_block_number = merkle_checkpoint.block_number; - - // Configure and build network - let network_secret_path = - self.network.p2p_secret_key.clone().unwrap_or_else(|| data_dir.p2p_secret_path()); - let network = self - .build_network( - &config, - ctx.task_executor.clone(), - db.clone(), - network_secret_path, - data_dir.known_peers_path(), - ) - .await?; - - let target_block_number = merkle_block_number + 1; - - info!(target: "reth::cli", target_block_number, "Downloading full block"); - let fetch_client = network.fetch_client().await?; - - let retries = self.retries.max(1); - let backoff = ConstantBuilder::default().with_max_times(retries); - - let client = fetch_client.clone(); - let header = (move || { - get_single_header(client.clone(), BlockHashOrNumber::Number(target_block_number)) - }) - .retry(&backoff) - .notify(|err, _| warn!(target: "reth::cli", "Error requesting header: {err}. Retrying...")) - .await?; - - let client = fetch_client.clone(); - let chain = Arc::clone(&self.chain); - let block = (move || get_single_body(client.clone(), Arc::clone(&chain), header.clone())) - .retry(&backoff) - .notify( - |err, _| warn!(target: "reth::cli", "Error requesting body: {err}. Retrying..."), - ) - .await?; - - let executor_factory = reth_revm::Factory::new(self.chain.clone()); - let mut executor = executor_factory.with_sp(LatestStateProviderRef::new(provider.tx_ref())); - - let merkle_block_td = - provider.header_td_by_number(merkle_block_number)?.unwrap_or_default(); - let block_state = executor.execute_and_verify_receipt( - &block.clone().unseal(), - merkle_block_td + block.difficulty, - None, - )?; - - // Unpacked `PostState::state_root_slow` function - let hashed_post_state = block_state.hash_state_slow().sorted(); - let (account_prefix_set, storage_prefix_set) = hashed_post_state.construct_prefix_sets(); - let tx = provider.tx_ref(); - let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, &hashed_post_state); - let (in_memory_state_root, in_memory_updates) = StateRoot::new(tx) - .with_hashed_cursor_factory(&hashed_cursor_factory) - .with_changed_account_prefixes(account_prefix_set) - .with_changed_storage_prefixes(storage_prefix_set) - .root_with_updates()?; - - if in_memory_state_root == block.state_root { - info!(target: "reth::cli", state_root = ?in_memory_state_root, "Computed in-memory state root matches"); - return Ok(()) - } - - let provider_rw = factory.provider_rw()?; - - // Insert block, state and hashes - provider_rw.insert_block(block.clone(), None)?; - block_state.write_to_db(provider_rw.tx_ref(), block.number)?; - let storage_lists = provider_rw.changed_storages_with_range(block.number..=block.number)?; - let storages = provider_rw.plainstate_storages(storage_lists)?; - provider_rw.insert_storage_for_hashing(storages)?; - let account_lists = provider_rw.changed_accounts_with_range(block.number..=block.number)?; - let accounts = provider_rw.basic_accounts(account_lists)?; - provider_rw.insert_account_for_hashing(accounts)?; - - let (state_root, incremental_trie_updates) = StateRoot::incremental_root_with_updates( - provider_rw.tx_ref(), - block.number..=block.number, - )?; - if state_root != block.state_root { - eyre::bail!( - "Computed incremental state root mismatch. Expected: {:?}. Got: {:?}", - block.state_root, - state_root - ); - } - - // Compare updates - let mut in_mem_mismatched = Vec::new(); - let mut incremental_mismatched = Vec::new(); - let mut in_mem_updates_iter = in_memory_updates.into_iter().peekable(); - let mut incremental_updates_iter = incremental_trie_updates.into_iter().peekable(); - - while in_mem_updates_iter.peek().is_some() || incremental_updates_iter.peek().is_some() { - match (in_mem_updates_iter.next(), incremental_updates_iter.next()) { - (Some(in_mem), Some(incr)) => { - pretty_assertions::assert_eq!(in_mem.0, incr.0, "Nibbles don't match"); - if in_mem.1 != incr.1 && - matches!(in_mem.0, TrieKey::AccountNode(ref nibbles) if nibbles.inner.len() > self.skip_node_depth.unwrap_or_default()) - { - in_mem_mismatched.push(in_mem); - incremental_mismatched.push(incr); - } - } - (Some(in_mem), None) => { - warn!(target: "reth::cli", next = ?in_mem, "In-memory trie updates have more entries"); - } - (None, Some(incr)) => { - tracing::warn!(target: "reth::cli", next = ?incr, "Incremental trie updates have more entries"); - } - (None, None) => { - tracing::info!(target: "reth::cli", "Exhausted all trie updates entries"); - } - } - } - - pretty_assertions::assert_eq!( - incremental_mismatched, - in_mem_mismatched, - "Mismatched trie updates" - ); - - // Drop without comitting. - drop(provider_rw); - - Ok(()) - } -} diff --git a/bin/reth/src/debug_cmd/mod.rs b/bin/reth/src/debug_cmd/mod.rs index e624307f68c..463c423508b 100644 --- a/bin/reth/src/debug_cmd/mod.rs +++ b/bin/reth/src/debug_cmd/mod.rs @@ -4,7 +4,6 @@ use clap::{Parser, Subcommand}; use crate::runner::CliContext; mod execution; -mod in_memory_merkle; mod merkle; /// `reth debug` command @@ -21,8 +20,6 @@ pub enum Subcommands { Execution(execution::Command), /// Debug the clean & incremental state root calculations. Merkle(merkle::Command), - /// Debug in-memory state root calculation. - InMemoryMerkle(in_memory_merkle::Command), } impl Command { @@ -31,7 +28,6 @@ impl Command { match self.command { Subcommands::Execution(command) => command.execute(ctx).await, Subcommands::Merkle(command) => command.execute().await, - Subcommands::InMemoryMerkle(command) => command.execute(ctx).await, } } } diff --git a/bin/reth/src/dirs.rs b/bin/reth/src/dirs.rs index 3305e8ab713..796377b6a16 100644 --- a/bin/reth/src/dirs.rs +++ b/bin/reth/src/dirs.rs @@ -171,11 +171,6 @@ impl PlatformPath { let platform_path = PlatformPath::(path, std::marker::PhantomData); ChainPath::new(platform_path, chain) } - - /// Map the inner path to a new type `T`. - pub fn map_to(&self) -> PlatformPath { - PlatformPath(self.0.clone(), std::marker::PhantomData) - } } /// An Optional wrapper type around [PlatformPath]. diff --git a/bin/reth/src/init.rs b/bin/reth/src/init.rs index 33eb2d5c336..4c45edbe25b 100644 --- a/bin/reth/src/init.rs +++ b/bin/reth/src/init.rs @@ -269,7 +269,7 @@ mod tests { ..Default::default() }, hardforks: BTreeMap::default(), - fork_timestamps: ForkTimestamps::default(), + fork_timestamps: ForkTimestamps { shanghai: None }, genesis_hash: None, paris_block_and_final_difficulty: None, #[cfg(feature = "optimism")] diff --git a/bin/reth/src/node/events.rs b/bin/reth/src/node/events.rs index cc8fe657b54..4f0c673e097 100644 --- a/bin/reth/src/node/events.rs +++ b/bin/reth/src/node/events.rs @@ -290,10 +290,9 @@ impl Eta { let elapsed = last_checkpoint_time.elapsed(); let per_second = processed_since_last as f64 / elapsed.as_secs_f64(); - self.eta = Duration::try_from_secs_f64( - ((current.total - current.processed) as f64) / per_second, - ) - .ok(); + self.eta = Some(Duration::from_secs_f64( + (current.total - current.processed) as f64 / per_second, + )); } self.last_checkpoint = current; diff --git a/bin/reth/src/node/mod.rs b/bin/reth/src/node/mod.rs index 386e365aa00..561e3c004ee 100644 --- a/bin/reth/src/node/mod.rs +++ b/bin/reth/src/node/mod.rs @@ -2,16 +2,9 @@ //! //! Starts the client use crate::{ - args::{ - get_secret_key, - utils::{genesis_value_parser, parse_socket_address}, - DatabaseArgs, DebugArgs, DevArgs, NetworkArgs, PayloadBuilderArgs, RpcServerArgs, - TxPoolArgs, - }, - cli::ext::RethCliExt, - dirs::{DataDirPath, MaybePlatformPath}, + args::{get_secret_key, DebugArgs, DevArgs, NetworkArgs, RpcServerArgs, TxPoolArgs}, + dirs::DataDirPath, init::init_genesis, - node::cl_events::ConsensusLayerHealthEvents, prometheus_exporter, runner::CliContext, utils::get_single_header, @@ -39,30 +32,26 @@ use reth_interfaces::{ p2p::{ bodies::{client::BodiesClient, downloader::BodyDownloader}, either::EitherDownloader, - headers::{client::HeadersClient, downloader::HeaderDownloader}, + headers::downloader::HeaderDownloader, }, }; use reth_network::{error::NetworkError, NetworkConfig, NetworkHandle, NetworkManager}; use reth_network_api::NetworkInfo; -use reth_payload_builder::PayloadBuilderService; use reth_primitives::{ - stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, DisplayHardforks, Head, - SealedHeader, H256, + stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, Head, SealedHeader, H256, }; use reth_provider::{ - providers::BlockchainProvider, BlockHashReader, BlockReader, CanonStateSubscriptions, - HeaderProvider, ProviderFactory, StageCheckpointReader, + BlockHashReader, BlockReader, CanonStateSubscriptions, HeaderProvider, ProviderFactory, + StageCheckpointReader, }; -use reth_prune::BatchSizes; use reth_revm::Factory; use reth_revm_inspectors::stack::Hook; use reth_rpc_engine_api::EngineApi; use reth_stages::{ prelude::*, stages::{ - AccountHashingStage, ExecutionStage, ExecutionStageThresholds, HeaderSyncMode, - IndexAccountHistoryStage, IndexStorageHistoryStage, MerkleStage, SenderRecoveryStage, - StorageHashingStage, TotalDifficultyStage, TransactionLookupStage, + ExecutionStage, ExecutionStageThresholds, HeaderSyncMode, SenderRecoveryStage, + TotalDifficultyStage, }, MetricEventsSender, MetricsListener, }; @@ -77,12 +66,30 @@ use std::{ use tokio::sync::{mpsc::unbounded_channel, oneshot, watch}; use tracing::*; +use crate::{ + args::{ + utils::{genesis_value_parser, parse_socket_address}, + DatabaseArgs, PayloadBuilderArgs, + }, + dirs::MaybePlatformPath, + node::cl_events::ConsensusLayerHealthEvents, +}; +use reth_interfaces::p2p::headers::client::HeadersClient; +use reth_payload_builder::PayloadBuilderService; +use reth_primitives::DisplayHardforks; +use reth_provider::providers::BlockchainProvider; +use reth_prune::BatchSizes; +use reth_stages::stages::{ + AccountHashingStage, IndexAccountHistoryStage, IndexStorageHistoryStage, MerkleStage, + StorageHashingStage, TransactionLookupStage, +}; + pub mod cl_events; pub mod events; /// Start the node #[derive(Debug, Parser)] -pub struct Command { +pub struct Command { /// The path to the data dir for all reth files and subdirectories. /// /// Defaults to the OS-specific data directory: @@ -127,7 +134,7 @@ pub struct Command { network: NetworkArgs, #[clap(flatten)] - rpc: RpcServerArgs, + rpc: RpcServerArgs, #[clap(flatten)] txpool: TxPoolArgs, @@ -757,17 +764,12 @@ impl Command { .set(AccountHashingStage::new( stage_config.account_hashing.clean_threshold, stage_config.account_hashing.commit_threshold, - config.prune.map(|prune| prune.parts).unwrap_or_default(), )) .set(StorageHashingStage::new( stage_config.storage_hashing.clean_threshold, stage_config.storage_hashing.commit_threshold, - config.prune.map(|prune| prune.parts).unwrap_or_default(), - )) - .set(MerkleStage::new_execution( - stage_config.merkle.clean_threshold, - config.prune.map(|prune| prune.parts).unwrap_or_default(), )) + .set(MerkleStage::new_execution(stage_config.merkle.clean_threshold)) .set(TransactionLookupStage::new(stage_config.transaction_lookup.commit_threshold)) .set(IndexAccountHistoryStage::new( stage_config.index_account_history.commit_threshold, @@ -817,61 +819,60 @@ async fn run_network_until_shutdown( #[cfg(test)] mod tests { - use super::*; use reth_primitives::DEV; + + use super::*; use std::{net::IpAddr, path::Path}; #[test] fn parse_help_node_command() { - let err = Command::<()>::try_parse_from(["reth", "--help"]).unwrap_err(); + let err = Command::try_parse_from(["reth", "--help"]).unwrap_err(); assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); } #[test] fn parse_common_node_command_chain_args() { for chain in ["mainnet", "sepolia", "goerli"] { - let args: Command = Command::<()>::parse_from(["reth", "--chain", chain]); + let args: Command = Command::parse_from(["reth", "--chain", chain]); assert_eq!(args.chain.chain, chain.parse().unwrap()); } } #[test] fn parse_discovery_port() { - let cmd = Command::<()>::try_parse_from(["reth", "--discovery.port", "300"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--discovery.port", "300"]).unwrap(); assert_eq!(cmd.network.discovery.port, Some(300)); } #[test] fn parse_port() { let cmd = - Command::<()>::try_parse_from(["reth", "--discovery.port", "300", "--port", "99"]) - .unwrap(); + Command::try_parse_from(["reth", "--discovery.port", "300", "--port", "99"]).unwrap(); assert_eq!(cmd.network.discovery.port, Some(300)); assert_eq!(cmd.network.port, Some(99)); } #[test] fn parse_metrics_port() { - let cmd = Command::<()>::try_parse_from(["reth", "--metrics", "9001"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--metrics", "9001"]).unwrap(); assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9001))); - let cmd = Command::<()>::try_parse_from(["reth", "--metrics", ":9001"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--metrics", ":9001"]).unwrap(); assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9001))); - let cmd = Command::<()>::try_parse_from(["reth", "--metrics", "localhost:9001"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--metrics", "localhost:9001"]).unwrap(); assert_eq!(cmd.metrics, Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9001))); } #[test] fn parse_config_path() { - let cmd = - Command::<()>::try_parse_from(["reth", "--config", "my/path/to/reth.toml"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--config", "my/path/to/reth.toml"]).unwrap(); // always store reth.toml in the data dir, not the chain specific data dir let data_dir = cmd.datadir.unwrap_or_chain_default(cmd.chain.chain); let config_path = cmd.config.unwrap_or(data_dir.config_path()); assert_eq!(config_path, Path::new("my/path/to/reth.toml")); - let cmd = Command::<()>::try_parse_from(["reth"]).unwrap(); + let cmd = Command::try_parse_from(["reth"]).unwrap(); // always store reth.toml in the data dir, not the chain specific data dir let data_dir = cmd.datadir.unwrap_or_chain_default(cmd.chain.chain); @@ -881,12 +882,12 @@ mod tests { #[test] fn parse_db_path() { - let cmd = Command::<()>::try_parse_from(["reth"]).unwrap(); + let cmd = Command::try_parse_from(["reth"]).unwrap(); let data_dir = cmd.datadir.unwrap_or_chain_default(cmd.chain.chain); let db_path = data_dir.db_path(); assert!(db_path.ends_with("reth/mainnet/db"), "{:?}", cmd.config); - let cmd = Command::<()>::try_parse_from(["reth", "--datadir", "my/custom/path"]).unwrap(); + let cmd = Command::try_parse_from(["reth", "--datadir", "my/custom/path"]).unwrap(); let data_dir = cmd.datadir.unwrap_or_chain_default(cmd.chain.chain); let db_path = data_dir.db_path(); assert_eq!(db_path, Path::new("my/custom/path/db")); @@ -894,7 +895,7 @@ mod tests { #[test] fn parse_dev() { - let cmd = Command::<()>::parse_from(["reth", "--dev"]); + let cmd = Command::parse_from(["reth", "--dev"]); let chain = DEV.clone(); assert_eq!(cmd.chain.chain, chain.chain); assert_eq!(cmd.chain.genesis_hash, chain.genesis_hash); diff --git a/bin/reth/src/stage/dump/merkle.rs b/bin/reth/src/stage/dump/merkle.rs index b5416876878..69b39234bd1 100644 --- a/bin/reth/src/stage/dump/merkle.rs +++ b/bin/reth/src/stage/dump/merkle.rs @@ -86,22 +86,14 @@ async fn unwind_and_copy( // Bring hashes to TO - AccountHashingStage { - clean_threshold: u64::MAX, - commit_threshold: u64::MAX, - prune_modes: PruneModes::none(), - } - .execute(&provider, execute_input) - .await - .unwrap(); - StorageHashingStage { - clean_threshold: u64::MAX, - commit_threshold: u64::MAX, - prune_modes: PruneModes::none(), - } - .execute(&provider, execute_input) - .await - .unwrap(); + AccountHashingStage { clean_threshold: u64::MAX, commit_threshold: u64::MAX } + .execute(&provider, execute_input) + .await + .unwrap(); + StorageHashingStage { clean_threshold: u64::MAX, commit_threshold: u64::MAX } + .execute(&provider, execute_input) + .await + .unwrap(); let unwind_inner_tx = provider.into_tx(); @@ -132,7 +124,6 @@ async fn dry_run( clean_threshold: u64::MAX, /* Forces updating the root instead of calculating * from * scratch */ - prune_modes: Default::default(), } .execute( &provider, diff --git a/bin/reth/src/stage/run.rs b/bin/reth/src/stage/run.rs index 9953bfc8a0e..f53412c3dbb 100644 --- a/bin/reth/src/stage/run.rs +++ b/bin/reth/src/stage/run.rs @@ -208,22 +208,12 @@ impl Command { ) } StageEnum::TxLookup => (Box::new(TransactionLookupStage::new(batch_size)), None), - StageEnum::AccountHashing => ( - Box::new(AccountHashingStage::new( - 1, - batch_size, - config.prune.map(|prune| prune.parts).unwrap_or_default(), - )), - None, - ), - StageEnum::StorageHashing => ( - Box::new(StorageHashingStage::new( - 1, - batch_size, - config.prune.map(|prune| prune.parts).unwrap_or_default(), - )), - None, - ), + StageEnum::AccountHashing => { + (Box::new(AccountHashingStage::new(1, batch_size)), None) + } + StageEnum::StorageHashing => { + (Box::new(StorageHashingStage::new(1, batch_size)), None) + } StageEnum::Merkle => ( Box::new(MerkleStage::default_execution()), Some(Box::new(MerkleStage::default_unwind())), diff --git a/bin/reth/src/utils.rs b/bin/reth/src/utils.rs index 32cd073ce07..1ac4f4d427f 100644 --- a/bin/reth/src/utils.rs +++ b/bin/reth/src/utils.rs @@ -1,7 +1,6 @@ //! Common CLI utility functions. use eyre::Result; -use reth_consensus_common::validation::validate_block_standalone; use reth_db::{ cursor::DbCursorRO, database::Database, @@ -9,13 +8,10 @@ use reth_db::{ transaction::{DbTx, DbTxMut}, }; use reth_interfaces::p2p::{ - bodies::client::BodiesClient, headers::client::{HeadersClient, HeadersRequest}, priority::Priority, }; -use reth_primitives::{ - fs, BlockHashOrNumber, ChainSpec, HeadersDirection, SealedBlock, SealedHeader, -}; +use reth_primitives::{fs, BlockHashOrNumber, ChainSpec, HeadersDirection, SealedHeader}; use std::{ env::VarError, path::{Path, PathBuf}, @@ -60,35 +56,6 @@ where Ok(header) } -/// Get a body from network based on header -pub async fn get_single_body( - client: Client, - chain_spec: Arc, - header: SealedHeader, -) -> Result -where - Client: BodiesClient, -{ - let (peer_id, response) = client.get_block_body(header.hash).await?.split(); - - if response.is_none() { - client.report_bad_message(peer_id); - eyre::bail!("Invalid number of bodies received. Expected: 1. Received: 0") - } - - let block = response.unwrap(); - let block = SealedBlock { - header, - body: block.transactions, - ommers: block.ommers, - withdrawals: block.withdrawals, - }; - - validate_block_standalone(&block, &chain_spec)?; - - Ok(block) -} - /// Wrapper over DB that implements many useful DB queries. pub struct DbTool<'a, DB: Database> { pub(crate) db: &'a DB, diff --git a/book/cli/db.md b/book/cli/db.md index 5772fe612cf..95627871c42 100644 --- a/book/cli/db.md +++ b/book/cli/db.md @@ -16,8 +16,6 @@ Commands: Gets the content of a table for the given key drop Deletes all database entries - clear - Deletes all table entries version Lists current and local database versions path @@ -97,85 +95,14 @@ Display: Silence all log output ``` -## `reth db stats` - -Lists all the tables, their entry count and their size - -```bash -$ reth db stats --help - -Usage: reth db stats [OPTIONS] - -Options: - --datadir - The path to the data dir for all reth files and subdirectories. - - Defaults to the OS-specific data directory: - - - Linux: `$XDG_DATA_HOME/reth/` or `$HOME/.local/share/reth/` - - Windows: `{FOLDERID_RoamingAppData}/reth/` - - macOS: `$HOME/Library/Application Support/reth/` - - [default: default] - - --chain - The chain this node is running. - - Possible values are either a built-in chain or the path to a chain specification file. - - Built-in chains: - - mainnet - - goerli - - sepolia - - [default: mainnet] - - -h, --help - Print help (see a summary with '-h') - -Logging: - --log.persistent - The flag to enable persistent logs - - --log.directory - The path to put log files in - - [default: /reth/logs] - - --log.journald - Log events to journald - - --log.filter - The filter to use for logs written to the log file - - [default: error] - -Display: - -v, --verbosity... - Set the minimum log level. - - -v Errors - -vv Warnings - -vvv Info - -vvvv Debug - -vvvvv Traces (warning: very verbose!) - - -q, --quiet - Silence all log output -``` - -## `reth db list` +## `reth db drop` -Lists the contents of a table +Deletes all database entries ```bash -$ reth db list --help - -Usage: reth db list [OPTIONS] +$ reth db drop --help -Arguments: -
- The table name +Usage: reth db drop [OPTIONS] Options: --datadir @@ -189,11 +116,6 @@ Options: [default: default] - -s, --skip - Skip first N entries - - [default: 0] - --chain The chain this node is running. @@ -206,17 +128,6 @@ Options: [default: mainnet] - -r, --reverse - Reverse the order of the entries. If enabled last table entries are read - - -l, --len - How many items to take from the walker - - [default: 5] - - -j, --json - Dump as JSON instead of using TUI - -h, --help Print help (see a summary with '-h') @@ -327,14 +238,18 @@ Display: Silence all log output ``` -## `reth db drop` +## `reth db list` -Deletes all database entries +Lists the contents of a table ```bash -$ reth db drop --help +$ reth db list --help -Usage: reth db drop [OPTIONS] +Usage: reth db list [OPTIONS]
+ +Arguments: +
+ The table name Options: --datadir @@ -348,6 +263,11 @@ Options: [default: default] + -s, --skip + Skip first N entries + + [default: 0] + --chain The chain this node is running. @@ -360,6 +280,17 @@ Options: [default: mainnet] + -r, --reverse + Reverse the order of the entries. If enabled last table entries are read + + -l, --len + How many items to take from the walker + + [default: 5] + + -j, --json + Dump as JSON instead of using TUI + -h, --help Print help (see a summary with '-h') @@ -394,18 +325,14 @@ Display: Silence all log output ``` -## `reth db clear` +## `reth db path` -Deletes all table entries +Returns the full database path ```bash -$ reth db clear --help - -Usage: reth db clear [OPTIONS]
+$ reth db path --help -Arguments: -
- Table name +Usage: reth db path [OPTIONS] Options: --datadir @@ -465,14 +392,14 @@ Display: Silence all log output ``` -## `reth db version` +## `reth db stats` -Lists current and local database versions +Lists all the tables, their entry count and their size ```bash -$ reth db version --help +$ reth db stats --help -Usage: reth db version [OPTIONS] +Usage: reth db stats [OPTIONS] Options: --datadir @@ -532,14 +459,14 @@ Display: Silence all log output ``` -## `reth db path` +## `reth db version` -Returns the full database path +Lists current and local database versions ```bash -$ reth db path --help +$ reth db version --help -Usage: reth db path [OPTIONS] +Usage: reth db version [OPTIONS] Options: --datadir diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 8edee773bad..ce92f48b283 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1001,12 +1001,9 @@ impl BlockchainTree old: Arc::new(old_canon_chain.clone()), new: Arc::new(new_canon_chain.clone()), }; - let reorg_depth = old_canon_chain.len(); - // insert old canon chain self.insert_chain(AppendableChain::new(old_canon_chain)); - - self.update_reorg_metrics(reorg_depth as f64); + self.metrics.reorgs.increment(1); } else { // error here to confirm that we are reverting nothing from db. error!(target: "blockchain_tree", "Reverting nothing from db on block: #{:?}", block_hash); @@ -1097,11 +1094,6 @@ impl BlockchainTree } } - fn update_reorg_metrics(&mut self, reorg_depth: f64) { - self.metrics.reorgs.increment(1); - self.metrics.latest_reorg_depth.set(reorg_depth); - } - /// Update blockchain tree chains (canonical and sidechains) and sync metrics. /// /// NOTE: this method should not be called during the pipeline sync, because otherwise the sync diff --git a/crates/blockchain-tree/src/metrics.rs b/crates/blockchain-tree/src/metrics.rs index b49ad3c5b92..fd48307d4be 100644 --- a/crates/blockchain-tree/src/metrics.rs +++ b/crates/blockchain-tree/src/metrics.rs @@ -13,8 +13,6 @@ pub struct TreeMetrics { pub canonical_chain_height: Gauge, /// The number of reorgs pub reorgs: Counter, - /// The latest reorg depth - pub latest_reorg_depth: Gauge, /// Longest sidechain height pub longest_sidechain_height: Gauge, } diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 29cb6f49177..668a2117f6b 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -269,8 +269,6 @@ impl StorageInner { nonce: 0, base_fee_per_gas, extra_data: Default::default(), - blob_gas_used: None, - excess_blob_gas: None, }; header.transactions_root = if transactions.is_empty() { diff --git a/crates/consensus/beacon/src/engine/message.rs b/crates/consensus/beacon/src/engine/message.rs index 76808558595..2e5e542aab1 100644 --- a/crates/consensus/beacon/src/engine/message.rs +++ b/crates/consensus/beacon/src/engine/message.rs @@ -145,7 +145,6 @@ impl Future for PendingPayloadId { /// A message for the beacon engine from other components of the node (engine RPC API invoked by the /// consensus layer). #[derive(Debug)] -#[allow(clippy::large_enum_variant)] pub enum BeaconEngineMessage { /// Message with new payload. NewPayload { diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 3aea32b5b45..5fffb7f2a2e 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -1,13 +1,8 @@ //! Collection of methods for block validation. use reth_interfaces::{consensus::ConsensusError, Result as RethResult}; use reth_primitives::{ - blobfee::calculate_excess_blob_gas, - constants::{ - self, - eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK}, - }, - BlockNumber, ChainSpec, Hardfork, Header, InvalidTransactionError, SealedBlock, SealedHeader, - Transaction, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy, + constants, BlockNumber, ChainSpec, Hardfork, Header, InvalidTransactionError, SealedBlock, + SealedHeader, Transaction, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy, }; use reth_provider::{AccountReader, HeaderProvider, WithdrawalsProvider}; use std::collections::{hash_map::Entry, HashMap}; @@ -46,15 +41,6 @@ pub fn validate_header_standalone( return Err(ConsensusError::WithdrawalsRootUnexpected) } - // Ensures that EIP-4844 fields are valid once cancun is active. - if chain_spec.fork(Hardfork::Cancun).active_at_timestamp(header.timestamp) { - validate_4844_header_standalone(header)?; - } else if header.blob_gas_used.is_some() { - return Err(ConsensusError::BlobGasUsedUnexpected) - } else if header.excess_blob_gas.is_some() { - return Err(ConsensusError::ExcessBlobGasUnexpected) - } - Ok(()) } @@ -315,11 +301,6 @@ pub fn validate_header_regarding_parent( } } - // ensure that the blob gas fields for this block - if chain_spec.fork(Hardfork::Cancun).active_at_timestamp(child.timestamp) { - validate_4844_header_with_parent(parent, child)?; - } - Ok(()) } @@ -405,72 +386,6 @@ pub fn full_validation Result<(), ConsensusError> { - // From [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844#header-extension): - // - // > For the first post-fork block, both parent.blob_gas_used and parent.excess_blob_gas - // > are evaluated as 0. - // - // This means in the first post-fork block, calculate_excess_blob_gas will return 0. - let parent_blob_gas_used = parent.blob_gas_used.unwrap_or(0); - let parent_excess_blob_gas = parent.excess_blob_gas.unwrap_or(0); - - if child.blob_gas_used.is_none() { - return Err(ConsensusError::BlobGasUsedMissing) - } - let excess_blob_gas = child.excess_blob_gas.ok_or(ConsensusError::ExcessBlobGasMissing)?; - - let expected_excess_blob_gas = - calculate_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used); - if expected_excess_blob_gas != excess_blob_gas { - return Err(ConsensusError::ExcessBlobGasDiff { - expected: expected_excess_blob_gas, - got: excess_blob_gas, - parent_excess_blob_gas, - parent_blob_gas_used, - }) - } - - Ok(()) -} - -/// Validates that the EIP-4844 header fields exist and conform to the spec. This ensures that: -/// -/// * `blob_gas_used` exists as a header field -/// * `excess_blob_gas` exists as a header field -/// * `blob_gas_used` is less than or equal to `MAX_DATA_GAS_PER_BLOCK` -/// * `blob_gas_used` is a multiple of `DATA_GAS_PER_BLOB` -pub fn validate_4844_header_standalone(header: &SealedHeader) -> Result<(), ConsensusError> { - let blob_gas_used = header.blob_gas_used.ok_or(ConsensusError::BlobGasUsedMissing)?; - - if header.excess_blob_gas.is_none() { - return Err(ConsensusError::ExcessBlobGasMissing) - } - - if blob_gas_used > MAX_DATA_GAS_PER_BLOCK { - return Err(ConsensusError::BlobGasUsedExceedsMaxBlobGasPerBlock { - blob_gas_used, - max_blob_gas_per_block: MAX_DATA_GAS_PER_BLOCK, - }) - } - - if blob_gas_used % DATA_GAS_PER_BLOB != 0 { - return Err(ConsensusError::BlobGasUsedNotMultipleOfBlobGasPerBlob { - blob_gas_used, - blob_gas_per_blob: DATA_GAS_PER_BLOB, - }) - } - - Ok(()) -} - #[cfg(test)] mod tests { use super::*; @@ -625,8 +540,6 @@ mod tests { nonce: 0x0000000000000000, base_fee_per_gas: 0x28f0001df.into(), withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }; // size: 0x9b5 diff --git a/crates/interfaces/src/consensus.rs b/crates/interfaces/src/consensus.rs index 76c2175c9af..16f4d6c07ad 100644 --- a/crates/interfaces/src/consensus.rs +++ b/crates/interfaces/src/consensus.rs @@ -113,27 +113,6 @@ pub enum ConsensusError { WithdrawalIndexInvalid { got: u64, expected: u64 }, #[error("Missing withdrawals")] BodyWithdrawalsMissing, - #[error("Missing blob gas used")] - BlobGasUsedMissing, - #[error("Unexpected blob gas used")] - BlobGasUsedUnexpected, - #[error("Missing excess blob gas")] - ExcessBlobGasMissing, - #[error("Unexpected excess blob gas")] - ExcessBlobGasUnexpected, - #[error("Blob gas used {blob_gas_used} exceeds maximum allowance {max_blob_gas_per_block}")] - BlobGasUsedExceedsMaxBlobGasPerBlock { blob_gas_used: u64, max_blob_gas_per_block: u64 }, - #[error( - "Blob gas used {blob_gas_used} is not a multiple of blob gas per blob {blob_gas_per_blob}" - )] - BlobGasUsedNotMultipleOfBlobGasPerBlob { blob_gas_used: u64, blob_gas_per_blob: u64 }, - #[error("Invalid excess blob gas. Expected: {expected}, got: {got}. Parent excess blob gas: {parent_excess_blob_gas}, parent blob gas used: {parent_blob_gas_used}.")] - ExcessBlobGasDiff { - expected: u64, - got: u64, - parent_excess_blob_gas: u64, - parent_blob_gas_used: u64, - }, /// Error for a transaction that violates consensus. #[error(transparent)] InvalidTransaction(#[from] InvalidTransactionError), diff --git a/crates/net/downloaders/Cargo.toml b/crates/net/downloaders/Cargo.toml index 281dbfc6c78..b5ca3d6b5b0 100644 --- a/crates/net/downloaders/Cargo.toml +++ b/crates/net/downloaders/Cargo.toml @@ -32,7 +32,7 @@ thiserror.workspace = true # optional deps for the test-utils feature reth-rlp = { workspace = true, optional = true } tempfile = { version = "3.3", optional = true } -itertools = { workspace = true, optional = true } +itertools = { version = "0.10", optional = true } [dev-dependencies] reth-db = { path = "../../storage/db", features = ["test-utils"] } @@ -42,7 +42,7 @@ reth-tracing = { path = "../../tracing" } assert_matches = "1.5.0" tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } reth-rlp.workspace = true -itertools.workspace = true +itertools = "0.10" tempfile = "3.3" diff --git a/crates/net/eth-wire/src/types/blocks.rs b/crates/net/eth-wire/src/types/blocks.rs index 808c8f4a460..47777cd71b1 100644 --- a/crates/net/eth-wire/src/types/blocks.rs +++ b/crates/net/eth-wire/src/types/blocks.rs @@ -258,8 +258,6 @@ mod test { nonce: 0x0000000000000000u64, base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }, ]), }.encode(&mut data); @@ -291,8 +289,6 @@ mod test { nonce: 0x0000000000000000u64, base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }, ]), }; @@ -405,8 +401,6 @@ mod test { nonce: 0x0000000000000000u64, base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }, ], withdrawals: None, @@ -491,8 +485,6 @@ mod test { nonce: 0x0000000000000000u64, base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }, ], withdrawals: None, diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index 10b53f61701..7cb4db72b37 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -8,7 +8,7 @@ use reth_eth_wire::{ }; use reth_interfaces::p2p::error::RequestResult; use reth_primitives::{BlockBody, BlockHashOrNumber, Header, HeadersDirection, PeerId}; -use reth_provider::{BlockReader, HeaderProvider, ReceiptProvider}; +use reth_provider::{BlockReader, HeaderProvider}; use std::{ borrow::Borrow, future::Future, @@ -21,11 +21,6 @@ use tokio_stream::wrappers::ReceiverStream; // Limits: -/// Maximum number of receipts to serve. -/// -/// Used to limit lookups. -const MAX_RECEIPTS_SERVE: usize = 1024; - /// Maximum number of block headers to serve. /// /// Used to limit lookups. @@ -37,9 +32,6 @@ const MAX_HEADERS_SERVE: usize = 1024; /// SOFT_RESPONSE_LIMIT. const MAX_BODIES_SERVE: usize = 1024; -/// Estimated size in bytes of an RLP encoded receipt. -const APPROX_RECEIPT_SIZE: usize = 24 * 1024; - /// Estimated size in bytes of an RLP encoded body. // TODO: check 24kb blocksize assumption const APPROX_BODY_SIZE: usize = 24 * 1024; @@ -78,7 +70,7 @@ impl EthRequestHandler { impl EthRequestHandler where - C: BlockReader + HeaderProvider + ReceiptProvider, + C: BlockReader + HeaderProvider, { /// Returns the list of requested headers fn get_headers_response(&self, request: GetBlockHeaders) -> Vec
{ @@ -193,44 +185,6 @@ where let _ = response.send(Ok(BlockBodies(bodies))); } - - fn on_receipts_request( - &mut self, - _peer_id: PeerId, - request: GetReceipts, - response: oneshot::Sender>, - ) { - let mut receipts = Vec::new(); - - let mut total_bytes = APPROX_RECEIPT_SIZE; - - for hash in request.0 { - if let Some(receipts_by_block) = - self.client.receipts_by_block(BlockHashOrNumber::Hash(hash)).unwrap_or_default() - { - receipts.push( - receipts_by_block - .into_iter() - .map(|receipt| receipt.with_bloom()) - .collect::>(), - ); - - total_bytes += APPROX_RECEIPT_SIZE; - - if total_bytes > SOFT_RESPONSE_LIMIT { - break - } - - if receipts.len() >= MAX_RECEIPTS_SERVE { - break - } - } else { - break - } - } - - let _ = response.send(Ok(Receipts(receipts))); - } } /// An endless future. @@ -257,9 +211,7 @@ where this.on_bodies_request(peer_id, request, response) } IncomingEthRequest::GetNodeData { .. } => {} - IncomingEthRequest::GetReceipts { peer_id, request, response } => { - this.on_receipts_request(peer_id, request, response) - } + IncomingEthRequest::GetReceipts { .. } => {} }, } } diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 3ed0a6873ce..bf12796f2dd 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -716,8 +716,6 @@ fn build_payload( difficulty: U256::ZERO, gas_used: cumulative_gas_used, extra_data: extra_data.into(), - blob_gas_used: None, - excess_blob_gas: None, }; // seal the block @@ -789,8 +787,6 @@ where difficulty: U256::ZERO, gas_used: 0, extra_data: extra_data.into(), - blob_gas_used: None, - excess_blob_gas: None, }; let block = Block { header, body: vec![], ommers: vec![], withdrawals }; diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index bfdfcc9c846..42570da25e2 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -22,7 +22,7 @@ crunchy = { version = "0.2.2", default-features = false, features = ["limit_256" ruint = { version = "1.9.0", features = ["primitive-types", "rlp"] } # Bloom - fixed-hash = { version = "0.8", default-features = false, features = ["rustc-hex"] } +fixed-hash = { version = "0.8", default-features = false, features = ["rustc-hex"] } # crypto secp256k1 = { workspace = true, default-features = false, features = [ diff --git a/crates/primitives/src/blobfee.rs b/crates/primitives/src/blobfee.rs deleted file mode 100644 index e82b5d2f8c6..00000000000 --- a/crates/primitives/src/blobfee.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Helpers for working with EIP-4844 blob fee - -use crate::constants::eip4844::TARGET_DATA_GAS_PER_BLOCK; - -/// Calculates the excess data gas for the next block, after applying the current set of blobs on -/// top of the excess data gas. -/// -/// Specified in [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844#header-extension) -pub fn calculate_excess_blob_gas(parent_excess_blob_gas: u64, parent_blob_gas_used: u64) -> u64 { - let excess_blob_gas = parent_excess_blob_gas + parent_blob_gas_used; - excess_blob_gas.saturating_sub(TARGET_DATA_GAS_PER_BLOCK) -} diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 552c1017df2..86db32ba0db 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -359,15 +359,6 @@ impl ChainSpec { .unwrap_or_else(|| self.is_fork_active_at_timestamp(Hardfork::Shanghai, timestamp)) } - /// Convenience method to check if [Hardfork::Cancun] is active at a given timestamp. - #[inline] - pub fn is_cancun_activated_at_timestamp(&self, timestamp: u64) -> bool { - self.fork_timestamps - .cancun - .map(|cancun| timestamp >= cancun) - .unwrap_or_else(|| self.is_fork_active_at_timestamp(Hardfork::Cancun, timestamp)) - } - /// Creates a [`ForkFilter`](crate::ForkFilter) for the block described by [Head]. pub fn fork_filter(&self, head: Head) -> ForkFilter { let forks = self.forks_iter().filter_map(|(_, condition)| { @@ -497,8 +488,6 @@ impl From for ChainSpec { pub struct ForkTimestamps { /// The timestamp of the shanghai fork pub shanghai: Option, - /// The timestamp of the cancun fork - pub cancun: Option, } impl ForkTimestamps { @@ -508,9 +497,6 @@ impl ForkTimestamps { if let Some(shanghai) = forks.get(&Hardfork::Shanghai).and_then(|f| f.as_timestamp()) { timestamps = timestamps.shanghai(shanghai); } - if let Some(cancun) = forks.get(&Hardfork::Cancun).and_then(|f| f.as_timestamp()) { - timestamps = timestamps.cancun(cancun); - } timestamps } @@ -519,12 +505,6 @@ impl ForkTimestamps { self.shanghai = Some(shanghai); self } - - /// Sets the given cancun timestamp - pub fn cancun(mut self, cancun: u64) -> Self { - self.cancun = Some(cancun); - self - } } /// A helper type for compatibility with geth's config @@ -693,13 +673,6 @@ impl ChainSpecBuilder { self } - /// Enable Cancun at genesis. - pub fn cancun_activated(mut self) -> Self { - self = self.paris_activated(); - self.hardforks.insert(Hardfork::Cancun, ForkCondition::Timestamp(0)); - self - } - /// Enable Bedrock at genesis #[cfg(feature = "optimism")] pub fn bedrock_activated(mut self) -> Self { diff --git a/crates/primitives/src/hardfork.rs b/crates/primitives/src/hardfork.rs index b0f5dfde04a..f772e8c6cc2 100644 --- a/crates/primitives/src/hardfork.rs +++ b/crates/primitives/src/hardfork.rs @@ -39,8 +39,6 @@ pub enum Hardfork { Paris, /// Shanghai. Shanghai, - /// Cancun. - Cancun, /// Bedrock. #[cfg(feature = "optimism")] Bedrock, @@ -90,7 +88,6 @@ impl FromStr for Hardfork { "grayglacier" => Hardfork::GrayGlacier, "paris" => Hardfork::Paris, "shanghai" => Hardfork::Shanghai, - "cancun" => Hardfork::Cancun, #[cfg(feature = "optimism")] "bedrock" => Hardfork::Bedrock, #[cfg(feature = "optimism")] @@ -110,6 +107,7 @@ impl Display for Hardfork { #[cfg(test)] mod tests { use super::*; + use crate::{Chain, Genesis}; use std::collections::BTreeMap; @@ -132,7 +130,6 @@ mod tests { "grayglacier", "PARIS", "ShAnGhAI", - "CaNcUn", ]; let expected_hardforks = [ Hardfork::Frontier, @@ -151,7 +148,6 @@ mod tests { Hardfork::GrayGlacier, Hardfork::Paris, Hardfork::Shanghai, - Hardfork::Cancun, ]; let hardforks: Vec = diff --git a/crates/primitives/src/header.rs b/crates/primitives/src/header.rs index e39c6a8287a..ba8e8f31deb 100644 --- a/crates/primitives/src/header.rs +++ b/crates/primitives/src/header.rs @@ -1,6 +1,5 @@ use crate::{ basefee::calculate_next_block_base_fee, - blobfee::calculate_excess_blob_gas, keccak256, proofs::{EMPTY_LIST_HASH, EMPTY_ROOT}, BlockBodyRoots, BlockHash, BlockNumHash, BlockNumber, Bloom, Bytes, H160, H256, H64, U256, @@ -8,7 +7,7 @@ use crate::{ use bytes::{Buf, BufMut, BytesMut}; use reth_codecs::{add_arbitrary_tests, derive_arbitrary, main_codec, Compact}; -use reth_rlp::{length_of_length, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE}; +use reth_rlp::{length_of_length, Decodable, Encodable, EMPTY_STRING_CODE}; use serde::{Deserialize, Serialize}; use std::{ mem, @@ -92,13 +91,6 @@ pub struct Header { /// above the gas target, and decreasing when blocks are below the gas target. The base fee per /// gas is burned. pub base_fee_per_gas: Option, - /// The total amount of blob gas consumed by the transactions within the block, added in - /// EIP-4844. - pub blob_gas_used: Option, - /// A running total of blob gas consumed in excess of the target, prior to the block. Blocks - /// with above-target blob gas consumption increase this value, blocks with below-target blob - /// gas consumption decrease it (bounded at 0). This was added in EIP-4844. - pub excess_blob_gas: Option, /// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or /// fewer; formally Hx. pub extra_data: Bytes, @@ -124,8 +116,6 @@ impl Default for Header { nonce: 0, base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, } } } @@ -180,13 +170,6 @@ impl Header { Some(calculate_next_block_base_fee(self.gas_used, self.gas_limit, self.base_fee_per_gas?)) } - /// Calculate excess blob gas for the next block according to the EIP-4844 spec. - /// - /// Returns a `None` if no excess blob gas is set, no EIP-4844 support - pub fn next_block_excess_blob_gas(&self) -> Option { - Some(calculate_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?)) - } - /// Seal the header with a known hash. /// /// WARNING: This method does not perform validation whether the hash is correct. @@ -219,8 +202,6 @@ impl Header { mem::size_of::() + // mix hash mem::size_of::() + // nonce mem::size_of::>() + // base fee per gas - mem::size_of::>() + // blob gas used - mem::size_of::>() + // excess blob gas self.extra_data.len() // extra data } @@ -244,34 +225,11 @@ impl Header { if let Some(base_fee) = self.base_fee_per_gas { length += U256::from(base_fee).length(); - } else if self.withdrawals_root.is_some() || - self.blob_gas_used.is_some() || - self.excess_blob_gas.is_some() - { - length += 1; // EMPTY STRING CODE + } else if self.withdrawals_root.is_some() { + length += 1; // EMTY STRING CODE } - if let Some(root) = self.withdrawals_root { length += root.length(); - } else if self.blob_gas_used.is_some() || self.excess_blob_gas.is_some() { - length += 1; // EMPTY STRING CODE - } - - if let Some(blob_gas_used) = self.blob_gas_used { - length += U256::from(blob_gas_used).length(); - } else if self.excess_blob_gas.is_some() { - length += 1; // EMPTY STRING CODE - } - - // Encode excess blob gas length. If new fields are added, the above pattern will need to - // be repeated and placeholder length added. Otherwise, it's impossible to tell _which_ - // fields are missing. This is mainly relevant for contrived cases where a header is - // created at random, for example: - // * A header is created with a withdrawals root, but no base fee. Shanghai blocks are - // post-London, so this is technically not valid. However, a tool like proptest would - // generate a block like this. - if let Some(excess_blob_gas) = self.excess_blob_gas { - length += U256::from(excess_blob_gas).length(); } length @@ -303,38 +261,12 @@ impl Encodable for Header { // but withdrawals root is present. if let Some(ref base_fee) = self.base_fee_per_gas { U256::from(*base_fee).encode(out); - } else if self.withdrawals_root.is_some() || - self.blob_gas_used.is_some() || - self.excess_blob_gas.is_some() - { + } else if self.withdrawals_root.is_some() { out.put_u8(EMPTY_STRING_CODE); } - // Encode withdrawals root. Put empty string if withdrawals root is missing, - // but blob gas used is present. if let Some(ref root) = self.withdrawals_root { root.encode(out); - } else if self.blob_gas_used.is_some() || self.excess_blob_gas.is_some() { - out.put_u8(EMPTY_STRING_CODE); - } - - // Encode blob gas used. Put empty string if blob gas used is missing, - // but excess blob gas is present. - if let Some(ref blob_gas_used) = self.blob_gas_used { - U256::from(*blob_gas_used).encode(out); - } else if self.excess_blob_gas.is_some() { - out.put_u8(EMPTY_LIST_CODE); - } - - // Encode excess blob gas. If new fields are added, the above pattern will need to be - // repeated and placeholders added. Otherwise, it's impossible to tell _which_ fields - // are missing. This is mainly relevant for contrived cases where a header is created - // at random, for example: - // * A header is created with a withdrawals root, but no base fee. Shanghai blocks are - // post-London, so this is technically not valid. However, a tool like proptest would - // generate a block like this. - if let Some(ref excess_blob_gas) = self.excess_blob_gas { - U256::from(*excess_blob_gas).encode(out); } } @@ -371,10 +303,7 @@ impl Decodable for Header { nonce: H64::decode(buf)?.to_low_u64_be(), base_fee_per_gas: None, withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }; - if started_len - buf.len() < rlp_head.payload_length { if buf.first().map(|b| *b == EMPTY_STRING_CODE).unwrap_or_default() { buf.advance(1) @@ -382,36 +311,9 @@ impl Decodable for Header { this.base_fee_per_gas = Some(U256::decode(buf)?.to::()); } } - - // Withdrawals root for post-shanghai headers - if started_len - buf.len() < rlp_head.payload_length { - if buf.first().map(|b| *b == EMPTY_STRING_CODE).unwrap_or_default() { - buf.advance(1) - } else { - this.withdrawals_root = Some(Decodable::decode(buf)?); - } - } - - // Blob gas used and excess blob gas for post-cancun headers - if started_len - buf.len() < rlp_head.payload_length { - if buf.first().map(|b| *b == EMPTY_LIST_CODE).unwrap_or_default() { - buf.advance(1) - } else { - this.blob_gas_used = Some(U256::decode(buf)?.to::()); - } - } - - // Decode excess blob gas. If new fields are added, the above pattern will need to be - // repeated and placeholders decoded. Otherwise, it's impossible to tell _which_ fields are - // missing. This is mainly relevant for contrived cases where a header is created at - // random, for example: - // * A header is created with a withdrawals root, but no base fee. Shanghai blocks are - // post-London, so this is technically not valid. However, a tool like proptest would - // generate a block like this. if started_len - buf.len() < rlp_head.payload_length { - this.excess_blob_gas = Some(U256::decode(buf)?.to::()); + this.withdrawals_root = Some(Decodable::decode(buf)?); } - let consumed = started_len - buf.len(); if consumed != rlp_head.payload_length { return Err(reth_rlp::DecodeError::ListLengthMismatch { @@ -634,8 +536,6 @@ mod ethers_compat { gas_used: block.gas_used.as_u64(), withdrawals_root: None, logs_bloom: block.logs_bloom.unwrap_or_default().0.into(), - blob_gas_used: None, - excess_blob_gas: None, } } } @@ -705,8 +605,6 @@ mod tests { nonce: 0, base_fee_per_gas: Some(0x036b_u64), withdrawals_root: None, - blob_gas_used: None, - excess_blob_gas: None, }; assert_eq!(header.hash_slow(), expected_hash); } @@ -785,120 +683,6 @@ mod tests { assert_eq!(header.hash_slow(), expected_hash); } - // Test vector from: https://github.com/ethereum/tests/blob/7e9e0940c0fcdbead8af3078ede70f969109bd85/BlockchainTests/ValidBlocks/bcExample/cancunExample.json - #[test] - fn test_decode_block_header_with_blob_fields_ef_tests() { - let data = hex::decode("f90221a03a9b485972e7353edd9152712492f0c58d89ef80623686b6bf947a4a6dce6cb6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa03c837fc158e3e93eafcaf2e658a02f5d8f99abc9f1c4c66cdea96c0ca26406aea04409cc4b699384ba5f8248d92b784713610c5ff9c1de51e9239da0dac76de9cea046cab26abf1047b5b119ecc2dda1296b071766c8b1307e1381fcecc90d513d86b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008001887fffffffffffffff8302a86582079e42a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42188000000000000000009a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218302000080").unwrap(); - let expected = Header { - parent_hash: H256::from_str( - "3a9b485972e7353edd9152712492f0c58d89ef80623686b6bf947a4a6dce6cb6", - ) - .unwrap(), - ommers_hash: H256::from_str( - "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - ) - .unwrap(), - beneficiary: Address::from_str("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap(), - state_root: H256::from_str( - "3c837fc158e3e93eafcaf2e658a02f5d8f99abc9f1c4c66cdea96c0ca26406ae", - ) - .unwrap(), - transactions_root: H256::from_str( - "4409cc4b699384ba5f8248d92b784713610c5ff9c1de51e9239da0dac76de9ce", - ) - .unwrap(), - receipts_root: H256::from_str( - "46cab26abf1047b5b119ecc2dda1296b071766c8b1307e1381fcecc90d513d86", - ) - .unwrap(), - logs_bloom: Default::default(), - difficulty: U256::from(0), - number: 0x1, - gas_limit: 0x7fffffffffffffff, - gas_used: 0x02a865, - timestamp: 0x079e, - extra_data: Bytes::from(vec![0x42]), - mix_hash: H256::from_str( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - ) - .unwrap(), - nonce: 0, - base_fee_per_gas: Some(9), - withdrawals_root: Some( - H256::from_str("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - .unwrap(), - ), - blob_gas_used: Some(0x020000), - excess_blob_gas: Some(0), - }; - - let header = Header::decode(&mut data.as_slice()).unwrap(); - assert_eq!(header, expected); - - let expected_hash = - H256::from_str("0x10aca3ebb4cf6ddd9e945a5db19385f9c105ede7374380c50d56384c3d233785") - .unwrap(); - assert_eq!(header.hash_slow(), expected_hash); - } - - #[test] - fn test_decode_block_header_with_blob_fields() { - // Block from devnet-7 - let data = hex::decode("f90239a013a7ec98912f917b3e804654e37c9866092043c13eb8eab94eb64818e886cff5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794f97e180c050e5ab072211ad2c213eb5aee4df134a0ec229dbe85b0d3643ad0f471e6ec1a36bbc87deffbbd970762d22a53b35d068aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080830305988401c9c380808464c40d5499d883010c01846765746888676f312e32302e35856c696e7578a070ccadc40b16e2094954b1064749cc6fbac783c1712f1b271a8aac3eda2f232588000000000000000007a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421808401600000").unwrap(); - let expected = Header { - parent_hash: H256::from_str( - "13a7ec98912f917b3e804654e37c9866092043c13eb8eab94eb64818e886cff5", - ) - .unwrap(), - ommers_hash: H256::from_str( - "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - ) - .unwrap(), - beneficiary: Address::from_str("f97e180c050e5ab072211ad2c213eb5aee4df134").unwrap(), - state_root: H256::from_str( - "ec229dbe85b0d3643ad0f471e6ec1a36bbc87deffbbd970762d22a53b35d068a", - ) - .unwrap(), - transactions_root: H256::from_str( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - ) - .unwrap(), - receipts_root: H256::from_str( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - ) - .unwrap(), - logs_bloom: Default::default(), - difficulty: U256::from(0), - number: 0x30598, - gas_limit: 0x1c9c380, - gas_used: 0, - timestamp: 0x64c40d54, - extra_data: Bytes::from( - hex::decode("d883010c01846765746888676f312e32302e35856c696e7578").unwrap(), - ), - mix_hash: H256::from_str( - "70ccadc40b16e2094954b1064749cc6fbac783c1712f1b271a8aac3eda2f2325", - ) - .unwrap(), - nonce: 0, - base_fee_per_gas: Some(7), - withdrawals_root: Some( - H256::from_str("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - .unwrap(), - ), - blob_gas_used: Some(0), - excess_blob_gas: Some(0x1600000), - }; - - let header = Header::decode(&mut data.as_slice()).unwrap(); - assert_eq!(header, expected); - - let expected_hash = - H256::from_str("0x539c9ea0a3ca49808799d3964b8b6607037227de26bc51073c6926963127087b") - .unwrap(); - assert_eq!(header.hash_slow(), expected_hash); - } - #[test] fn sanity_direction() { let reverse = true; diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 36c6ce3e58a..f8ae0d08350 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -23,7 +23,6 @@ pub mod abi; mod account; pub mod basefee; mod bits; -pub mod blobfee; mod block; pub mod bloom; mod chain; @@ -81,7 +80,7 @@ pub use net::{ SEPOLIA_BOOTNODES, }; pub use peer::{PeerId, WithPeerId}; -pub use prune::{PruneCheckpoint, PruneMode, PruneModes, PrunePart, PrunePartError}; +pub use prune::{PruneCheckpoint, PruneMode, PruneModes, PrunePart}; pub use receipt::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef}; pub use revm_primitives::JumpMap; pub use serde_helper::JsonU256; diff --git a/crates/primitives/src/prune/mod.rs b/crates/primitives/src/prune/mod.rs index a3bcb959627..4dfc591bfcc 100644 --- a/crates/primitives/src/prune/mod.rs +++ b/crates/primitives/src/prune/mod.rs @@ -5,5 +5,5 @@ mod target; pub use checkpoint::PruneCheckpoint; pub use mode::PruneMode; -pub use part::{PrunePart, PrunePartError}; +pub use part::PrunePart; pub use target::PruneModes; diff --git a/crates/primitives/src/prune/part.rs b/crates/primitives/src/prune/part.rs index db49870735a..caa176b86a2 100644 --- a/crates/primitives/src/prune/part.rs +++ b/crates/primitives/src/prune/part.rs @@ -1,10 +1,8 @@ -use derive_more::Display; use reth_codecs::{main_codec, Compact}; -use thiserror::Error; /// Part of the data that can be pruned. #[main_codec] -#[derive(Debug, Display, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] pub enum PrunePart { /// Prune part responsible for the `TxSenders` table. SenderRecovery, @@ -18,14 +16,6 @@ pub enum PrunePart { StorageHistory, } -/// PrunePart error type. -#[derive(Debug, Error)] -pub enum PrunePartError { - /// Invalid configuration of a prune part. - #[error("The configuration provided for {0} is invalid.")] - Configuration(PrunePart), -} - #[cfg(test)] impl Default for PrunePart { fn default() -> Self { diff --git a/crates/primitives/src/prune/target.rs b/crates/primitives/src/prune/target.rs index af6781897c2..b314ae9d038 100644 --- a/crates/primitives/src/prune/target.rs +++ b/crates/primitives/src/prune/target.rs @@ -1,7 +1,4 @@ -use crate::{ - prune::PrunePartError, serde_helper::deserialize_opt_prune_mode_with_min_blocks, BlockNumber, - PruneMode, PrunePart, -}; +use crate::{serde_helper::deserialize_opt_prune_mode_with_min_blocks, BlockNumber, PruneMode}; use paste::paste; use serde::{Deserialize, Serialize}; @@ -22,16 +19,10 @@ pub struct PruneModes { )] pub receipts: Option, /// Account History pruning configuration. - #[serde( - skip_serializing_if = "Option::is_none", - deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<64, _>" - )] + #[serde(skip_serializing_if = "Option::is_none")] pub account_history: Option, /// Storage History pruning configuration. - #[serde( - skip_serializing_if = "Option::is_none", - deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<64, _>" - )] + #[serde(skip_serializing_if = "Option::is_none")] pub storage_history: Option, } @@ -60,15 +51,12 @@ macro_rules! impl_prune_parts { $human_part, " pruning needs to be done, inclusive, according to the provided tip." )] - pub fn [](&self, tip: BlockNumber) -> Result, PrunePartError> { - match &self.$part { - Some(mode) => - match self.prune_target_block(mode, tip, $min_blocks) { - Some(block) => Ok(Some((block, *mode))), - None => Err(PrunePartError::Configuration(PrunePart::[<$human_part>])) - } - None => Ok(None) - } + pub fn [](&self, tip: BlockNumber) -> Option<(BlockNumber, PruneMode)> { + self.$part.as_ref().and_then(|mode| { + self.prune_target_block(mode, tip, $min_blocks).map(|block| { + (block, *mode) + }) + }) } } )+ @@ -119,17 +107,17 @@ impl PruneModes { Some(tip.saturating_sub(*distance)) } PruneMode::Before(n) if tip.saturating_sub(*n) >= min_blocks.unwrap_or_default() => { - Some(n.saturating_sub(1)) + Some(*n) } _ => None, } } impl_prune_parts!( - (sender_recovery, "SenderRecovery", None), - (transaction_lookup, "TransactionLookup", None), + (sender_recovery, "Sender Recovery", None), + (transaction_lookup, "Transaction Lookup", None), (receipts, "Receipts", Some(64)), - (account_history, "AccountHistory", Some(64)), - (storage_history, "StorageHistory", Some(64)) + (account_history, "Account History", None), + (storage_history, "Storage History", None) ); } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 393b35f72be..85b286c1462 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -175,10 +175,6 @@ impl Decodable for ReceiptWithBloom { buf.advance(1); Self::decode_receipt(buf, TxType::EIP1559) } - 0x03 => { - buf.advance(1); - Self::decode_receipt(buf, TxType::EIP4844) - } #[cfg(feature = "optimism")] 0x7E => { buf.advance(1); @@ -287,9 +283,6 @@ impl<'a> ReceiptWithBloomEncoder<'a> { TxType::EIP1559 => { out.put_u8(0x02); } - TxType::EIP4844 => { - out.put_u8(0x03); - } _ => unreachable!("legacy handled; qed."), } out.put_slice(payload.as_ref()); @@ -309,7 +302,7 @@ impl<'a> Encodable for ReceiptWithBloomEncoder<'a> { fn length(&self) -> usize { let mut payload_len = self.receipt_length(); // account for eip-2718 type prefix and set the list - if matches!(self.receipt.tx_type, TxType::EIP1559 | TxType::EIP2930 | TxType::EIP4844) { + if matches!(self.receipt.tx_type, TxType::EIP1559 | TxType::EIP2930) { payload_len += 1; // we include a string header for typed receipts, so include the length here payload_len += length_of_length(payload_len); diff --git a/crates/primitives/src/transaction/eip1559.rs b/crates/primitives/src/transaction/eip1559.rs deleted file mode 100644 index 3108c6e51e6..00000000000 --- a/crates/primitives/src/transaction/eip1559.rs +++ /dev/null @@ -1,123 +0,0 @@ -use super::access_list::AccessList; -use crate::{Bytes, ChainId, TransactionKind}; -use reth_codecs::{main_codec, Compact}; -use std::mem; - -/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). -#[main_codec] -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] -pub struct TxEip1559 { - /// Added as EIP-pub 155: Simple replay attack protection - pub chain_id: u64, - /// A scalar value equal to the number of transactions sent by the sender; formally Tn. - pub nonce: u64, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - pub gas_limit: u64, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasFeeCap` - pub max_fee_per_gas: u128, - /// Max Priority fee that transaction is paying - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasTipCap` - pub max_priority_fee_per_gas: u128, - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - pub to: TransactionKind, - /// A scalar value equal to the number of Wei to - /// be transferred to the message call’s recipient or, - /// in the case of contract creation, as an endowment - /// to the newly created account; formally Tv. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub value: u128, - /// The accessList specifies a list of addresses and storage keys; - /// these addresses and storage keys are added into the `accessed_addresses` - /// and `accessed_storage_keys` global sets (introduced in EIP-2929). - /// A gas cost is charged, though at a discount relative to the cost of - /// accessing outside the list. - pub access_list: AccessList, - /// Input has two uses depending if transaction is Create or Call (if `to` field is None or - /// Some). pub init: An unlimited size byte array specifying the - /// EVM-code for the account initialisation procedure CREATE, - /// data: An unlimited size byte array specifying the - /// input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxEip1559 { - /// Calculates a heuristic for the in-memory size of the [TxEip1559] transaction. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::() + // chain_id - mem::size_of::() + // nonce - mem::size_of::() + // gas_limit - mem::size_of::() + // max_fee_per_gas - mem::size_of::() + // max_priority_fee_per_gas - self.to.size() + // to - mem::size_of::() + // value - self.access_list.size() + // access_list - self.input.len() // input - } -} - -#[cfg(test)] -mod tests { - use super::TxEip1559; - use crate::{ - transaction::{signature::Signature, TransactionKind}, - AccessList, Address, Transaction, TransactionSigned, H256, U256, - }; - use std::str::FromStr; - - #[test] - fn recover_signer_eip1559() { - use crate::hex_literal::hex; - - let signer: Address = hex!("dd6b8b3dc6b7ad97db52f08a275ff4483e024cea").into(); - let hash: H256 = - hex!("0ec0b6a2df4d87424e5f6ad2a654e27aaeb7dac20ae9e8385cc09087ad532ee0").into(); - - let tx = Transaction::Eip1559( TxEip1559 { - chain_id: 1, - nonce: 0x42, - gas_limit: 44386, - to: TransactionKind::Call( hex!("6069a6c32cf691f5982febae4faf8a6f3ab2f0f6").into()), - value: 0, - input: hex!("a22cb4650000000000000000000000005eee75727d804a2b13038928d36f8b188945a57a0000000000000000000000000000000000000000000000000000000000000000").into(), - max_fee_per_gas: 0x4a817c800, - max_priority_fee_per_gas: 0x3b9aca00, - access_list: AccessList::default(), - }); - - let sig = Signature { - r: U256::from_str("0x840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565") - .unwrap(), - s: U256::from_str("0x25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1") - .unwrap(), - odd_y_parity: false, - }; - - let signed_tx = TransactionSigned::from_transaction_and_signature(tx, sig); - assert_eq!(signed_tx.hash(), hash, "Expected same hash"); - assert_eq!(signed_tx.recover_signer(), Some(signer), "Recovering signer should pass."); - } -} diff --git a/crates/primitives/src/transaction/eip2930.rs b/crates/primitives/src/transaction/eip2930.rs deleted file mode 100644 index ecd6ecb7ec2..00000000000 --- a/crates/primitives/src/transaction/eip2930.rs +++ /dev/null @@ -1,127 +0,0 @@ -use super::access_list::AccessList; -use crate::{Bytes, ChainId, TransactionKind}; -use reth_codecs::{main_codec, Compact}; -use std::mem; - -/// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). -#[main_codec] -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] -pub struct TxEip2930 { - /// Added as EIP-pub 155: Simple replay attack protection - pub chain_id: ChainId, - /// A scalar value equal to the number of transactions sent by the sender; formally Tn. - pub nonce: u64, - /// A scalar value equal to the number of - /// Wei to be paid per unit of gas for all computation - /// costs incurred as a result of the execution of this transaction; formally Tp. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub gas_price: u128, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - pub gas_limit: u64, - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - pub to: TransactionKind, - /// A scalar value equal to the number of Wei to - /// be transferred to the message call’s recipient or, - /// in the case of contract creation, as an endowment - /// to the newly created account; formally Tv. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub value: u128, - /// The accessList specifies a list of addresses and storage keys; - /// these addresses and storage keys are added into the `accessed_addresses` - /// and `accessed_storage_keys` global sets (introduced in EIP-2929). - /// A gas cost is charged, though at a discount relative to the cost of - /// accessing outside the list. - pub access_list: AccessList, - /// Input has two uses depending if transaction is Create or Call (if `to` field is None or - /// Some). pub init: An unlimited size byte array specifying the - /// EVM-code for the account initialisation procedure CREATE, - /// data: An unlimited size byte array specifying the - /// input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxEip2930 { - /// Calculates a heuristic for the in-memory size of the [TxEip2930] transaction. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::() + // chain_id - mem::size_of::() + // nonce - mem::size_of::() + // gas_price - mem::size_of::() + // gas_limit - self.to.size() + // to - mem::size_of::() + // value - self.access_list.size() + // access_list - self.input.len() // input - } -} - -#[cfg(test)] -mod tests { - use super::TxEip2930; - use crate::{ - transaction::{signature::Signature, TransactionKind}, - Address, Bytes, Transaction, TransactionSigned, U256, - }; - use bytes::BytesMut; - use reth_rlp::{Decodable, Encodable}; - - #[test] - fn test_decode_create() { - // tests that a contract creation tx encodes and decodes properly - let request = Transaction::Eip2930(TxEip2930 { - chain_id: 1u64, - nonce: 0, - gas_price: 1, - gas_limit: 2, - to: TransactionKind::Create, - value: 3, - input: Bytes::from(vec![1, 2]), - access_list: Default::default(), - }); - let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() }; - let tx = TransactionSigned::from_transaction_and_signature(request, signature); - - let mut encoded = BytesMut::new(); - tx.encode(&mut encoded); - assert_eq!(encoded.len(), tx.length()); - - let decoded = TransactionSigned::decode(&mut &*encoded).unwrap(); - assert_eq!(decoded, tx); - } - - #[test] - fn test_decode_call() { - let request = Transaction::Eip2930(TxEip2930 { - chain_id: 1u64, - nonce: 0, - gas_price: 1, - gas_limit: 2, - to: TransactionKind::Call(Address::default()), - value: 3, - input: Bytes::from(vec![1, 2]), - access_list: Default::default(), - }); - - let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() }; - - let tx = TransactionSigned::from_transaction_and_signature(request, signature); - - let mut encoded = BytesMut::new(); - tx.encode(&mut encoded); - assert_eq!(encoded.len(), tx.length()); - - let decoded = TransactionSigned::decode(&mut &*encoded).unwrap(); - assert_eq!(decoded, tx); - } -} diff --git a/crates/primitives/src/transaction/eip4844.rs b/crates/primitives/src/transaction/eip4844.rs deleted file mode 100644 index 34b43e19bb6..00000000000 --- a/crates/primitives/src/transaction/eip4844.rs +++ /dev/null @@ -1,118 +0,0 @@ -use super::access_list::AccessList; -use crate::{constants::eip4844::DATA_GAS_PER_BLOB, Bytes, ChainId, TransactionKind, H256}; -use reth_codecs::{main_codec, Compact}; -use std::mem; - -/// [EIP-4844 Blob Transaction](https://eips.ethereum.org/EIPS/eip-4844#blob-transaction) -/// -/// A transaction with blob hashes and max blob fee -#[main_codec] -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] -pub struct TxEip4844 { - /// Added as EIP-pub 155: Simple replay attack protection - pub chain_id: u64, - /// A scalar value equal to the number of transactions sent by the sender; formally Tn. - pub nonce: u64, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - pub gas_limit: u64, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasFeeCap` - pub max_fee_per_gas: u128, - /// Max Priority fee that transaction is paying - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - /// - /// This is also known as `GasTipCap` - pub max_priority_fee_per_gas: u128, - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - pub to: TransactionKind, - /// A scalar value equal to the number of Wei to - /// be transferred to the message call’s recipient or, - /// in the case of contract creation, as an endowment - /// to the newly created account; formally Tv. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub value: u128, - /// The accessList specifies a list of addresses and storage keys; - /// these addresses and storage keys are added into the `accessed_addresses` - /// and `accessed_storage_keys` global sets (introduced in EIP-2929). - /// A gas cost is charged, though at a discount relative to the cost of - /// accessing outside the list. - pub access_list: AccessList, - - /// It contains a vector of fixed size hash(32 bytes) - pub blob_versioned_hashes: Vec, - - /// Max fee per data gas - /// - /// aka BlobFeeCap - pub max_fee_per_blob_gas: u128, - - /// Input has two uses depending if transaction is Create or Call (if `to` field is None or - /// Some). pub init: An unlimited size byte array specifying the - /// EVM-code for the account initialisation procedure CREATE, - /// data: An unlimited size byte array specifying the - /// input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxEip4844 { - /// Returns the effective gas price for the given `base_fee`. - pub fn effective_gas_price(&self, base_fee: Option) -> u128 { - match base_fee { - None => self.max_fee_per_gas, - Some(base_fee) => { - // if the tip is greater than the max priority fee per gas, set it to the max - // priority fee per gas + base fee - let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); - if tip > self.max_priority_fee_per_gas { - self.max_priority_fee_per_gas + base_fee as u128 - } else { - // otherwise return the max fee per gas - self.max_fee_per_gas - } - } - } - } - - /// Returns the total gas for all blobs in this transaction. - #[inline] - pub fn blob_gas(&self) -> u64 { - // SAFETY: we don't expect u64::MAX / DATA_GAS_PER_BLOB hashes in a single transaction - self.blob_versioned_hashes.len() as u64 * DATA_GAS_PER_BLOB - } - - /// Calculates a heuristic for the in-memory size of the [TxEip4844] transaction. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::() + // chain_id - mem::size_of::() + // nonce - mem::size_of::() + // gas_limit - mem::size_of::() + // max_fee_per_gas - mem::size_of::() + // max_priority_fee_per_gas - self.to.size() + // to - mem::size_of::() + // value - self.access_list.size() + // access_list - self.input.len() + // input - self.blob_versioned_hashes.capacity() * mem::size_of::() + // blob hashes size - mem::size_of::() // max_fee_per_data_gas - } -} diff --git a/crates/primitives/src/transaction/legacy.rs b/crates/primitives/src/transaction/legacy.rs deleted file mode 100644 index cd324732bd5..00000000000 --- a/crates/primitives/src/transaction/legacy.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::{Bytes, ChainId, TransactionKind}; -use reth_codecs::{main_codec, Compact}; -use std::mem; - -/// Legacy transaction. -#[main_codec] -#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] -pub struct TxLegacy { - /// Added as EIP-155: Simple replay attack protection - pub chain_id: Option, - /// A scalar value equal to the number of transactions sent by the sender; formally Tn. - pub nonce: u64, - /// A scalar value equal to the number of - /// Wei to be paid per unit of gas for all computation - /// costs incurred as a result of the execution of this transaction; formally Tp. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub gas_price: u128, - /// A scalar value equal to the maximum - /// amount of gas that should be used in executing - /// this transaction. This is paid up-front, before any - /// computation is done and may not be increased - /// later; formally Tg. - pub gas_limit: u64, - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - pub to: TransactionKind, - /// A scalar value equal to the number of Wei to - /// be transferred to the message call’s recipient or, - /// in the case of contract creation, as an endowment - /// to the newly created account; formally Tv. - /// - /// As ethereum circulation is around 120mil eth as of 2022 that is around - /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: - /// 340282366920938463463374607431768211455 - pub value: u128, - /// Input has two uses depending if transaction is Create or Call (if `to` field is None or - /// Some). pub init: An unlimited size byte array specifying the - /// EVM-code for the account initialisation procedure CREATE, - /// data: An unlimited size byte array specifying the - /// input data of the message call, formally Td. - pub input: Bytes, -} - -impl TxLegacy { - /// Calculates a heuristic for the in-memory size of the [TxLegacy] transaction. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::>() + // chain_id - mem::size_of::() + // nonce - mem::size_of::() + // gas_price - mem::size_of::() + // gas_limit - self.to.size() + // to - mem::size_of::() + // value - self.input.len() // input - } -} - -#[cfg(test)] -mod tests { - use super::TxLegacy; - use crate::{ - transaction::{signature::Signature, TransactionKind}, - Address, Transaction, TransactionSigned, H256, U256, - }; - - #[test] - fn recover_signer_legacy() { - use crate::hex_literal::hex; - - let signer: Address = hex!("398137383b3d25c92898c656696e41950e47316b").into(); - let hash: H256 = - hex!("bb3a336e3f823ec18197f1e13ee875700f08f03e2cab75f0d0b118dabb44cba0").into(); - - let tx = Transaction::Legacy(TxLegacy { - chain_id: Some(1), - nonce: 0x18, - gas_price: 0xfa56ea00, - gas_limit: 119902, - to: TransactionKind::Call( hex!("06012c8cf97bead5deae237070f9587f8e7a266d").into()), - value: 0x1c6bf526340000u64.into(), - input: hex!("f7d8c88300000000000000000000000000000000000000000000000000000000000cee6100000000000000000000000000000000000000000000000000000000000ac3e1").into(), - }); - - let sig = Signature { - r: U256::from_be_bytes(hex!( - "2a378831cf81d99a3f06a18ae1b6ca366817ab4d88a70053c41d7a8f0368e031" - )), - s: U256::from_be_bytes(hex!( - "450d831a05b6e418724436c05c155e0a1b7b921015d0fbc2f667aed709ac4fb5" - )), - odd_y_parity: false, - }; - - let signed_tx = TransactionSigned::from_transaction_and_signature(tx, sig); - assert_eq!(signed_tx.hash(), hash, "Expected same hash"); - assert_eq!(signed_tx.recover_signer(), Some(signer), "Recovering signer should pass."); - } -} diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 94aff3b17de..7c56a807752 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1,41 +1,306 @@ +use std::mem; + use crate::{ compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR}, - keccak256, Address, Bytes, TxHash, H256, + keccak256, Address, Bytes, ChainId, TxHash, H256, }; pub use access_list::{AccessList, AccessListItem, AccessListWithGasUsed}; use bytes::{Buf, BytesMut}; use derive_more::{AsRef, Deref}; pub use error::InvalidTransactionError; pub use meta::TransactionMeta; -use reth_codecs::{add_arbitrary_tests, derive_arbitrary, Compact}; +use reth_codecs::{add_arbitrary_tests, derive_arbitrary, main_codec, Compact}; use reth_rlp::{ length_of_length, Decodable, DecodeError, Encodable, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE, }; use serde::{Deserialize, Serialize}; pub use signature::Signature; -use std::mem; pub use tx_type::{TxType, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID}; -#[cfg(feature = "optimism")] -pub use optimism::{TxDeposit, DEPOSIT_TX_TYPE, DEPOSIT_VERSION}; -pub use eip1559::TxEip1559; -pub use eip2930::TxEip2930; -pub use eip4844::TxEip4844; -pub use legacy::TxLegacy; - -#[cfg(feature = "optimism")] -mod optimism; mod access_list; -mod eip1559; -mod eip2930; -mod eip4844; mod error; -mod legacy; mod meta; mod signature; mod tx_type; pub(crate) mod util; +#[cfg(feature = "optimism")] +mod optimism; +#[cfg(feature = "optimism")] +pub use optimism::{TxDeposit, DEPOSIT_TX_TYPE, DEPOSIT_VERSION}; + +/// Legacy transaction. +#[main_codec] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] +pub struct TxLegacy { + /// Added as EIP-155: Simple replay attack protection + pub chain_id: Option, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the number of + /// Wei to be paid per unit of gas for all computation + /// costs incurred as a result of the execution of this transaction; formally Tp. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub gas_price: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + pub gas_limit: u64, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + pub to: TransactionKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub value: u128, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Bytes, +} + +impl TxLegacy { + /// Calculates a heuristic for the in-memory size of the [TxLegacy] transaction. + #[inline] + fn size(&self) -> usize { + mem::size_of::>() + // chain_id + mem::size_of::() + // nonce + mem::size_of::() + // gas_price + mem::size_of::() + // gas_limit + self.to.size() + // to + mem::size_of::() + // value + self.input.len() // input + } +} + +/// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). +#[main_codec] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] +pub struct TxEip2930 { + /// Added as EIP-pub 155: Simple replay attack protection + pub chain_id: ChainId, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the number of + /// Wei to be paid per unit of gas for all computation + /// costs incurred as a result of the execution of this transaction; formally Tp. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub gas_price: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + pub gas_limit: u64, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + pub to: TransactionKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub value: u128, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: AccessList, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Bytes, +} + +impl TxEip2930 { + /// Calculates a heuristic for the in-memory size of the [TxEip2930] transaction. + #[inline] + pub fn size(&self) -> usize { + mem::size_of::() + // chain_id + mem::size_of::() + // nonce + mem::size_of::() + // gas_price + mem::size_of::() + // gas_limit + self.to.size() + // to + mem::size_of::() + // value + self.access_list.size() + // access_list + self.input.len() // input + } +} + +/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). +#[main_codec] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] +pub struct TxEip1559 { + /// Added as EIP-pub 155: Simple replay attack protection + pub chain_id: u64, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + pub gas_limit: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub max_fee_per_gas: u128, + /// Max Priority fee that transaction is paying + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub max_priority_fee_per_gas: u128, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + pub to: TransactionKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub value: u128, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: AccessList, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Bytes, +} + +impl TxEip1559 { + /// Calculates a heuristic for the in-memory size of the [TxEip1559] transaction. + #[inline] + pub fn size(&self) -> usize { + mem::size_of::() + // chain_id + mem::size_of::() + // nonce + mem::size_of::() + // gas_limit + mem::size_of::() + // max_fee_per_gas + mem::size_of::() + // max_priority_fee_per_gas + self.to.size() + // to + mem::size_of::() + // value + self.access_list.size() + // access_list + self.input.len() // input + } +} + +/// A transaction with blob hashes and max blob fee +#[main_codec] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] +pub struct TxEip4844 { + /// Added as EIP-pub 155: Simple replay attack protection + pub chain_id: u64, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + pub gas_limit: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub max_fee_per_gas: u128, + /// Max Priority fee that transaction is paying + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub max_priority_fee_per_gas: u128, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + pub to: TransactionKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub value: u128, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: AccessList, + + /// It contains a vector of fixed size hash(32 bytes) + pub blob_hashes: Vec, + + /// Max fee per data gas + pub max_fee_per_blob: u128, + + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Bytes, +} + +impl TxEip4844 { + /// Calculates a heuristic for the in-memory size of the [TxEip4844] transaction. + #[inline] + pub fn size(&self) -> usize { + mem::size_of::() + // chain_id + mem::size_of::() + // nonce + mem::size_of::() + // gas_limit + mem::size_of::() + // max_fee_per_gas + mem::size_of::() + // max_priority_fee_per_gas + self.to.size() + // to + mem::size_of::() + // value + self.access_list.size() + // access_list + self.input.len() + // input + self.blob_hashes.capacity() * mem::size_of::() + // blob hashes size + mem::size_of::() // blob fee cap + } +} + /// A raw transaction. /// /// Transaction types were introduced in [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718). @@ -715,7 +980,7 @@ impl TxEip1559 { Some(base_fee) => { // if the tip is greater than the max priority fee per gas, set it to the max // priority fee per gas + base fee - let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); + let tip = self.max_fee_per_gas - base_fee as u128; if tip > self.max_priority_fee_per_gas { self.max_priority_fee_per_gas + base_fee as u128 } else { @@ -1394,8 +1659,9 @@ impl IntoRecoveredTransaction for TransactionSignedEcRecovered { #[cfg(test)] mod tests { use crate::{ - transaction::{signature::Signature, TransactionKind, TxEip1559, TxLegacy}, - Address, Bytes, Transaction, TransactionSigned, TransactionSignedEcRecovered, H256, U256, + transaction::{signature::Signature, TransactionKind, TxEip1559, TxEip2930, TxLegacy}, + AccessList, Address, Bytes, Transaction, TransactionSigned, TransactionSignedEcRecovered, + H256, U256, }; use bytes::BytesMut; use ethers_core::utils::hex; @@ -1409,6 +1675,30 @@ mod tests { assert_eq!(DecodeError::InputTooShort, res); } + #[test] + fn test_decode_create() { + // tests that a contract creation tx encodes and decodes properly + let request = Transaction::Eip2930(TxEip2930 { + chain_id: 1u64, + nonce: 0, + gas_price: 1, + gas_limit: 2, + to: TransactionKind::Create, + value: 3, + input: Bytes::from(vec![1, 2]), + access_list: Default::default(), + }); + let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() }; + let tx = TransactionSigned::from_transaction_and_signature(request, signature); + + let mut encoded = BytesMut::new(); + tx.encode(&mut encoded); + assert_eq!(encoded.len(), tx.length()); + + let decoded = TransactionSigned::decode(&mut &*encoded).unwrap(); + assert_eq!(decoded, tx); + } + #[test] fn test_decode_create_goerli() { // test that an example create tx from goerli decodes properly @@ -1425,6 +1715,31 @@ mod tests { assert_eq!(tx_bytes, encoded); } + #[test] + fn test_decode_call() { + let request = Transaction::Eip2930(TxEip2930 { + chain_id: 1u64, + nonce: 0, + gas_price: 1, + gas_limit: 2, + to: TransactionKind::Call(Address::default()), + value: 3, + input: Bytes::from(vec![1, 2]), + access_list: Default::default(), + }); + + let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() }; + + let tx = TransactionSigned::from_transaction_and_signature(request, signature); + + let mut encoded = BytesMut::new(); + tx.encode(&mut encoded); + assert_eq!(encoded.len(), tx.length()); + + let decoded = TransactionSigned::decode(&mut &*encoded).unwrap(); + assert_eq!(decoded, tx); + } + #[test] fn decode_transaction_consumes_buffer() { let bytes = &mut &hex::decode("b87502f872041a8459682f008459682f0d8252089461815774383099e24810ab832a5b2a5425c154d58829a2241af62c000080c001a059e6b67f48fb32e7e570dfb11e042b5ad2e55e3ce3ce9cd989c7e06e07feeafda0016b83f4f980694ed2eee4d10667242b1f40dc406901b34125b008d334d47469").unwrap()[..]; @@ -1586,6 +1901,72 @@ mod tests { assert_eq!(tx.recover_signer(), Some(signer), "Recovering signer should pass."); } + #[test] + fn recover_signer_legacy() { + use crate::hex_literal::hex; + + let signer: Address = hex!("398137383b3d25c92898c656696e41950e47316b").into(); + let hash: H256 = + hex!("bb3a336e3f823ec18197f1e13ee875700f08f03e2cab75f0d0b118dabb44cba0").into(); + + let tx = Transaction::Legacy(TxLegacy { + chain_id: Some(1), + nonce: 0x18, + gas_price: 0xfa56ea00, + gas_limit: 119902, + to: TransactionKind::Call( hex!("06012c8cf97bead5deae237070f9587f8e7a266d").into()), + value: 0x1c6bf526340000u64.into(), + input: hex!("f7d8c88300000000000000000000000000000000000000000000000000000000000cee6100000000000000000000000000000000000000000000000000000000000ac3e1").into(), + }); + + let sig = Signature { + r: U256::from_be_bytes(hex!( + "2a378831cf81d99a3f06a18ae1b6ca366817ab4d88a70053c41d7a8f0368e031" + )), + s: U256::from_be_bytes(hex!( + "450d831a05b6e418724436c05c155e0a1b7b921015d0fbc2f667aed709ac4fb5" + )), + odd_y_parity: false, + }; + + let signed_tx = TransactionSigned::from_transaction_and_signature(tx, sig); + assert_eq!(signed_tx.hash(), hash, "Expected same hash"); + assert_eq!(signed_tx.recover_signer(), Some(signer), "Recovering signer should pass."); + } + + #[test] + fn recover_signer_eip1559() { + use crate::hex_literal::hex; + + let signer: Address = hex!("dd6b8b3dc6b7ad97db52f08a275ff4483e024cea").into(); + let hash: H256 = + hex!("0ec0b6a2df4d87424e5f6ad2a654e27aaeb7dac20ae9e8385cc09087ad532ee0").into(); + + let tx = Transaction::Eip1559( TxEip1559 { + chain_id: 1, + nonce: 0x42, + gas_limit: 44386, + to: TransactionKind::Call( hex!("6069a6c32cf691f5982febae4faf8a6f3ab2f0f6").into()), + value: 0, + input: hex!("a22cb4650000000000000000000000005eee75727d804a2b13038928d36f8b188945a57a0000000000000000000000000000000000000000000000000000000000000000").into(), + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + access_list: AccessList::default(), + }); + + let sig = Signature { + r: U256::from_str("0x840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565") + .unwrap(), + s: U256::from_str("0x25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1") + .unwrap(), + odd_y_parity: false, + }; + + let signed_tx = TransactionSigned::from_transaction_and_signature(tx, sig); + assert_eq!(signed_tx.hash(), hash, "Expected same hash"); + assert_eq!(signed_tx.recover_signer(), Some(signer), "Recovering signer should pass."); + } + #[test] fn test_envelop_encode() { // random tx: diff --git a/crates/primitives/src/transaction/tx_type.rs b/crates/primitives/src/transaction/tx_type.rs index 66b6db2524f..5b256c2d9c8 100644 --- a/crates/primitives/src/transaction/tx_type.rs +++ b/crates/primitives/src/transaction/tx_type.rs @@ -13,21 +13,11 @@ pub const EIP2930_TX_TYPE_ID: u8 = 1; /// Identifier for [TxEip1559](crate::TxEip1559) transaction. pub const EIP1559_TX_TYPE_ID: u8 = 2; -/// Identifier for [TxEip4844](crate::TxEip4844) transaction. -#[allow(unused)] -pub(crate) const EIP4844_TX_TYPE_ID: u8 = 3; - /// Identifier for [TxDeposit](crate::TxDeposit) transaction. #[cfg(feature = "optimism")] use crate::DEPOSIT_TX_TYPE; /// Transaction Type -/// -/// Currently being used as 2-bit type when encoding it to [`Compact`] on -/// [`crate::TransactionSignedNoHash`]. Adding more transaction types will break the codec and -/// database format. -/// -/// Other required changes when adding a new type can be seen on [PR#3953](https://github.com/paradigmxyz/reth/pull/3953/files). #[derive_arbitrary(compact)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)] pub enum TxType { @@ -38,8 +28,6 @@ pub enum TxType { EIP2930 = 1_isize, /// Transaction with Priority fee EIP1559 = 2_isize, - /// Shard Blob Transactions - EIP-4844 - EIP4844 = 3_isize, /// OP Deposit transaction. #[cfg(feature = "optimism")] DEPOSIT = DEPOSIT_TX_TYPE as isize, @@ -51,7 +39,6 @@ impl From for u8 { TxType::Legacy => LEGACY_TX_TYPE_ID, TxType::EIP2930 => EIP2930_TX_TYPE_ID, TxType::EIP1559 => EIP1559_TX_TYPE_ID, - TxType::EIP4844 => EIP4844_TX_TYPE_ID, #[cfg(feature = "optimism")] TxType::DEPOSIT => DEPOSIT_TX_TYPE, } @@ -76,10 +63,9 @@ impl Compact for TxType { TxType::Legacy => LEGACY_TX_TYPE_ID as usize, TxType::EIP2930 => EIP2930_TX_TYPE_ID as usize, TxType::EIP1559 => EIP1559_TX_TYPE_ID as usize, - TxType::EIP4844 => 3, _ => { buf.put_u8(self as u8); - 4 + 3 } } } @@ -93,7 +79,6 @@ impl Compact for TxType { 0 => TxType::Legacy, 1 => TxType::EIP2930, 2 => TxType::EIP1559, - 3 => TxType::EIP4844, _ => { let identifier = buf.get_u8() as usize; match identifier { diff --git a/crates/prune/Cargo.toml b/crates/prune/Cargo.toml index 99a4901cb13..13d5ae4f916 100644 --- a/crates/prune/Cargo.toml +++ b/crates/prune/Cargo.toml @@ -20,8 +20,8 @@ reth-interfaces.workspace = true # misc tracing.workspace = true thiserror.workspace = true -itertools.workspace = true -rayon.workspace = true +itertools = "0.10" +rayon = "1.6.0" [dev-dependencies] # reth diff --git a/crates/prune/src/error.rs b/crates/prune/src/error.rs index 1a31a039422..fdc0af4484a 100644 --- a/crates/prune/src/error.rs +++ b/crates/prune/src/error.rs @@ -4,9 +4,6 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum PrunerError { - #[error(transparent)] - PrunePart(#[from] reth_primitives::PrunePartError), - #[error("Inconsistent data: {0}")] InconsistentData(&'static str), diff --git a/crates/prune/src/pruner.rs b/crates/prune/src/pruner.rs index 3dae8bcb04f..de020dcd272 100644 --- a/crates/prune/src/pruner.rs +++ b/crates/prune/src/pruner.rs @@ -72,13 +72,13 @@ impl Pruner { let provider = self.provider_factory.provider_rw()?; if let Some((to_block, prune_mode)) = - self.modes.prune_target_block_receipts(tip_block_number)? + self.modes.prune_target_block_receipts(tip_block_number) { self.prune_receipts(&provider, to_block, prune_mode)?; } if let Some((to_block, prune_mode)) = - self.modes.prune_target_block_transaction_lookup(tip_block_number)? + self.modes.prune_target_block_transaction_lookup(tip_block_number) { self.prune_transaction_lookup(&provider, to_block, prune_mode)?; } @@ -160,18 +160,14 @@ impl Pruner { return Ok(()) } }; - let total = range.clone().count(); - let mut processed = 0; provider.prune_table_in_batches::( range, self.batch_sizes.receipts, - |entries| { - processed += entries; + |receipts| { trace!( target: "pruner", - %entries, - progress = format!("{:.1}%", 100.0 * processed as f64 / total as f64), + %receipts, "Pruned receipts" ); }, @@ -205,8 +201,6 @@ impl Pruner { } }; let last_tx_num = *range.end(); - let total = range.clone().count(); - let mut processed = 0; for i in range.step_by(self.batch_sizes.transaction_lookup) { // The `min` ensures that the transaction range doesn't exceed the last transaction @@ -229,16 +223,19 @@ impl Pruner { } // Pre-sort hashes to prune them in order - hashes.sort_unstable(); - - let entries = provider.prune_table::(hashes)?; - processed += entries; - trace!( - target: "pruner", - %entries, - progress = format!("{:.1}%", 100.0 * processed as f64 / total as f64), - "Pruned transaction lookup" - ); + hashes.sort(); + + provider.prune_table_in_batches::( + hashes, + self.batch_sizes.transaction_lookup, + |entries| { + trace!( + target: "pruner", + %entries, + "Pruned transaction lookup" + ); + }, + )?; } provider.save_prune_checkpoint( diff --git a/crates/revm/revm-inspectors/src/tracing/builder/geth.rs b/crates/revm/revm-inspectors/src/tracing/builder/geth.rs index 2f02b32cfa6..a3eaa3233fd 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/geth.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/geth.rs @@ -4,12 +4,8 @@ use crate::tracing::{ types::{CallTraceNode, CallTraceStepStackItem}, TracingInspectorConfig, }; -use reth_primitives::{Address, Bytes, H256, U256}; -use reth_rpc_types::trace::geth::{ - AccountState, CallConfig, CallFrame, DefaultFrame, DiffMode, GethDefaultTracingOptions, - PreStateConfig, PreStateFrame, PreStateMode, StructLog, -}; -use revm::{db::DatabaseRef, primitives::ResultAndState}; +use reth_primitives::{Address, Bytes, H256}; +use reth_rpc_types::trace::geth::*; use std::collections::{BTreeMap, HashMap, VecDeque}; /// A type for creating geth style traces @@ -151,75 +147,4 @@ impl GethTraceBuilder { } } } - - /// Returns the accounts necessary for transaction execution. - /// - /// The prestate mode returns the accounts necessary to execute a given transaction. - /// diff_mode returns the differences between the transaction's pre and post-state. - /// - /// * `state` - The state post-transaction execution. - /// * `diff_mode` - if prestate is in diff or prestate mode. - /// * `db` - The database to fetch state pre-transaction execution. - pub fn geth_prestate_traces( - &self, - ResultAndState { state, .. }: &ResultAndState, - prestate_config: PreStateConfig, - db: DB, - ) -> Result - where - DB: DatabaseRef, - { - let account_diffs: Vec<_> = - state.into_iter().map(|(addr, acc)| (*addr, &acc.info)).collect(); - - if prestate_config.is_diff_mode() { - let mut prestate = PreStateMode::default(); - for (addr, _) in account_diffs { - let db_acc = db.basic(addr)?.unwrap_or_default(); - prestate.0.insert( - addr, - AccountState { - balance: Some(db_acc.balance), - nonce: Some(U256::from(db_acc.nonce)), - code: db_acc.code.as_ref().map(|code| Bytes::from(code.original_bytes())), - storage: None, - }, - ); - } - self.update_storage_from_trace(&mut prestate.0, false); - Ok(PreStateFrame::Default(prestate)) - } else { - let mut state_diff = DiffMode::default(); - for (addr, changed_acc) in account_diffs { - let db_acc = db.basic(addr)?.unwrap_or_default(); - let pre_state = AccountState { - balance: Some(db_acc.balance), - nonce: Some(U256::from(db_acc.nonce)), - code: db_acc.code.as_ref().map(|code| Bytes::from(code.original_bytes())), - storage: None, - }; - let post_state = AccountState { - balance: Some(changed_acc.balance), - nonce: Some(U256::from(changed_acc.nonce)), - code: changed_acc.code.as_ref().map(|code| Bytes::from(code.original_bytes())), - storage: None, - }; - state_diff.pre.insert(addr, pre_state); - state_diff.post.insert(addr, post_state); - } - self.update_storage_from_trace(&mut state_diff.pre, false); - self.update_storage_from_trace(&mut state_diff.post, true); - Ok(PreStateFrame::Diff(state_diff)) - } - } - - fn update_storage_from_trace( - &self, - account_states: &mut BTreeMap, - post_value: bool, - ) { - for node in self.nodes.iter() { - node.geth_update_account_storage(account_states, post_value); - } - } } diff --git a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs index 7c3720621bc..cce86c43445 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs @@ -330,7 +330,7 @@ impl ParityTraceBuilder { let maybe_execution = Some(VmExecutedOperation { used: step.gas_cost, - push: step.new_stack.into_iter().map(|new_stack| new_stack.into()).collect(), + push: step.new_stack.map(|new_stack| new_stack.into()), mem: maybe_memory, store: maybe_storage, }); diff --git a/crates/revm/revm-inspectors/src/tracing/mod.rs b/crates/revm/revm-inspectors/src/tracing/mod.rs index de8a3b3b24a..fe6c5b8609d 100644 --- a/crates/revm/revm-inspectors/src/tracing/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/mod.rs @@ -395,6 +395,7 @@ where if self.config.record_steps { self.gas_inspector.step_end(interp, data, is_static, eval); self.fill_step_on_step_end(interp, data, eval); + return eval } InstructionResult::Continue } diff --git a/crates/revm/revm-inspectors/src/tracing/types.rs b/crates/revm/revm-inspectors/src/tracing/types.rs index 83c720dd281..22bebdbb247 100644 --- a/crates/revm/revm-inspectors/src/tracing/types.rs +++ b/crates/revm/revm-inspectors/src/tracing/types.rs @@ -3,7 +3,7 @@ use crate::tracing::{config::TraceStyle, utils::convert_memory}; use reth_primitives::{abi::decode_revert_reason, bytes::Bytes, Address, H256, U256}; use reth_rpc_types::trace::{ - geth::{AccountState, CallFrame, CallLogFrame, GethDefaultTracingOptions, StructLog}, + geth::{CallFrame, CallLogFrame, GethDefaultTracingOptions, StructLog}, parity::{ Action, ActionType, CallAction, CallOutput, CallType, ChangedType, CreateAction, CreateOutput, Delta, SelfdestructAction, StateDiff, TraceOutput, TransactionTrace, @@ -13,7 +13,7 @@ use revm::interpreter::{ opcode, CallContext, CallScheme, CreateScheme, InstructionResult, Memory, OpCode, Stack, }; use serde::{Deserialize, Serialize}; -use std::collections::{btree_map::Entry, BTreeMap, VecDeque}; +use std::collections::{btree_map::Entry, VecDeque}; /// A unified representation of a call #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] @@ -267,12 +267,9 @@ impl CallTraceNode { opcode::CALL | opcode::STATICCALL | opcode::CALLCODE => { - // The opcode of this step is a call but it's possible that this step resulted - // in a revert or out of gas error in which case there's no actual child call executed and recorded: - if let Some(call_id) = self.children.get(child_id).copied() { - item.call_child_id = Some(call_id); - child_id += 1; - } + let call_id = self.children[child_id]; + item.call_child_id = Some(call_id); + child_id += 1; } _ => {} } @@ -446,34 +443,6 @@ impl CallTraceNode { call_frame } - - /// Adds storage in-place to account state for all accounts that were touched in the trace - /// [CallTrace] execution. - /// - /// * `account_states` - the account map updated in place. - /// * `post_value` - if true, it adds storage values after trace transaction execution, if - /// false, returns the storage values before trace execution. - pub(crate) fn geth_update_account_storage( - &self, - account_states: &mut BTreeMap, - post_value: bool, - ) { - let addr = self.trace.address; - let acc_state = account_states.entry(addr).or_insert_with(AccountState::default); - for change in self.trace.steps.iter().filter_map(|s| s.storage_change) { - let StorageChange { key, value, had_value } = change; - let storage_map = acc_state.storage.get_or_insert_with(BTreeMap::new); - let value_to_insert = if post_value { - H256::from(value) - } else { - match had_value { - Some(had_value) => H256::from(had_value), - None => continue, - } - }; - storage_map.insert(key.into(), value_to_insert); - } - } } pub(crate) struct CallTraceStepStackItem<'a> { @@ -535,9 +504,7 @@ pub(crate) struct CallTraceStep { pub(crate) gas_cost: u64, /// Change of the contract state after step execution (effect of the SLOAD/SSTORE instructions) pub(crate) storage_change: Option, - /// Final status of the step - /// - /// This is set after the step was executed. + /// Final status of the call pub(crate) status: InstructionResult, } diff --git a/crates/rpc/ipc/Cargo.toml b/crates/rpc/ipc/Cargo.toml index 0dc0bebee6d..e78c8f5dee3 100644 --- a/crates/rpc/ipc/Cargo.toml +++ b/crates/rpc/ipc/Cargo.toml @@ -23,7 +23,7 @@ pin-project.workspace = true tower = "0.4" # misc -jsonrpsee = { workspace = true, features = ["server", "client"] } +jsonrpsee = { version = "0.18", features = ["server", "client"] } serde_json.workspace = true tracing.workspace = true bytes.workspace = true diff --git a/crates/rpc/ipc/src/server/ipc.rs b/crates/rpc/ipc/src/server/ipc.rs index ff04d2c5e71..c03f3ca385a 100644 --- a/crates/rpc/ipc/src/server/ipc.rs +++ b/crates/rpc/ipc/src/server/ipc.rs @@ -6,7 +6,7 @@ use jsonrpsee::{ tracing::{rx_log_from_json, tx_log_from_str}, JsonRawValue, }, - helpers::{batch_response_error, MethodResponseResult}, + helpers::batch_response_error, server::{ logger, logger::{Logger, TransportProtocol}, @@ -219,20 +219,14 @@ pub(crate) async fn execute_call( }; tx_log_from_str(&response.as_response().result, max_log_length); - logger.on_result( - name, - response.as_response().success_or_error, - request_start, - TransportProtocol::Http, - ); + logger.on_result(name, response.as_response().success, request_start, TransportProtocol::Http); response } #[instrument(name = "notification", fields(method = notif.method.as_ref()), skip(notif, max_log_length), level = "TRACE")] fn execute_notification(notif: Notif<'_>, max_log_length: u32) -> MethodResponse { rx_log_from_json(¬if, max_log_length); - let response = - MethodResponse { result: String::new(), success_or_error: MethodResponseResult::Success }; + let response = MethodResponse { result: String::new(), success: true }; tx_log_from_str(&response.result, max_log_length); response } diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index 53a7676b112..7b220ba1123 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -16,7 +16,7 @@ reth-primitives.workspace = true reth-rpc-types.workspace = true # misc -jsonrpsee = { workspace = true, features = ["server", "macros"] } +jsonrpsee = { version = "0.18", features = ["server", "macros"] } serde_json.workspace = true [features] diff --git a/crates/rpc/rpc-api/src/engine.rs b/crates/rpc/rpc-api/src/engine.rs index 9905957e91d..756cb5473c7 100644 --- a/crates/rpc/rpc-api/src/engine.rs +++ b/crates/rpc/rpc-api/src/engine.rs @@ -21,17 +21,6 @@ pub trait EngineApi { #[method(name = "newPayloadV2")] async fn new_payload_v2(&self, payload: ExecutionPayload) -> RpcResult; - /// Post Cancun payload handler - /// - /// See also - #[method(name = "newPayloadV3")] - async fn new_payload_v3( - &self, - payload: ExecutionPayload, - versioned_hashes: Vec, - parent_beacon_block_root: H256, - ) -> RpcResult; - /// See also /// /// Caution: This should not accept the `withdrawals` field @@ -50,16 +39,6 @@ pub trait EngineApi { payload_attributes: Option, ) -> RpcResult; - /// Same as `forkchoiceUpdatedV2` but supports additional [PayloadAttributes] field. - /// - /// See also - #[method(name = "forkchoiceUpdatedV3")] - async fn fork_choice_updated_v3( - &self, - fork_choice_state: ForkchoiceState, - payload_attributes: Option, - ) -> RpcResult; - /// See also /// /// Returns the most recent version of the payload that is available in the corresponding @@ -80,16 +59,6 @@ pub trait EngineApi { #[method(name = "getPayloadV2")] async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult; - /// Post Cancun payload handler which also returns a blobs bundle. - /// - /// See also - /// - /// Returns the most recent version of the payload that is available in the corresponding - /// payload build process at the time of receiving this call. Note: - /// > Provider software MAY stop the corresponding build process after serving this call. - #[method(name = "getPayloadV3")] - async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult; - /// See also #[method(name = "getPayloadBodiesByHashV1")] async fn get_payload_bodies_by_hash_v1( @@ -117,12 +86,6 @@ pub trait EngineApi { ) -> RpcResult; /// See also - /// - /// Note: This method will be deprecated after the cancun hardfork: - /// - /// > Consensus and execution layer clients MAY remove support of this method after Cancun. If - /// > no longer supported, this method MUST be removed from the engine_exchangeCapabilities - /// > request or response list depending on whether it is consensus or execution layer client. #[method(name = "exchangeTransitionConfigurationV1")] async fn exchange_transition_configuration( &self, diff --git a/crates/rpc/rpc-builder/Cargo.toml b/crates/rpc/rpc-builder/Cargo.toml index e7f7cf826d5..aeb1d300d23 100644 --- a/crates/rpc/rpc-builder/Cargo.toml +++ b/crates/rpc/rpc-builder/Cargo.toml @@ -24,7 +24,7 @@ reth-transaction-pool.workspace = true reth-metrics = { workspace = true, features = ["common"] } # rpc/net -jsonrpsee = { workspace = true, features = ["server"] } +jsonrpsee = { version = "0.18", features = ["server"] } tower-http = { version = "0.4", features = ["full"] } tower = { version = "0.4", features = ["full"] } hyper = "0.14" @@ -34,6 +34,9 @@ strum = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } thiserror.workspace = true tracing.workspace = true +rayon.workspace = true +pin-project.workspace = true +tokio = { workspace = true, features = ["sync"] } [dev-dependencies] reth-tracing = { path = "../../tracing" } diff --git a/crates/rpc/rpc-builder/src/auth.rs b/crates/rpc/rpc-builder/src/auth.rs index 95e64b8fbfe..758713bbdeb 100644 --- a/crates/rpc/rpc-builder/src/auth.rs +++ b/crates/rpc/rpc-builder/src/auth.rs @@ -17,7 +17,7 @@ use reth_provider::{ use reth_rpc::{ eth::{cache::EthStateCache, gas_oracle::GasPriceOracle}, AuthLayer, Claims, EngineEthApi, EthApi, EthFilter, EthSubscriptionIdProvider, - JwtAuthValidator, JwtSecret, TracingCallPool, + JwtAuthValidator, JwtSecret, }; use reth_rpc_api::{servers::*, EngineApiServer}; use reth_tasks::TaskSpawner; @@ -64,7 +64,6 @@ where gas_oracle, EthConfig::default().rpc_gas_cap, Box::new(executor.clone()), - TracingCallPool::build().expect("failed to build tracing pool"), ); let eth_filter = EthFilter::new( provider, @@ -115,7 +114,7 @@ where let local_addr = server.local_addr()?; - let handle = server.start(module); + let handle = server.start(module)?; Ok(AuthServerHandle { handle, local_addr, secret }) } @@ -154,7 +153,7 @@ impl AuthServerConfig { let local_addr = server.local_addr()?; - let handle = server.start(module.inner); + let handle = server.start(module.inner)?; Ok(AuthServerHandle { handle, local_addr, secret }) } } diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index b372d3be77e..34ec4989c62 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -4,7 +4,7 @@ use reth_rpc::{ gas_oracle::GasPriceOracleConfig, RPC_DEFAULT_GAS_CAP, }, - EthApi, EthFilter, EthPubSub, TracingCallPool, + EthApi, EthFilter, EthPubSub, }; use serde::{Deserialize, Serialize}; @@ -25,8 +25,6 @@ pub struct EthHandlers { pub filter: EthFilter, /// Handler for subscriptions only available for transports that support it (ws, ipc) pub pubsub: EthPubSub, - /// The configured tracing call pool - pub tracing_call_pool: TracingCallPool, } /// Additional config values for the eth namespace diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index c66636babb0..4e86181b940 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -89,7 +89,7 @@ //! let builder = RpcModuleBuilder::new(provider, pool, network, TokioTaskExecutor::default(), events); //! //! // configure the server modules -//! let (modules, auth_module, _registry) = builder.build_with_auth_server(transports, engine_api); +//! let (modules, auth_module) = builder.build_with_auth_server(transports, engine_api); //! //! // start the servers //! let auth_config = AuthServerConfig::builder(JwtSecret::random()).build(); @@ -122,8 +122,7 @@ use reth_rpc::{ gas_oracle::GasPriceOracle, }, AdminApi, DebugApi, EngineEthApi, EthApi, EthFilter, EthPubSub, EthSubscriptionIdProvider, - NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, TracingCallGuard, TracingCallPool, TxPoolApi, - Web3Api, + NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, TracingCallGuard, TxPoolApi, Web3Api, }; use reth_rpc_api::{servers::*, EngineApiServer}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; @@ -155,6 +154,9 @@ mod eth; /// Common RPC constants. pub mod constants; +/// Additional support for tracing related rpc calls +pub mod tracing_pool; + // Rpc server metrics mod metrics; @@ -343,11 +345,7 @@ where self, module_config: TransportRpcModuleConfig, engine: EngineApi, - ) -> ( - TransportRpcModules<()>, - AuthRpcModule, - RethModuleRegistry, - ) + ) -> (TransportRpcModules<()>, AuthRpcModule) where EngineApi: EngineApiServer, { @@ -373,7 +371,7 @@ where let auth_module = registry.create_auth_module(engine); - (modules, auth_module, registry) + (modules, auth_module) } /// Configures all [RpcModule]s specific to the given [TransportRpcModuleConfig] which can be @@ -818,9 +816,15 @@ where let eth = self.eth_handlers(); self.modules.insert( RethRpcModule::Trace, - TraceApi::new(self.provider.clone(), eth.api.clone(), self.tracing_call_guard.clone()) - .into_rpc() - .into(), + TraceApi::new( + self.provider.clone(), + eth.api.clone(), + eth.cache, + Box::new(self.executor.clone()), + self.tracing_call_guard.clone(), + ) + .into_rpc() + .into(), ); self } @@ -891,13 +895,8 @@ where &mut self, namespaces: impl Iterator, ) -> Vec { - let EthHandlers { - api: eth_api, - filter: eth_filter, - pubsub: eth_pubsub, - cache: _, - tracing_call_pool: _, - } = self.with_eth(|eth| eth.clone()); + let EthHandlers { api: eth_api, cache: eth_cache, filter: eth_filter, pubsub: eth_pubsub } = + self.with_eth(|eth| eth.clone()); // Create a copy, so we can list out all the methods for rpc_ api let namespaces: Vec<_> = namespaces.collect(); @@ -934,6 +933,8 @@ where RethRpcModule::Trace => TraceApi::new( self.provider.clone(), eth_api.clone(), + eth_cache.clone(), + Box::new(self.executor.clone()), self.tracing_call_guard.clone(), ) .into_rpc() @@ -996,7 +997,6 @@ where ); let executor = Box::new(self.executor.clone()); - let tracing_call_pool = TracingCallPool::build().expect("failed to build tracing pool"); let api = EthApi::with_spawner( self.provider.clone(), self.pool.clone(), @@ -1005,7 +1005,6 @@ where gas_oracle, self.config.eth.rpc_gas_cap, executor.clone(), - tracing_call_pool.clone(), ); let filter = EthFilter::new( self.provider.clone(), @@ -1023,19 +1022,19 @@ where executor, ); - let eth = EthHandlers { api, cache, filter, pubsub, tracing_call_pool }; + let eth = EthHandlers { api, cache, filter, pubsub }; self.eth = Some(eth); } f(self.eth.as_ref().expect("exists; qed")) } /// Returns the configured [EthHandlers] or creates it if it does not exist yet - pub fn eth_handlers(&mut self) -> EthHandlers { + fn eth_handlers(&mut self) -> EthHandlers { self.with_eth(|handlers| handlers.clone()) } /// Returns the configured [EthApi] or creates it if it does not exist yet - pub fn eth_api(&mut self) -> EthApi { + fn eth_api(&mut self) -> EthApi { self.with_eth(|handlers| handlers.api.clone()) } } @@ -1460,65 +1459,6 @@ impl TransportRpcModules<()> { &self.config } - /// Merge the given Methods in the configured http methods. - /// - /// Fails if any of the methods in other is present already. - /// - /// Returns Ok(false) if no http transport is configured. - pub fn merge_http( - &mut self, - other: impl Into, - ) -> Result { - if let Some(ref mut http) = self.http { - return http.merge(other.into()).map(|_| true) - } - Ok(false) - } - - /// Merge the given Methods in the configured ws methods. - /// - /// Fails if any of the methods in other is present already. - /// - /// Returns Ok(false) if no http transport is configured. - pub fn merge_ws( - &mut self, - other: impl Into, - ) -> Result { - if let Some(ref mut ws) = self.ws { - return ws.merge(other.into()).map(|_| true) - } - Ok(false) - } - - /// Merge the given Methods in the configured ipc methods. - /// - /// Fails if any of the methods in other is present already. - /// - /// Returns Ok(false) if no ipc transport is configured. - pub fn merge_ipc( - &mut self, - other: impl Into, - ) -> Result { - if let Some(ref mut http) = self.http { - return http.merge(other.into()).map(|_| true) - } - Ok(false) - } - - /// Merge the given Methods in all configured methods. - /// - /// Fails if any of the methods in other is present already. - pub fn merge_configured( - &mut self, - other: impl Into, - ) -> Result<(), jsonrpsee::core::error::Error> { - let other = other.into(); - self.merge_http(other.clone())?; - self.merge_ws(other.clone())?; - self.merge_ipc(other.clone())?; - Ok(()) - } - /// Convenience function for starting a server pub async fn start_server(self, builder: RpcServerConfig) -> Result { builder.start(self).await @@ -1563,7 +1503,7 @@ impl WsHttpServers { config.ensure_ws_http_identical()?; if let Some(module) = http_module.or(ws_module) { - let handle = both.start(module).await; + let handle = both.start(module).await?; http_handle = Some(handle.clone()); ws_handle = Some(handle); } @@ -1572,12 +1512,12 @@ impl WsHttpServers { if let Some((server, module)) = http.and_then(|server| http_module.map(|module| (server, module))) { - http_handle = Some(server.start(module).await); + http_handle = Some(server.start(module).await?); } if let Some((server, module)) = ws.and_then(|server| ws_module.map(|module| (server, module))) { - ws_handle = Some(server.start(module).await); + ws_handle = Some(server.start(module).await?); } } } @@ -1604,10 +1544,10 @@ enum WsHttpServerKind { impl WsHttpServerKind { /// Starts the server and returns the handle - async fn start(self, module: RpcModule<()>) -> ServerHandle { + async fn start(self, module: RpcModule<()>) -> Result { match self { - WsHttpServerKind::Plain(server) => server.start(module), - WsHttpServerKind::WithCors(server) => server.start(module), + WsHttpServerKind::Plain(server) => Ok(server.start(module)?), + WsHttpServerKind::WithCors(server) => Ok(server.start(module)?), } } diff --git a/crates/rpc/rpc-builder/src/metrics.rs b/crates/rpc/rpc-builder/src/metrics.rs index ee3ed62328a..e40e2c23258 100644 --- a/crates/rpc/rpc-builder/src/metrics.rs +++ b/crates/rpc/rpc-builder/src/metrics.rs @@ -1,7 +1,4 @@ -use jsonrpsee::{ - helpers::MethodResponseResult, - server::logger::{HttpRequest, Logger, MethodKind, Params, TransportProtocol}, -}; +use jsonrpsee::server::logger::{HttpRequest, Logger, MethodKind, Params, TransportProtocol}; use reth_metrics::{ metrics::{self, Counter, Histogram}, Metrics, @@ -61,13 +58,13 @@ impl Logger for RpcServerMetrics { fn on_result( &self, _method_name: &str, - success: MethodResponseResult, + success: bool, started_at: Self::Instant, _transport: TransportProtocol, ) { // capture call duration self.call_latency.record(started_at.elapsed().as_millis() as f64); - if success.is_error() { + if !success { self.failed_calls.increment(1); } else { self.successful_calls.increment(1); diff --git a/crates/rpc/rpc/src/tracing_call.rs b/crates/rpc/rpc-builder/src/tracing_pool.rs similarity index 71% rename from crates/rpc/rpc/src/tracing_call.rs rename to crates/rpc/rpc-builder/src/tracing_pool.rs index 26956ae2d50..dd305611780 100644 --- a/crates/rpc/rpc/src/tracing_call.rs +++ b/crates/rpc/rpc-builder/src/tracing_pool.rs @@ -8,46 +8,9 @@ use std::{ task::{ready, Context, Poll}, thread, }; -use tokio::sync::{oneshot, AcquireError, OwnedSemaphorePermit, Semaphore}; - -/// RPC Tracing call guard semaphore. -/// -/// This is used to restrict the number of concurrent RPC requests to tracing methods like -/// `debug_traceTransaction` because they can consume a lot of memory and CPU. -/// -/// This types serves as an entry guard for the [TracingCallPool] and is used to rate limit parallel -/// tracing calls on the pool. -#[derive(Clone, Debug)] -pub struct TracingCallGuard(Arc); - -impl TracingCallGuard { - /// Create a new `TracingCallGuard` with the given maximum number of tracing calls in parallel. - pub fn new(max_tracing_requests: u32) -> Self { - Self(Arc::new(Semaphore::new(max_tracing_requests as usize))) - } - - /// See also [Semaphore::acquire_owned] - pub async fn acquire_owned(self) -> Result { - self.0.acquire_owned().await - } - - /// See also [Semaphore::acquire_many_owned] - pub async fn acquire_many_owned(self, n: u32) -> Result { - self.0.acquire_many_owned(n).await - } -} +use tokio::sync::oneshot; /// Used to execute tracing calls on a rayon threadpool from within a tokio runtime. -/// -/// This is a dedicated threadpool for tracing calls which are CPU bound. -/// RPC calls that perform blocking IO (disk lookups) are not executed on this pool but on the tokio -/// runtime's blocking pool, which performs poorly with CPU bound tasks. Once the tokio blocking -/// pool is saturated it is converted into a queue, tracing calls could then interfere with the -/// queue and block other RPC calls. -/// -/// See also [tokio-docs] for more information. -/// -/// [tokio-docs]: https://docs.rs/tokio/latest/tokio/index.html#cpu-bound-tasks-and-blocking-code #[derive(Clone, Debug)] pub struct TracingCallPool { pool: Arc, diff --git a/crates/rpc/rpc-engine-api/Cargo.toml b/crates/rpc/rpc-engine-api/Cargo.toml index 6e64471c26b..cd30e8250ae 100644 --- a/crates/rpc/rpc-engine-api/Cargo.toml +++ b/crates/rpc/rpc-engine-api/Cargo.toml @@ -25,12 +25,11 @@ tokio = { workspace = true, features = ["sync"] } # misc async-trait.workspace = true thiserror.workspace = true -jsonrpsee-types.workspace = true -jsonrpsee-core.workspace = true +jsonrpsee-types = "0.18" +jsonrpsee-core = "0.18" tracing.workspace = true [dev-dependencies] -reth-rlp.workspace = true reth-interfaces = { workspace = true, features = ["test-utils"] } reth-provider = { workspace = true, features = ["test-utils"] } reth-payload-builder = { workspace = true, features = ["test-utils"] } diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index 56ddc71cdf9..2a0581595f4 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -4,7 +4,7 @@ use jsonrpsee_core::RpcResult; use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_interfaces::consensus::ForkchoiceState; use reth_payload_builder::PayloadStore; -use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hardfork, H256, U64}; +use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hardfork, U64}; use reth_provider::{BlockReader, EvmEnvProvider, HeaderProvider, StateProviderFactory}; use reth_rpc_api::EngineApiServer; use reth_rpc_types::engine::{ @@ -130,26 +130,6 @@ where Ok(self.inner.beacon_consensus.fork_choice_updated(state, payload_attrs).await?) } - /// Sends a message to the beacon consensus engine to update the fork choice _with_ withdrawals, - /// but only _after_ cancun. - /// - /// See also - pub async fn fork_choice_updated_v3( - &self, - state: ForkchoiceState, - payload_attrs: Option, - ) -> EngineApiResult { - if let Some(ref attrs) = payload_attrs { - self.validate_withdrawals_presence( - EngineApiMessageVersion::V3, - attrs.timestamp.as_u64(), - attrs.withdrawals.is_some(), - )?; - } - - Ok(self.inner.beacon_consensus.fork_choice_updated(state, payload_attrs).await?) - } - /// Returns the most recent version of the payload that is available in the corresponding /// payload build process at the time of receiving this call. /// @@ -341,7 +321,7 @@ where return Err(EngineApiError::NoWithdrawalsPostShanghai) } } - EngineApiMessageVersion::V2 | EngineApiMessageVersion::V3 => { + EngineApiMessageVersion::V2 => { if is_shanghai && !has_withdrawals { return Err(EngineApiError::NoWithdrawalsPostShanghai) } @@ -375,15 +355,6 @@ where Ok(EngineApi::new_payload_v2(self, payload).await?) } - async fn new_payload_v3( - &self, - _payload: ExecutionPayload, - _versioned_hashes: Vec, - _parent_beacon_block_root: H256, - ) -> RpcResult { - Err(jsonrpsee_types::error::ErrorCode::MethodNotFound.into()) - } - /// Handler for `engine_forkchoiceUpdatedV1` /// See also /// @@ -408,17 +379,6 @@ where Ok(EngineApi::fork_choice_updated_v2(self, fork_choice_state, payload_attributes).await?) } - /// Handler for `engine_forkchoiceUpdatedV2` - /// - /// See also - async fn fork_choice_updated_v3( - &self, - _fork_choice_state: ForkchoiceState, - _payload_attributes: Option, - ) -> RpcResult { - Err(jsonrpsee_types::error::ErrorCode::MethodNotFound.into()) - } - /// Handler for `engine_getPayloadV1` /// /// Returns the most recent version of the payload that is available in the corresponding @@ -449,10 +409,6 @@ where Ok(EngineApi::get_payload_v2(self, payload_id).await?) } - async fn get_payload_v3(&self, _payload_id: PayloadId) -> RpcResult { - Err(jsonrpsee_types::error::ErrorCode::MethodNotFound.into()) - } - /// Handler for `engine_getPayloadBodiesByHashV1` /// See also async fn get_payload_bodies_by_hash_v1( diff --git a/crates/rpc/rpc-engine-api/src/lib.rs b/crates/rpc/rpc-engine-api/src/lib.rs index ba36670c5aa..fa440801b11 100644 --- a/crates/rpc/rpc-engine-api/src/lib.rs +++ b/crates/rpc/rpc-engine-api/src/lib.rs @@ -29,10 +29,3 @@ pub use message::EngineApiMessageVersion; // re-export server trait for convenience pub use reth_rpc_api::EngineApiServer; - -#[cfg(test)] -#[allow(unused_imports)] -mod tests { - // silence unused import warning - use reth_rlp as _; -} diff --git a/crates/rpc/rpc-engine-api/src/message.rs b/crates/rpc/rpc-engine-api/src/message.rs index c0d6b85d511..9d000ed7440 100644 --- a/crates/rpc/rpc-engine-api/src/message.rs +++ b/crates/rpc/rpc-engine-api/src/message.rs @@ -4,11 +4,5 @@ pub enum EngineApiMessageVersion { /// Version 1 V1, /// Version 2 - /// - /// Added for shanghai hardfork. V2, - /// Version 3 - /// - /// Added for cancun hardfork. - V3, } diff --git a/crates/rpc/rpc-engine-api/tests/it/main.rs b/crates/rpc/rpc-engine-api/tests/it/main.rs deleted file mode 100644 index cf02e709823..00000000000 --- a/crates/rpc/rpc-engine-api/tests/it/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod payload; - -fn main() {} diff --git a/crates/rpc/rpc-engine-api/tests/it/payload.rs b/crates/rpc/rpc-engine-api/tests/it/payload.rs deleted file mode 100644 index bc9f1f4249a..00000000000 --- a/crates/rpc/rpc-engine-api/tests/it/payload.rs +++ /dev/null @@ -1,127 +0,0 @@ -//! Some payload tests - -use assert_matches::assert_matches; -use reth_interfaces::test_utils::generators::{ - self, random_block, random_block_range, random_header, -}; -use reth_primitives::{ - bytes::{Bytes, BytesMut}, - proofs::{self}, - Block, SealedBlock, TransactionSigned, H256, U256, -}; -use reth_rlp::{Decodable, DecodeError}; -use reth_rpc_types::engine::{ExecutionPayload, ExecutionPayloadBodyV1, PayloadError}; - -fn transform_block Block>(src: SealedBlock, f: F) -> ExecutionPayload { - let unsealed = src.unseal(); - let mut transformed: Block = f(unsealed); - // Recalculate roots - transformed.header.transactions_root = proofs::calculate_transaction_root(&transformed.body); - transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.ommers); - SealedBlock { - header: transformed.header.seal_slow(), - body: transformed.body, - ommers: transformed.ommers, - withdrawals: transformed.withdrawals, - } - .into() -} - -#[test] -fn payload_body_roundtrip() { - let mut rng = generators::rng(); - for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) { - let unsealed = block.clone().unseal(); - let payload_body: ExecutionPayloadBodyV1 = unsealed.into(); - - assert_eq!( - Ok(block.body), - payload_body - .transactions - .iter() - .map(|x| TransactionSigned::decode(&mut &x[..])) - .collect::, _>>(), - ); - - assert_eq!(block.withdrawals, payload_body.withdrawals); - } -} - -#[test] -fn payload_validation() { - let mut rng = generators::rng(); - let block = random_block(&mut rng, 100, Some(H256::random()), Some(3), Some(0)); - - // Valid extra data - let block_with_valid_extra_data = transform_block(block.clone(), |mut b| { - b.header.extra_data = BytesMut::zeroed(32).freeze().into(); - b - }); - assert_matches!(TryInto::::try_into(block_with_valid_extra_data), Ok(_)); - - // Invalid extra data - let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze(); - let invalid_extra_data_block = transform_block(block.clone(), |mut b| { - b.header.extra_data = block_with_invalid_extra_data.clone().into(); - b - }); - assert_matches!( - TryInto::::try_into(invalid_extra_data_block), - Err(PayloadError::ExtraData(data)) if data == block_with_invalid_extra_data - ); - - // Zero base fee - let block_with_zero_base_fee = transform_block(block.clone(), |mut b| { - b.header.base_fee_per_gas = Some(0); - b - }); - assert_matches!( - TryInto::::try_into(block_with_zero_base_fee), - Err(PayloadError::BaseFee(val)) if val == U256::ZERO - ); - - // Invalid encoded transactions - let mut payload_with_invalid_txs: ExecutionPayload = block.clone().into(); - payload_with_invalid_txs.transactions.iter_mut().for_each(|tx| { - *tx = Bytes::new().into(); - }); - assert_matches!( - TryInto::::try_into(payload_with_invalid_txs), - Err(PayloadError::Decode(DecodeError::InputTooShort)) - ); - - // Non empty ommers - let block_with_ommers = transform_block(block.clone(), |mut b| { - b.ommers.push(random_header(&mut rng, 100, None).unseal()); - b - }); - assert_matches!( - TryInto::::try_into(block_with_ommers.clone()), - Err(PayloadError::BlockHash { consensus, .. }) - if consensus == block_with_ommers.block_hash - ); - - // None zero difficulty - let block_with_difficulty = transform_block(block.clone(), |mut b| { - b.header.difficulty = U256::from(1); - b - }); - assert_matches!( - TryInto::::try_into(block_with_difficulty.clone()), - Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_difficulty.block_hash - ); - - // None zero nonce - let block_with_nonce = transform_block(block.clone(), |mut b| { - b.header.nonce = 1; - b - }); - assert_matches!( - TryInto::::try_into(block_with_nonce.clone()), - Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_nonce.block_hash - ); - - // Valid block - let valid_block = block; - assert_matches!(TryInto::::try_into(valid_block), Ok(_)); -} diff --git a/crates/rpc/rpc-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index 5d0d1a2b2cf..93415adb681 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -21,7 +21,7 @@ async-trait.workspace = true futures.workspace = true # misc -jsonrpsee = { workspace = true, features = ["client", "async-client"] } +jsonrpsee = { version = "0.18", features = ["client", "async-client"] } serde_json.workspace = true [dev-dependencies] diff --git a/crates/rpc/rpc-testing-util/src/debug.rs b/crates/rpc/rpc-testing-util/src/debug.rs index aedb83ac16f..2aad67e1754 100644 --- a/crates/rpc/rpc-testing-util/src/debug.rs +++ b/crates/rpc/rpc-testing-util/src/debug.rs @@ -40,20 +40,11 @@ impl DebugApiExt for T { /// A helper type that can be used to build a javascript tracer. #[derive(Debug, Clone, Default)] pub struct JsTracerBuilder { - /// `setup_body` is invoked once at the beginning, during the construction of a given - /// transaction. setup_body: Option, - /// `fault_body` is invoked when an error happens during the execution of an opcode which - /// wasn't reported in step. fault_body: Option, - /// `result_body` returns a JSON-serializable value to the RPC caller. result_body: Option, - /// `enter_body` is invoked on stepping in of an internal call. enter_body: Option, - /// `step_body` is called for each step of the EVM, or when an error occurs, as the specified - /// transaction is traced. step_body: Option, - /// `exit_body` is invoked on stepping out of an internal call. exit_body: Option, } diff --git a/crates/rpc/rpc-types/Cargo.toml b/crates/rpc/rpc-types/Cargo.toml index 20b03a3b7cb..0c2db471dd6 100644 --- a/crates/rpc/rpc-types/Cargo.toml +++ b/crates/rpc/rpc-types/Cargo.toml @@ -19,17 +19,17 @@ reth-rlp.workspace = true thiserror.workspace = true # misc -itertools.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true -jsonrpsee-types = { workspace = true, optional = true } - -[features] -default = ["jsonrpsee-types"] +jsonrpsee-types = { version = "0.18" } [dev-dependencies] +# reth +reth-interfaces = { workspace = true, features = ["test-utils"] } + # misc rand.workspace = true +assert_matches = "1.5" similar-asserts = "1.4" [features] diff --git a/crates/rpc/rpc-types/src/eth/block.rs b/crates/rpc/rpc-types/src/eth/block.rs index 5b07b300878..ff47937af4e 100644 --- a/crates/rpc/rpc-types/src/eth/block.rs +++ b/crates/rpc/rpc-types/src/eth/block.rs @@ -267,9 +267,6 @@ impl Header { base_fee_per_gas, extra_data, withdrawals_root, - // TODO: add header fields to the rpc header - blob_gas_used: _, - excess_blob_gas: _, }, hash, } = primitive_header; @@ -379,6 +376,7 @@ pub struct BlockOverrides { #[cfg(test)] mod tests { use super::*; + use jsonrpsee_types::SubscriptionResponse; #[test] fn test_full_conversion() { @@ -390,9 +388,7 @@ mod tests { } #[test] - #[cfg(feature = "jsonrpsee-types")] - fn serde_json_header() { - use jsonrpsee_types::SubscriptionResponse; + fn serde_header() { let resp = r#"{"jsonrpc":"2.0","method":"eth_subscribe","params":{"subscription":"0x7eef37ff35d471f8825b1c8f67a5d3c0","result":{"hash":"0x7a7ada12e140961a32395059597764416499f4178daf1917193fad7bd2cc6386","parentHash":"0xdedbd831f496e705e7f2ec3c8dcb79051040a360bf1455dbd7eb8ea6ad03b751","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":"0x8","gasUsed":"0x0","gasLimit":"0x1c9c380","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x642aa48f","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000"}}}"#; let _header: SubscriptionResponse<'_, Header> = serde_json::from_str(resp).unwrap(); diff --git a/crates/rpc/rpc-types/src/eth/engine/error.rs b/crates/rpc/rpc-types/src/eth/engine/error.rs new file mode 100644 index 00000000000..36feba4dfd8 --- /dev/null +++ b/crates/rpc/rpc-types/src/eth/engine/error.rs @@ -0,0 +1,58 @@ +//! Commonly used errors for the `engine_` namespace. + +/// List of Engine API errors used in RPC, see +/// +/// Note: These are all errors that can be returned by the `engine_` namespace in the error case. +/// +/// TODO: get rid of this +#[derive(Debug, Copy, PartialEq, Eq, Clone, thiserror::Error)] +pub enum EngineRpcError { + /// Invalid JSON was received by the server. + #[error("Invalid JSON was received by the server")] + ParseError, + /// The JSON sent is not a valid Request object. + #[error("The JSON sent is not a valid Request object")] + InvalidRequest, + /// The method does not exist / is not available. + #[error("The method does not exist / is not available")] + MethodNotFound, + /// Invalid method parameter(s). + #[error("Invalid method parameter(s)")] + InvalidParams, + /// Internal JSON-RPC error. + #[error("Internal JSON-RPC error")] + InternalError, + /// Generic client error while processing request. + #[error("Server error")] + ServerError, + /// Payload does not exist / is not available. + #[error("Unknown payload")] + UnknownPayload, + /// Forkchoice state is invalid / inconsistent. + #[error("Invalid forkchoice state")] + InvalidForkchoiceState, + /// Payload attributes are invalid / inconsistent. + #[error("Invalid payload attributes")] + InvalidPayloadAttributes, + /// Number of requested entities is too large. + #[error("Too large request")] + TooLargeRequest, +} + +impl EngineRpcError { + /// Returns the error code as `i32` + pub const fn code(&self) -> i32 { + match *self { + EngineRpcError::ParseError => -32700, + EngineRpcError::InvalidRequest => -32600, + EngineRpcError::MethodNotFound => -32601, + EngineRpcError::InvalidParams => -32602, + EngineRpcError::InternalError => -32603, + EngineRpcError::ServerError => -32000, + EngineRpcError::UnknownPayload => -38001, + EngineRpcError::InvalidForkchoiceState => -38002, + EngineRpcError::InvalidPayloadAttributes => -38003, + EngineRpcError::TooLargeRequest => -38004, + } + } +} diff --git a/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs b/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs index f1c2ca4a79c..ea215df5c16 100644 --- a/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs +++ b/crates/rpc/rpc-types/src/eth/engine/forkchoice.rs @@ -50,7 +50,6 @@ pub enum ForkchoiceUpdateError { UnknownFinalBlock, } -#[cfg(feature = "jsonrpsee-types")] impl From for jsonrpsee_types::error::ErrorObject<'static> { fn from(value: ForkchoiceUpdateError) -> Self { match value { diff --git a/crates/rpc/rpc-types/src/eth/engine/mod.rs b/crates/rpc/rpc-types/src/eth/engine/mod.rs index 2a814374fb2..5212588decc 100644 --- a/crates/rpc/rpc-types/src/eth/engine/mod.rs +++ b/crates/rpc/rpc-types/src/eth/engine/mod.rs @@ -2,11 +2,12 @@ #![allow(missing_docs)] +mod error; mod forkchoice; mod payload; mod transition; -pub use self::{forkchoice::*, payload::*, transition::*}; +pub use self::{error::*, forkchoice::*, payload::*, transition::*}; /// The list of supported Engine capabilities pub const CAPABILITIES: [&str; 9] = [ diff --git a/crates/rpc/rpc-types/src/eth/engine/payload.rs b/crates/rpc/rpc-types/src/eth/engine/payload.rs index 72eba8bab8e..3a0fcc4b9ec 100644 --- a/crates/rpc/rpc-types/src/eth/engine/payload.rs +++ b/crates/rpc/rpc-types/src/eth/engine/payload.rs @@ -46,10 +46,6 @@ pub struct ExecutionPayloadEnvelope { /// The expected value to be received by the feeRecipient in wei #[serde(rename = "blockValue")] pub block_value: U256, - // - // // TODO(mattsse): for V3 - // #[serde(rename = "blobsBundle", skip_serializing_if = "Option::is_none")] - // pub blobs_bundle: Option, } impl ExecutionPayloadEnvelope { @@ -172,9 +168,6 @@ impl TryFrom for SealedBlock { ommers_hash: EMPTY_LIST_HASH, difficulty: Default::default(), nonce: Default::default(), - // TODO: add conversion once ExecutionPayload has 4844 fields - blob_gas_used: None, - excess_blob_gas: None, } .seal_slow(); @@ -194,14 +187,6 @@ impl TryFrom for SealedBlock { } } -/// This includes all bundled blob related data of an executed payload. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct BlobsBundleV1 { - pub commitments: Vec, - pub proofs: Vec, - pub blobs: Vec, -} - /// Error that can occur when handling payloads. #[derive(thiserror::Error, Debug)] pub enum PayloadError { @@ -271,12 +256,6 @@ pub struct PayloadAttributes { #[serde(default, skip_serializing_if = "Option::is_none")] pub withdrawals: Option>, - /// Root of the parent beacon block enabled with V3. - /// - /// See also - #[serde(default, skip_serializing_if = "Option::is_none")] - pub parent_beacon_block_root: Option, - /// Transactions is a field for rollups: the transactions list is forced into the block #[cfg(feature = "optimism")] #[serde(default, skip_serializing_if = "Option::is_none")] @@ -372,25 +351,25 @@ impl From for PayloadStatusEnum { #[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")] pub enum PayloadStatusEnum { /// VALID is returned by the engine API in the following calls: - /// - newPayload: if the payload was already known or was just validated and executed - /// - forkchoiceUpdate: if the chain accepted the reorg (might ignore if it's stale) + /// - newPayloadV1: if the payload was already known or was just validated and executed + /// - forkchoiceUpdateV1: if the chain accepted the reorg (might ignore if it's stale) Valid, /// INVALID is returned by the engine API in the following calls: - /// - newPayload: if the payload failed to execute on top of the local chain - /// - forkchoiceUpdate: if the new head is unknown, pre-merge, or reorg to it fails + /// - newPayloadV1: if the payload failed to execute on top of the local chain + /// - forkchoiceUpdateV1: if the new head is unknown, pre-merge, or reorg to it fails Invalid { #[serde(rename = "validationError")] validation_error: String, }, /// SYNCING is returned by the engine API in the following calls: - /// - newPayload: if the payload was accepted on top of an active sync - /// - forkchoiceUpdate: if the new head was seen before, but not part of the chain + /// - newPayloadV1: if the payload was accepted on top of an active sync + /// - forkchoiceUpdateV1: if the new head was seen before, but not part of the chain Syncing, /// ACCEPTED is returned by the engine API in the following calls: - /// - newPayload: if the payload was accepted, but not processed (side chain) + /// - newPayloadV1: if the payload was accepted, but not processed (side chain) Accepted, } @@ -466,6 +445,130 @@ pub enum PayloadValidationError { #[cfg(test)] mod tests { use super::*; + use assert_matches::assert_matches; + use reth_interfaces::test_utils::generators::{ + self, random_block, random_block_range, random_header, + }; + use reth_primitives::{ + bytes::{Bytes, BytesMut}, + TransactionSigned, H256, + }; + use reth_rlp::{Decodable, DecodeError}; + + fn transform_block Block>(src: SealedBlock, f: F) -> ExecutionPayload { + let unsealed = src.unseal(); + let mut transformed: Block = f(unsealed); + // Recalculate roots + transformed.header.transactions_root = + proofs::calculate_transaction_root(&transformed.body); + transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.ommers); + SealedBlock { + header: transformed.header.seal_slow(), + body: transformed.body, + ommers: transformed.ommers, + withdrawals: transformed.withdrawals, + } + .into() + } + + #[test] + fn payload_body_roundtrip() { + let mut rng = generators::rng(); + for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) { + let unsealed = block.clone().unseal(); + let payload_body: ExecutionPayloadBodyV1 = unsealed.into(); + + assert_eq!( + Ok(block.body), + payload_body + .transactions + .iter() + .map(|x| TransactionSigned::decode(&mut &x[..])) + .collect::, _>>(), + ); + + assert_eq!(block.withdrawals, payload_body.withdrawals); + } + } + + #[test] + fn payload_validation() { + let mut rng = generators::rng(); + let block = random_block(&mut rng, 100, Some(H256::random()), Some(3), Some(0)); + + // Valid extra data + let block_with_valid_extra_data = transform_block(block.clone(), |mut b| { + b.header.extra_data = BytesMut::zeroed(32).freeze().into(); + b + }); + assert_matches!(TryInto::::try_into(block_with_valid_extra_data), Ok(_)); + + // Invalid extra data + let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze(); + let invalid_extra_data_block = transform_block(block.clone(), |mut b| { + b.header.extra_data = block_with_invalid_extra_data.clone().into(); + b + }); + assert_matches!( + TryInto::::try_into(invalid_extra_data_block), + Err(PayloadError::ExtraData(data)) if data == block_with_invalid_extra_data + ); + + // Zero base fee + let block_with_zero_base_fee = transform_block(block.clone(), |mut b| { + b.header.base_fee_per_gas = Some(0); + b + }); + assert_matches!( + TryInto::::try_into(block_with_zero_base_fee), + Err(PayloadError::BaseFee(val)) if val == U256::ZERO + ); + + // Invalid encoded transactions + let mut payload_with_invalid_txs: ExecutionPayload = block.clone().into(); + payload_with_invalid_txs.transactions.iter_mut().for_each(|tx| { + *tx = Bytes::new().into(); + }); + assert_matches!( + TryInto::::try_into(payload_with_invalid_txs), + Err(PayloadError::Decode(DecodeError::InputTooShort)) + ); + + // Non empty ommers + let block_with_ommers = transform_block(block.clone(), |mut b| { + b.ommers.push(random_header(&mut rng, 100, None).unseal()); + b + }); + assert_matches!( + TryInto::::try_into(block_with_ommers.clone()), + Err(PayloadError::BlockHash { consensus, .. }) + if consensus == block_with_ommers.block_hash + ); + + // None zero difficulty + let block_with_difficulty = transform_block(block.clone(), |mut b| { + b.header.difficulty = U256::from(1); + b + }); + assert_matches!( + TryInto::::try_into(block_with_difficulty.clone()), + Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_difficulty.block_hash + ); + + // None zero nonce + let block_with_nonce = transform_block(block.clone(), |mut b| { + b.header.nonce = 1; + b + }); + assert_matches!( + TryInto::::try_into(block_with_nonce.clone()), + Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_nonce.block_hash + ); + + // Valid block + let valid_block = block; + assert_matches!(TryInto::::try_into(valid_block), Ok(_)); + } #[test] fn serde_payload_status() { diff --git a/crates/rpc/rpc-types/src/eth/filter.rs b/crates/rpc/rpc-types/src/eth/filter.rs index bfe92fbe070..d4b6365ccc1 100644 --- a/crates/rpc/rpc-types/src/eth/filter.rs +++ b/crates/rpc/rpc-types/src/eth/filter.rs @@ -1,5 +1,5 @@ use crate::Log as RpcLog; -use itertools::{EitherOrBoth::*, Itertools}; +use jsonrpsee_types::SubscriptionId; use reth_primitives::{ bloom::{Bloom, Input}, keccak256, Address, BlockNumberOrTag, Log, H160, H256, U256, U64, @@ -9,120 +9,13 @@ use serde::{ ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer, }; -use std::{ - collections::HashSet, - hash::Hash, - ops::{Range, RangeFrom, RangeTo}, -}; +use std::ops::{Range, RangeFrom, RangeTo}; /// Helper type to represent a bloom filter used for matching logs. -#[derive(Default, Debug)] -pub struct BloomFilter(Vec); - -impl From> for BloomFilter { - fn from(src: Vec) -> Self { - BloomFilter(src) - } -} - -impl BloomFilter { - /// Returns whether the given bloom matches the list of Blooms in the current filter. - /// If the filter is empty (the list is empty), then any bloom matches - /// Otherwise, there must be at least one matche for the BloomFilter to match. - pub fn matches(&self, bloom: Bloom) -> bool { - self.0.is_empty() || self.0.iter().any(|a| bloom.contains_bloom(a)) - } -} - -#[derive(Default, Debug, PartialEq, Eq, Clone, Deserialize)] -/// FilterSet is a set of values that will be used to filter logs -pub struct FilterSet(HashSet); - -impl From for FilterSet { - fn from(src: T) -> Self { - FilterSet(HashSet::from([src])) - } -} - -impl From> for FilterSet { - fn from(src: Vec) -> Self { - FilterSet(HashSet::from_iter(src.into_iter().map(Into::into))) - } -} - -impl From> for FilterSet { - fn from(src: ValueOrArray) -> Self { - match src { - ValueOrArray::Value(val) => val.into(), - ValueOrArray::Array(arr) => arr.into(), - } - } -} - -impl From>> for FilterSet { - fn from(src: ValueOrArray>) -> Self { - match src { - ValueOrArray::Value(None) => FilterSet(HashSet::new()), - ValueOrArray::Value(Some(val)) => val.into(), - ValueOrArray::Array(arr) => { - // If the array contains at least one `null` (ie. None), as it's considered - // a "wildcard" value, the whole filter should be treated as matching everything, - // thus is empty. - if arr.iter().contains(&None) { - FilterSet(HashSet::new()) - } else { - // Otherwise, we flatten the array, knowing there are no `None` values - arr.into_iter().flatten().collect::>().into() - } - } - } - } -} - -impl FilterSet { - /// Returns wheter the filter is empty - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// Returns whether the given value matches the filter. It the filter is empty - /// any value matches. Otherwise, the filter must include the value - pub fn matches(&self, value: &T) -> bool { - self.is_empty() || self.0.contains(value) - } -} - -impl + Eq + Hash> FilterSet { - /// Returns a list of Bloom (BloomFilter) corresponding to the filter's values - pub fn to_bloom_filter(&self) -> BloomFilter { - self.0.iter().map(|a| Input::Raw(a.as_ref()).into()).collect::>().into() - } -} - -impl FilterSet { - /// Returns a ValueOrArray inside an Option, so that: - /// - If the filter is empty, it returns None - /// - If the filter has only 1 value, it returns the single value - /// - Otherwise it returns an array of values - /// This should be useful for serialization - pub fn to_value_or_array(&self) -> Option> { - let mut values = self.0.iter().cloned().collect::>(); - match values.len() { - 0 => None, - 1 => Some(ValueOrArray::Value(values.pop().expect("values length is one"))), - _ => Some(ValueOrArray::Array(values)), - } - } -} +pub type BloomFilter = Vec>; /// A single topic -pub type Topic = FilterSet; - -impl From for Topic { - fn from(src: U256) -> Self { - Into::::into(src).into() - } -} +pub type Topic = ValueOrArray>; /// Represents the target range of blocks for the filter #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -248,16 +141,16 @@ impl FilterBlockOption { } /// Filter for -#[derive(Default, Debug, PartialEq, Eq, Clone)] +#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)] pub struct Filter { /// Filter block options, specifying on which blocks the filter should /// match. // https://eips.ethereum.org/EIPS/eip-234 pub block_option: FilterBlockOption, /// Address - pub address: FilterSet
, + pub address: Option>, /// Topics (maxmimum of 4) - pub topics: [Topic; 4], + pub topics: [Option; 4], } impl Filter { @@ -386,7 +279,7 @@ impl Filter { /// ``` #[must_use] pub fn address>>(mut self, address: T) -> Self { - self.address = address.into().into(); + self.address = Some(address.into()); self } @@ -407,28 +300,28 @@ impl Filter { /// Sets topic0 (the event name for non-anonymous events) #[must_use] pub fn topic0>(mut self, topic: T) -> Self { - self.topics[0] = topic.into(); + self.topics[0] = Some(topic.into()); self } /// Sets the 1st indexed topic #[must_use] pub fn topic1>(mut self, topic: T) -> Self { - self.topics[1] = topic.into(); + self.topics[1] = Some(topic.into()); self } /// Sets the 2nd indexed topic #[must_use] pub fn topic2>(mut self, topic: T) -> Self { - self.topics[2] = topic.into(); + self.topics[2] = Some(topic.into()); self } /// Sets the 3rd indexed topic #[must_use] pub fn topic3>(mut self, topic: T) -> Self { - self.topics[3] = topic.into(); + self.topics[3] = Some(topic.into()); self } @@ -455,9 +348,64 @@ impl Filter { } } + /// Flattens the topics using the cartesian product + fn flatten(&self) -> Vec>> { + fn cartesian(lists: &[Vec>]) -> Vec>> { + let mut res = Vec::new(); + let mut list_iter = lists.iter(); + if let Some(first_list) = list_iter.next() { + for &i in first_list { + res.push(vec![i]); + } + } + for l in list_iter { + let mut tmp = Vec::new(); + for r in res { + for &el in l { + let mut tmp_el = r.clone(); + tmp_el.push(el); + tmp.push(tmp_el); + } + } + res = tmp; + } + res + } + let mut out = Vec::new(); + let mut tmp = Vec::new(); + for v in self.topics.iter() { + let v = if let Some(v) = v { + match v { + ValueOrArray::Value(s) => { + vec![*s] + } + ValueOrArray::Array(s) => { + if s.is_empty() { + vec![None] + } else { + s.clone() + } + } + } + } else { + vec![None] + }; + tmp.push(v); + } + for v in cartesian(&tmp) { + out.push(ValueOrArray::Array(v)); + } + out + } + + /// Returns an iterator over all existing topics + pub fn topics(&self) -> impl Iterator + '_ { + self.topics.iter().flatten() + } + /// Returns true if at least one topic is set pub fn has_topics(&self) -> bool { - self.topics.iter().any(|t| !t.is_empty()) + self.topics.iter().any(|t| t.is_some()) } } @@ -481,28 +429,27 @@ impl Serialize for Filter { FilterBlockOption::AtBlockHash(ref h) => s.serialize_field("blockHash", h)?, } - if let Some(address) = self.address.to_value_or_array() { - s.serialize_field("address", &address)?; + if let Some(ref address) = self.address { + s.serialize_field("address", address)?; } let mut filtered_topics = Vec::new(); - let mut filtered_topics_len = 0; - for (i, topic) in self.topics.iter().enumerate() { - if !topic.is_empty() { - filtered_topics_len = i + 1; + for i in 0..4 { + if self.topics[i].is_some() { + filtered_topics.push(&self.topics[i]); + } else { + // TODO: This can be optimized + if self.topics[i + 1..].iter().any(|x| x.is_some()) { + filtered_topics.push(&None); + } } - filtered_topics.push(topic.to_value_or_array()); } - filtered_topics.truncate(filtered_topics_len); s.serialize_field("topics", &filtered_topics)?; s.end() } } -type RawAddressFilter = ValueOrArray>; -type RawTopicsFilter = Vec>>>; - impl<'de> Deserialize<'de> for Filter { fn deserialize(deserializer: D) -> Result where @@ -524,8 +471,8 @@ impl<'de> Deserialize<'de> for Filter { let mut from_block: Option> = None; let mut to_block: Option> = None; let mut block_hash: Option> = None; - let mut address: Option> = None; - let mut topics: Option> = None; + let mut address: Option>> = None; + let mut topics: Option>>> = None; while let Some(key) = map.next_key::()? { match key.as_str() { @@ -587,21 +534,16 @@ impl<'de> Deserialize<'de> for Filter { let from_block = from_block.unwrap_or_default(); let to_block = to_block.unwrap_or_default(); let block_hash = block_hash.unwrap_or_default(); - let address = address.flatten().map(|a| a.into()).unwrap_or_default(); + let address = address.unwrap_or_default(); let topics_vec = topics.flatten().unwrap_or_default(); // maximum allowed filter len if topics_vec.len() > 4 { return Err(serde::de::Error::custom("exceeded maximum topics len")) } - let mut topics: [Topic; 4] = [ - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ]; + let mut topics: [Option; 4] = [None, None, None, None]; for (idx, topic) in topics_vec.into_iter().enumerate() { - topics[idx] = topic.map(|t| t.into()).unwrap_or_default(); + topics[idx] = topic; } let block_option = if let Some(block_hash) = block_hash { @@ -639,12 +581,47 @@ impl From> for ValueOrArray { } } +impl From for Topic { + fn from(src: H256) -> Self { + ValueOrArray::Value(Some(src)) + } +} + impl From> for ValueOrArray { fn from(src: Vec) -> Self { ValueOrArray::Array(src) } } +impl From> for Topic { + fn from(src: ValueOrArray) -> Self { + match src { + ValueOrArray::Value(val) => ValueOrArray::Value(Some(val)), + ValueOrArray::Array(arr) => arr.into(), + } + } +} + +impl> From> for Topic { + fn from(src: Vec) -> Self { + ValueOrArray::Array(src.into_iter().map(Into::into).map(Some).collect()) + } +} + +impl From
for Topic { + fn from(src: Address) -> Self { + let mut bytes = [0; 32]; + bytes[12..32].copy_from_slice(src.as_bytes()); + ValueOrArray::Value(Some(H256::from(bytes))) + } +} + +impl From for Topic { + fn from(src: U256) -> Self { + ValueOrArray::Value(Some(src.into())) + } +} + impl Serialize for ValueOrArray where T: Serialize, @@ -695,6 +672,8 @@ where pub struct FilteredParams { /// The original filter, if any pub filter: Option, + /// Flattened topics of the `filter` used to determine if the the filter matches a log. + pub flat_topics: Vec>>, } impl FilteredParams { @@ -702,43 +681,86 @@ impl FilteredParams { /// for matching pub fn new(filter: Option) -> Self { if let Some(filter) = filter { - FilteredParams { filter: Some(filter) } + let flat_topics = filter.flatten(); + FilteredParams { filter: Some(filter), flat_topics } } else { Default::default() } } /// Returns the [BloomFilter] for the given address - pub fn address_filter(address: &FilterSet
) -> BloomFilter { - address.to_bloom_filter() + pub fn address_filter(address: &Option>) -> BloomFilter { + address.as_ref().map(address_to_bloom_filter).unwrap_or_default() } /// Returns the [BloomFilter] for the given topics - pub fn topics_filter(topics: &[FilterSet]) -> Vec { - topics.iter().map(|t| t.to_bloom_filter()).collect() + pub fn topics_filter(topics: &Option>>>) -> Vec { + let mut output = Vec::new(); + if let Some(topics) = topics { + output.extend(topics.iter().map(topics_to_bloom_filter)); + } + output } /// Returns `true` if the bloom matches the topics - pub fn matches_topics(bloom: Bloom, topic_filters: &Vec) -> bool { + pub fn matches_topics(bloom: Bloom, topic_filters: &[BloomFilter]) -> bool { if topic_filters.is_empty() { return true } - // for each filter, iterate through the list of filter blooms. for each set of filter - // (each BloomFilter), the given `bloom` must match at least one of them, unless the list is - // empty (no filters). + // returns true if a filter matches for filter in topic_filters.iter() { - if !filter.matches(bloom) { - return false + let mut is_match = false; + for maybe_bloom in filter { + is_match = maybe_bloom.as_ref().map(|b| bloom.contains_bloom(b)).unwrap_or(true); + if !is_match { + break + } + } + if is_match { + return true } } - true + false } - /// Returns `true` if the bloom contains one of the address blooms, or the address blooms - /// list is empty (thus, no filters) + /// Returns `true` if the bloom contains the address pub fn matches_address(bloom: Bloom, address_filter: &BloomFilter) -> bool { - address_filter.matches(bloom) + if address_filter.is_empty() { + return true + } else { + for maybe_bloom in address_filter { + if maybe_bloom.as_ref().map(|b| bloom.contains_bloom(b)).unwrap_or(true) { + return true + } + } + } + false + } + + /// Replace None values - aka wildcards - for the log input value in that position. + pub fn replace(&self, log: &Log, topic: Topic) -> Option> { + let mut out: Vec = Vec::new(); + match topic { + ValueOrArray::Value(value) => { + if let Some(value) = value { + out.push(value); + } + } + ValueOrArray::Array(value) => { + for (k, v) in value.into_iter().enumerate() { + if let Some(v) = v { + out.push(v); + } else { + out.push(log.topics[k]); + } + } + } + }; + if out.is_empty() { + return None + } + Some(out) } /// Returns true if the filter matches the given block number @@ -783,30 +805,18 @@ impl FilteredParams { /// Returns `true` if the filter matches the given log. pub fn filter_address(&self, log: &Log) -> bool { - self.filter.as_ref().map(|f| f.address.matches(&log.address)).unwrap_or(true) - } - - /// Returns `true` if the log matches the filter's topics - pub fn filter_topics(&self, log: &Log) -> bool { - let topics = match self.filter.as_ref() { - None => return true, - Some(f) => &f.topics, - }; - for topic_tuple in topics.iter().zip_longest(log.topics.iter()) { - match topic_tuple { - // We exhausted the `log.topics`, so if there's a filter set for - // this topic index, there is no match. Otherwise (empty filter), continue. - Left(filter_topic) => { - if !filter_topic.is_empty() { + if let Some(input_address) = &self.filter.as_ref().and_then(|f| f.address.clone()) { + match input_address { + ValueOrArray::Value(x) => { + if log.address != *x { return false } } - // We exhausted the filter topics, therefore any subsequent log topic - // will match. - Right(_) => return true, - // Check that `log_topic` is included in `filter_topic` - Both(filter_topic, log_topic) => { - if !filter_topic.matches(log_topic) { + ValueOrArray::Array(x) => { + if x.is_empty() { + return true + } + if !x.contains(&log.address) { return false } } @@ -814,6 +824,98 @@ impl FilteredParams { } true } + + /// Returns `true` if the log matches any topic + pub fn filter_topics(&self, log: &Log) -> bool { + let mut out: bool = true; + for topic in self.flat_topics.iter().cloned() { + match topic { + ValueOrArray::Value(single) => { + if let Some(single) = single { + if !log.topics.starts_with(&[single]) { + out = false; + } + } + } + ValueOrArray::Array(multi) => { + if multi.is_empty() { + out = true; + continue + } + // Shrink the topics until the last item is Some. + let mut new_multi = multi; + while new_multi.iter().last().unwrap_or(&Some(H256::default())).is_none() { + new_multi.pop(); + } + // We can discard right away any logs with lesser topics than the filter. + if new_multi.len() > log.topics.len() { + out = false; + break + } + let replaced: Option> = + self.replace(log, ValueOrArray::Array(new_multi)); + if let Some(replaced) = replaced { + out = false; + if log.topics.starts_with(&replaced[..]) { + out = true; + break + } + } + } + } + } + out + } +} + +fn topics_to_bloom_filter(topics: &ValueOrArray>) -> BloomFilter { + let mut blooms = BloomFilter::new(); + match topics { + ValueOrArray::Value(topic) => { + if let Some(topic) = topic { + let bloom: Bloom = Input::Raw(topic.as_ref()).into(); + blooms.push(Some(bloom)); + } else { + blooms.push(None); + } + } + ValueOrArray::Array(topics) => { + if topics.is_empty() { + blooms.push(None); + } else { + for topic in topics.iter() { + if let Some(topic) = topic { + let bloom: Bloom = Input::Raw(topic.as_ref()).into(); + blooms.push(Some(bloom)); + } else { + blooms.push(None); + } + } + } + } + } + blooms +} + +fn address_to_bloom_filter(address: &ValueOrArray
) -> BloomFilter { + let mut blooms = BloomFilter::new(); + match address { + ValueOrArray::Value(address) => { + let bloom: Bloom = Input::Raw(address.as_ref()).into(); + blooms.push(Some(bloom)) + } + ValueOrArray::Array(addresses) => { + if addresses.is_empty() { + blooms.push(None); + } else { + for address in addresses.iter() { + let bloom: Bloom = Input::Raw(address.as_ref()).into(); + blooms.push(Some(bloom)); + } + } + } + } + blooms } /// Response of the `eth_getFilterChanges` RPC. @@ -873,7 +975,7 @@ impl<'de> Deserialize<'de> for FilterChanges { } } -/// Owned equivalent of a `SubscriptionId` +/// Owned equivalent of [SubscriptionId] #[derive(Debug, PartialEq, Clone, Hash, Eq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] #[serde(untagged)] @@ -884,22 +986,20 @@ pub enum FilterId { Str(String), } -#[cfg(feature = "jsonrpsee-types")] -impl From for jsonrpsee_types::SubscriptionId<'_> { +impl From for SubscriptionId<'_> { fn from(value: FilterId) -> Self { match value { - FilterId::Num(n) => jsonrpsee_types::SubscriptionId::Num(n), - FilterId::Str(s) => jsonrpsee_types::SubscriptionId::Str(s.into()), + FilterId::Num(n) => SubscriptionId::Num(n), + FilterId::Str(s) => SubscriptionId::Str(s.into()), } } } -#[cfg(feature = "jsonrpsee-types")] -impl From> for FilterId { - fn from(value: jsonrpsee_types::SubscriptionId<'_>) -> Self { +impl From> for FilterId { + fn from(value: SubscriptionId<'_>) -> Self { match value { - jsonrpsee_types::SubscriptionId::Num(n) => FilterId::Num(n), - jsonrpsee_types::SubscriptionId::Str(s) => FilterId::Str(s.into_owned()), + SubscriptionId::Num(n) => FilterId::Num(n), + SubscriptionId::Str(s) => FilterId::Str(s.into_owned()), } } } @@ -907,7 +1007,6 @@ impl From> for FilterId { #[cfg(test)] mod tests { use super::*; - use reth_primitives::U256; use serde_json::json; fn serialize(t: &T) -> serde_json::Value { @@ -921,36 +1020,40 @@ mod tests { similar_asserts::assert_eq!( filter.topics, [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" - .parse::() - .unwrap() - .into(), - Default::default(), - "0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778" - .parse::() - .unwrap() - .into(), - Default::default(), + Some(ValueOrArray::Array(vec![Some( + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + .parse() + .unwrap() + ),])), + Some(ValueOrArray::Array(vec![])), + Some(ValueOrArray::Array(vec![Some( + "0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778" + .parse() + .unwrap() + )])), + None ] ); - } - #[test] - fn test_filter_topics_middle_wildcard() { - let s = r#"{"fromBlock": "0xfc359e", "toBlock": "0xfc359e", "topics": [["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"], [], [null, "0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778"]]}"#; - let filter = serde_json::from_str::(s).unwrap(); - similar_asserts::assert_eq!( - filter.topics, - [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" - .parse::() - .unwrap() - .into(), - Default::default(), - Default::default(), - Default::default(), - ] - ); + let filtered_params = FilteredParams::new(Some(filter)); + let topics = filtered_params.flat_topics; + assert_eq!( + topics, + vec![ValueOrArray::Array(vec![ + Some( + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" + .parse() + .unwrap() + ), + None, + Some( + "0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778" + .parse() + .unwrap() + ), + None + ])] + ) } #[test] @@ -973,13 +1076,11 @@ mod tests { #[test] fn filter_serialization_test() { - let t1 = "0000000000000000000000009729a6fbefefc8f6005933898b13dc45c3a2c8b7" - .parse::() - .unwrap(); + let t1 = "9729a6fbefefc8f6005933898b13dc45c3a2c8b7".parse::
().unwrap(); let t2 = H256::from([0; 32]); let t3 = U256::from(123); - let t1_padded = t1; + let t1_padded = H256::from(t1); let t3_padded = H256::from({ let mut x = [0; 32]; x[31] = 123; @@ -1042,17 +1143,24 @@ mod tests { block_bloom } - fn topic_filter(topic1: H256, topic2: H256, topic3: H256) -> Filter { - Filter { + fn topic_filter( + topic1: H256, + topic2: H256, + topic3: H256, + ) -> (Filter, Option>>>) { + let filter = Filter { block_option: Default::default(), - address: Default::default(), + address: None, topics: [ - topic1.into(), - vec![topic2, topic3].into(), - Default::default(), - Default::default(), + Some(ValueOrArray::Value(Some(topic1))), + Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])), + None, + None, ], - } + }; + let filtered_params = FilteredParams::new(Some(filter.clone())); + + (filter, Some(filtered_params.flat_topics)) } #[test] @@ -1061,7 +1169,7 @@ mod tests { let topic2 = H256::random(); let topic3 = H256::random(); - let topics = topic_filter(topic1, topic2, topic3).topics; + let (_, topics) = topic_filter(topic1, topic2, topic3); let topics_bloom = FilteredParams::topics_filter(&topics); assert!(!FilteredParams::matches_topics( build_bloom(Address::random(), H256::random(), H256::random()), @@ -1075,7 +1183,7 @@ mod tests { let topic2 = H256::random(); let topic3 = H256::random(); - let topics = topic_filter(topic1, topic2, topic3).topics; + let (_, topics) = topic_filter(topic1, topic2, topic3); let _topics_bloom = FilteredParams::topics_filter(&topics); let topics_bloom = FilteredParams::topics_filter(&topics); @@ -1087,12 +1195,11 @@ mod tests { #[test] fn can_match_empty_topics() { - let filter = Filter { - block_option: Default::default(), - address: Default::default(), - topics: Default::default(), - }; - let topics = filter.topics; + let filter = + Filter { block_option: Default::default(), address: None, topics: Default::default() }; + + let filtered_params = FilteredParams::new(Some(filter)); + let topics = Some(filtered_params.flat_topics); let topics_bloom = FilteredParams::topics_filter(&topics); assert!(FilteredParams::matches_topics( @@ -1110,16 +1217,16 @@ mod tests { let filter = Filter { block_option: Default::default(), - address: rng_address.into(), + address: Some(ValueOrArray::Value(rng_address)), topics: [ - topic1.into(), - vec![topic2, topic3].into(), - Default::default(), - Default::default(), + Some(ValueOrArray::Value(Some(topic1))), + Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])), + None, + None, ], }; - let topics = filter.topics; - + let filtered_params = FilteredParams::new(Some(filter.clone())); + let topics = Some(filtered_params.flat_topics); let address_filter = FilteredParams::address_filter(&filter.address); let topics_filter = FilteredParams::topics_filter(&topics); assert!( @@ -1141,16 +1248,11 @@ mod tests { let filter = Filter { block_option: Default::default(), - address: Default::default(), - topics: [ - Default::default(), - vec![topic2, topic3].into(), - Default::default(), - Default::default(), - ], + address: None, + topics: [None, Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])), None, None], }; - let topics = filter.topics; - + let filtered_params = FilteredParams::new(Some(filter)); + let topics = Some(filtered_params.flat_topics); let topics_bloom = FilteredParams::topics_filter(&topics); assert!(FilteredParams::matches_topics( build_bloom(Address::random(), topic1, topic2), @@ -1162,16 +1264,16 @@ mod tests { fn can_match_topics_wildcard_mismatch() { let filter = Filter { block_option: Default::default(), - address: Default::default(), + address: None, topics: [ - Default::default(), - vec![H256::random(), H256::random()].into(), - Default::default(), - Default::default(), + None, + Some(ValueOrArray::Array(vec![Some(H256::random()), Some(H256::random())])), + None, + None, ], }; - let topics_input = filter.topics; - + let filtered_params = FilteredParams::new(Some(filter)); + let topics_input = Some(filtered_params.flat_topics); let topics_bloom = FilteredParams::topics_filter(&topics_input); assert!(!FilteredParams::matches_topics( build_bloom(Address::random(), H256::random(), H256::random()), @@ -1184,7 +1286,7 @@ mod tests { let rng_address = Address::random(); let filter = Filter { block_option: Default::default(), - address: rng_address.into(), + address: Some(ValueOrArray::Value(rng_address)), topics: Default::default(), }; let address_bloom = FilteredParams::address_filter(&filter.address); @@ -1200,7 +1302,7 @@ mod tests { let rng_address = Address::random(); let filter = Filter { block_option: Default::default(), - address: rng_address.into(), + address: Some(ValueOrArray::Value(rng_address)), topics: Default::default(), }; let address_bloom = FilteredParams::address_filter(&filter.address); @@ -1233,24 +1335,26 @@ mod tests { from_block: Some(4365627u64.into()), to_block: Some(4365627u64.into()), }, - address: "0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907" - .parse::
() - .unwrap() - .into(), + address: Some(ValueOrArray::Value( + "0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907".parse().unwrap() + )), topics: [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" - .parse::() - .unwrap() - .into(), - "0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75" - .parse::() - .unwrap() - .into(), - "0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078" - .parse::() - .unwrap() - .into(), - Default::default(), + Some(ValueOrArray::Value(Some( + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + .parse() + .unwrap(), + ))), + Some(ValueOrArray::Value(Some( + "0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75" + .parse() + .unwrap(), + ))), + Some(ValueOrArray::Value(Some( + "0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078" + .parse() + .unwrap(), + ))), + None, ], } ); @@ -1275,8 +1379,8 @@ mod tests { from_block: Some(4365627u64.into()), to_block: Some(4365627u64.into()), }, - address: Default::default(), - topics: Default::default(), + address: None, + topics: [None, None, None, None,], } ); } diff --git a/crates/rpc/rpc-types/src/eth/pubsub.rs b/crates/rpc/rpc-types/src/eth/pubsub.rs index bf2b3b55d44..d54f6f849a8 100644 --- a/crates/rpc/rpc-types/src/eth/pubsub.rs +++ b/crates/rpc/rpc-types/src/eth/pubsub.rs @@ -97,7 +97,7 @@ pub enum SubscriptionKind { } /// Any additional parameters for a subscription. -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] pub enum Params { /// No parameters passed. #[default] diff --git a/crates/rpc/rpc-types/src/eth/trace/geth/call.rs b/crates/rpc/rpc-types/src/eth/trace/geth/call.rs index d131f0f6a32..99085208f14 100644 --- a/crates/rpc/rpc-types/src/eth/trace/geth/call.rs +++ b/crates/rpc/rpc-types/src/eth/trace/geth/call.rs @@ -16,7 +16,7 @@ pub struct CallFrame { pub output: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub error: Option, - #[serde(default, rename = "revertReason", skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none")] pub revert_reason: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub calls: Vec, diff --git a/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs b/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs index 2f8be5ab36b..b6301da3f2e 100644 --- a/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs +++ b/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs @@ -1,4 +1,4 @@ -use reth_primitives::{serde_helper::num::from_int_or_hex_opt, Address, Bytes, H256, U256}; +use reth_primitives::{serde_helper::num::from_int_or_hex_opt, Address, H256, U256}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -29,7 +29,7 @@ pub struct AccountState { )] pub balance: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub code: Option, + pub code: Option, #[serde( default, deserialize_with = "from_int_or_hex_opt", @@ -47,12 +47,6 @@ pub struct PreStateConfig { pub diff_mode: Option, } -impl PreStateConfig { - pub fn is_diff_mode(&self) -> bool { - self.diff_mode.unwrap_or_default() - } -} - #[cfg(test)] mod tests { use super::*; @@ -92,11 +86,4 @@ mod tests { _ => unreachable!(), } } - - #[test] - fn test_is_diff_mode() { - assert!(PreStateConfig { diff_mode: Some(true) }.is_diff_mode()); - assert!(!PreStateConfig { diff_mode: Some(false) }.is_diff_mode()); - assert!(!PreStateConfig { diff_mode: None }.is_diff_mode()); - } } diff --git a/crates/rpc/rpc-types/src/eth/trace/parity.rs b/crates/rpc/rpc-types/src/eth/trace/parity.rs index f99f97de674..f3fa4eb9b1f 100644 --- a/crates/rpc/rpc-types/src/eth/trace/parity.rs +++ b/crates/rpc/rpc-types/src/eth/trace/parity.rs @@ -308,16 +308,16 @@ pub struct VmExecutedOperation { /// The total gas used. pub used: u64, /// The stack item placed, if any. - pub push: Vec, + pub push: Option, /// If altered, the memory delta. pub mem: Option, /// The altered storage value, if any. pub store: Option, } -/// A diff of some chunk of memory. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] +/// A diff of some chunk of memory. pub struct MemoryDelta { /// Offset into memory the change begins. pub off: usize, @@ -325,7 +325,6 @@ pub struct MemoryDelta { pub data: Bytes, } -/// A diff of some storage value. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct StorageDelta { diff --git a/crates/rpc/rpc-types/src/eth/transaction/mod.rs b/crates/rpc/rpc-types/src/eth/transaction/mod.rs index 9482fe64490..109257909a1 100644 --- a/crates/rpc/rpc-types/src/eth/transaction/mod.rs +++ b/crates/rpc/rpc-types/src/eth/transaction/mod.rs @@ -112,7 +112,7 @@ impl Transaction { let (gas_price, max_fee_per_gas) = match signed_tx.tx_type() { TxType::Legacy => (Some(U128::from(signed_tx.max_fee_per_gas())), None), TxType::EIP2930 => (Some(U128::from(signed_tx.max_fee_per_gas())), None), - TxType::EIP1559 | TxType::EIP4844 => { + TxType::EIP1559 => { // the gas price field for EIP1559 is set to `min(tip, gasFeeCap - baseFee) + // baseFee` let gas_price = base_fee diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index 662f7579bbf..ca3a72b64db 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -35,7 +35,7 @@ ethers-core = { workspace = true, features = ["eip712"] } revm-primitives = { workspace = true, features = ["serde"] } # rpc -jsonrpsee.workspace = true +jsonrpsee = { version = "0.18" } http = "0.2.8" http-body = "0.4.5" hyper = "0.14.24" @@ -48,7 +48,6 @@ tower = "0.4" tokio-stream = { workspace = true, features = ["sync"] } tokio-util = "0.7" pin-project.workspace = true -rayon.workspace = true bytes.workspace = true secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] } @@ -63,7 +62,7 @@ schnellru = "0.2" futures.workspace = true [dev-dependencies] -jsonrpsee = { workspace = true, features = ["client"] } +jsonrpsee = { version = "0.18", features = ["client"] } assert_matches = "1.5.0" tempfile = "3.5.0" reth-interfaces = { workspace = true, features = ["test-utils"] } diff --git a/crates/rpc/rpc/src/call_guard.rs b/crates/rpc/rpc/src/call_guard.rs new file mode 100644 index 00000000000..bec4ed3ca98 --- /dev/null +++ b/crates/rpc/rpc/src/call_guard.rs @@ -0,0 +1,26 @@ +use std::sync::Arc; +use tokio::sync::{AcquireError, OwnedSemaphorePermit, Semaphore}; + +/// RPC Tracing call guard semaphore. +/// +/// This is used to restrict the number of concurrent RPC requests to tracing methods like +/// `debug_traceTransaction` because they can consume a lot of memory and CPU. +#[derive(Clone, Debug)] +pub struct TracingCallGuard(Arc); + +impl TracingCallGuard { + /// Create a new `TracingCallGuard` with the given maximum number of tracing calls in parallel. + pub fn new(max_tracing_requests: u32) -> Self { + Self(Arc::new(Semaphore::new(max_tracing_requests as usize))) + } + + /// See also [Semaphore::acquire_owned] + pub async fn acquire_owned(self) -> Result { + self.0.acquire_owned().await + } + + /// See also [Semaphore::acquire_many_owned] + pub async fn acquire_many_owned(self, n: u32) -> Result { + self.0.acquire_many_owned(n).await + } +} diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 3fd5bdef06b..d6abad21fe2 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -2,7 +2,7 @@ use crate::{ eth::{ error::{EthApiError, EthResult}, revm_utils::{ - clone_into_empty_db, inspect, inspect_and_return_db, replay_transactions_until, + clone_into_empty_db, inspect, prepare_call_env, replay_transactions_until, result_output, EvmOverrides, }, EthTransactions, TransactionSource, @@ -40,8 +40,8 @@ use revm_primitives::{ db::{DatabaseCommit, DatabaseRef}, BlockEnv, CfgEnv, }; -use std::sync::Arc; -use tokio::sync::{mpsc, AcquireError, OwnedSemaphorePermit}; +use std::{future::Future, sync::Arc}; +use tokio::sync::{mpsc, oneshot, AcquireError, OwnedSemaphorePermit}; use tokio_stream::{wrappers::ReceiverStream, StreamExt}; /// `debug` API implementation. @@ -74,13 +74,30 @@ where Provider: BlockReaderIdExt + HeaderProvider + 'static, Eth: EthTransactions + 'static, { + /// Executes the future on a new blocking task. + async fn on_blocking_task(&self, c: C) -> EthResult + where + C: FnOnce(Self) -> F, + F: Future> + Send + 'static, + R: Send + 'static, + { + let (tx, rx) = oneshot::channel(); + let this = self.clone(); + let f = c(this); + self.inner.task_spawner.spawn_blocking(Box::pin(async move { + let res = f.await; + let _ = tx.send(res); + })); + rx.await.map_err(|_| EthApiError::InternalTracingError)? + } + /// Acquires a permit to execute a tracing call. async fn acquire_trace_permit(&self) -> Result { self.inner.tracing_call_guard.clone().acquire_owned().await } - /// Trace the entire block asynchronously - async fn trace_block_with( + /// Trace the entire block + fn trace_block_with_sync( &self, at: BlockId, transactions: Vec, @@ -90,31 +107,43 @@ where ) -> EthResult> { // replay all transactions of the block let this = self.clone(); - self.inner - .eth_api - .spawn_with_state_at_block(at, move |state| { - let mut results = Vec::with_capacity(transactions.len()); - let mut db = SubState::new(State::new(state)); - - let mut transactions = transactions.into_iter().peekable(); - while let Some(tx) = transactions.next() { - let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; - let tx = tx_env_with_recovered(&tx); - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; - let (result, state_changes) = - this.trace_transaction(opts.clone(), env, at, &mut db)?; - results.push(TraceResult::Success { result }); - - if transactions.peek().is_some() { - // need to apply the state changes of this transaction before executing the - // next transaction - db.commit(state_changes) - } + self.inner.eth_api.with_state_at_block(at, move |state| { + let mut results = Vec::with_capacity(transactions.len()); + let mut db = SubState::new(State::new(state)); + + let mut transactions = transactions.into_iter().peekable(); + while let Some(tx) = transactions.next() { + let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; + let tx = tx_env_with_recovered(&tx); + let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + let (result, state_changes) = + this.trace_transaction(opts.clone(), env, at, &mut db)?; + results.push(TraceResult::Success { result }); + + if transactions.peek().is_some() { + // need to apply the state changes of this transaction before executing the next + // transaction + db.commit(state_changes) } + } - Ok(results) - }) - .await + Ok(results) + }) + } + + /// Trace the entire block asynchronously + async fn trace_block_with( + &self, + at: BlockId, + transactions: Vec, + cfg: CfgEnv, + block_env: BlockEnv, + opts: GethDebugTracingOptions, + ) -> EthResult> { + self.on_blocking_task(|this| async move { + this.trace_block_with_sync(at, transactions, cfg, block_env, opts) + }) + .await } /// Replays the given block and returns the trace of each transaction. @@ -142,6 +171,17 @@ where &self, block_id: BlockId, opts: GethDebugTracingOptions, + ) -> EthResult> { + self.on_blocking_task( + |this| async move { this.try_debug_trace_block(block_id, opts).await }, + ) + .await + } + + async fn try_debug_trace_block( + &self, + block_id: BlockId, + opts: GethDebugTracingOptions, ) -> EthResult> { let block_hash = self .inner @@ -159,7 +199,7 @@ where // its parent block's state let state_at = block.parent_hash; - self.trace_block_with(state_at.into(), block.body, cfg, block_env, opts).await + self.trace_block_with_sync(state_at.into(), block.body, cfg, block_env, opts) } /// Trace the transaction according to the provided options. @@ -181,10 +221,8 @@ where let state_at: BlockId = block.parent_hash.into(); let block_txs = block.body; - let this = self.clone(); - self.inner - .eth_api - .spawn_with_state_at_block(state_at, move |state| { + self.on_blocking_task(|this| async move { + this.inner.eth_api.with_state_at_block(state_at, |state| { // configure env for the target transaction let tx = transaction.into_recovered(); @@ -201,7 +239,8 @@ where let env = Env { cfg, block: block_env, tx: tx_env_with_recovered(&tx) }; this.trace_transaction(opts, env, state_at, &mut db).map(|(trace, _)| trace) }) - .await + }) + .await } /// The debug_traceCall method lets you run an `eth_call` within the context of the given block @@ -211,6 +250,22 @@ where call: CallRequest, block_id: Option, opts: GethDebugTracingCallOptions, + ) -> EthResult { + self.on_blocking_task(|this| async move { + this.try_debug_trace_call(call, block_id, opts).await + }) + .await + } + + /// The debug_traceCall method lets you run an `eth_call` within the context of the given block + /// execution using the final state of parent block as the base. + /// + /// Caution: while this is async, this may still be blocking on necessary DB io. + async fn try_debug_trace_call( + &self, + call: CallRequest, + block_id: Option, + opts: GethDebugTracingCallOptions, ) -> EthResult { let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); let GethDebugTracingCallOptions { tracing_options, state_overrides, block_overrides } = @@ -223,13 +278,10 @@ where GethDebugTracerType::BuiltInTracer(tracer) => match tracer { GethDebugBuiltInTracerType::FourByteTracer => { let mut inspector = FourByteInspector::default(); - let inspector = self + let (_res, _) = self .inner .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - inspect(db, env, &mut inspector)?; - Ok(inspector) - }) + .inspect_call_at(call, at, overrides, &mut inspector) .await?; return Ok(FourByteFrame::from(inspector).into()) } @@ -243,40 +295,19 @@ where .set_record_logs(call_config.with_log.unwrap_or_default()), ); - let frame = self + let _ = self .inner .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - inspect(db, env, &mut inspector)?; - let frame = - inspector.into_geth_builder().geth_call_traces(call_config); - Ok(frame.into()) - }) + .inspect_call_at(call, at, overrides, &mut inspector) .await?; - return Ok(frame) - } - GethDebugBuiltInTracerType::PreStateTracer => { - let prestate_config = tracer_config - .into_pre_state_config() - .map_err(|_| EthApiError::InvalidTracerConfig)?; - let mut inspector = TracingInspector::new( - TracingInspectorConfig::from_geth_config(&config), - ); - let frame = - self.inner - .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - let (res, _, db) = - inspect_and_return_db(db, env, &mut inspector)?; - let frame = inspector - .into_geth_builder() - .geth_prestate_traces(&res, prestate_config, &db)?; - Ok(frame) - }) - .await?; + let frame = inspector.into_geth_builder().geth_call_traces(call_config); + return Ok(frame.into()) } + GethDebugBuiltInTracerType::PreStateTracer => { + Err(EthApiError::Unsupported("pre state tracer currently unsupported.")) + } GethDebugBuiltInTracerType::NoopTracer => Ok(NoopFrame::default().into()), }, GethDebugTracerType::JsTracer(code) => { @@ -284,10 +315,18 @@ where // for JS tracing we need to setup all async work before we can start tracing // because JSTracer and all JS types are not Send - let (_, _, at) = self.inner.eth_api.evm_env_at(at).await?; + let (cfg, block_env, at) = self.inner.eth_api.evm_env_at(at).await?; let state = self.inner.eth_api.state_at(at)?; - let db = SubState::new(State::new(state)); + let mut db = SubState::new(State::new(state)); let has_state_overrides = overrides.has_state(); + let env = prepare_call_env( + cfg, + block_env, + call, + self.inner.eth_api.call_gas_limit(), + &mut db, + overrides, + )?; // If the caller provided state overrides we need to clone the DB so the js // service has access these modifications @@ -298,17 +337,11 @@ where let to_db_service = self.spawn_js_trace_service(at, maybe_override_db)?; - let res = self - .inner - .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - let mut inspector = JsInspector::new(code, config, to_db_service)?; - let (res, _) = inspect(db, env.clone(), &mut inspector)?; - Ok(inspector.json_result(res, &env)?) - }) - .await?; + let mut inspector = JsInspector::new(code, config, to_db_service)?; + let (res, env) = inspect(db, env, &mut inspector)?; - Ok(GethTrace::JS(res)) + let result = inspector.json_result(res, &env)?; + Ok(GethTrace::JS(result)) } } } @@ -318,14 +351,8 @@ where let mut inspector = TracingInspector::new(inspector_config); - let (res, inspector) = self - .inner - .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - let (res, _) = inspect(db, env, &mut inspector)?; - Ok((res, inspector)) - }) - .await?; + let (res, _) = + self.inner.eth_api.inspect_call_at(call, at, overrides, &mut inspector).await?; let gas_used = res.result.gas_used(); let return_value = result_output(&res.result).unwrap_or_default().into(); let frame = inspector.into_geth_builder().geth_traces(gas_used, return_value, config); @@ -338,8 +365,6 @@ where /// Returns the trace frame and the state that got updated after executing the transaction. /// /// Note: this does not apply any state overrides if they're configured in the `opts`. - /// - /// Caution: this is blocking and should be performed on a blocking task. fn trace_transaction( &self, opts: GethDebugTracingOptions, @@ -374,22 +399,7 @@ where return Ok((frame.into(), res.state)) } GethDebugBuiltInTracerType::PreStateTracer => { - let prestate_config = tracer_config - .into_pre_state_config() - .map_err(|_| EthApiError::InvalidTracerConfig)?; - - let mut inspector = TracingInspector::new( - TracingInspectorConfig::from_geth_config(&config), - ); - let (res, _) = inspect(&mut *db, env, &mut inspector)?; - - let frame = inspector.into_geth_builder().geth_prestate_traces( - &res, - prestate_config, - &*db, - )?; - - return Ok((frame.into(), res.state)) + Err(EthApiError::Unsupported("prestate tracer is unimplemented yet.")) } GethDebugBuiltInTracerType::NoopTracer => { Ok((NoopFrame::default().into(), Default::default())) diff --git a/crates/rpc/rpc/src/eth/api/mod.rs b/crates/rpc/rpc/src/eth/api/mod.rs index 20ecf114e2a..de5d12f8d10 100644 --- a/crates/rpc/rpc/src/eth/api/mod.rs +++ b/crates/rpc/rpc/src/eth/api/mod.rs @@ -37,7 +37,6 @@ mod sign; mod state; mod transactions; -use crate::TracingCallPool; pub use transactions::{EthTransactions, TransactionSource}; /// `Eth` API trait. @@ -89,7 +88,6 @@ where eth_cache: EthStateCache, gas_oracle: GasPriceOracle, gas_cap: impl Into, - tracing_call_pool: TracingCallPool, ) -> Self { Self::with_spawner( provider, @@ -99,12 +97,10 @@ where gas_oracle, gas_cap.into().into(), Box::::default(), - tracing_call_pool, ) } /// Creates a new, shareable instance. - #[allow(clippy::too_many_arguments)] pub fn with_spawner( provider: Provider, pool: Pool, @@ -113,7 +109,6 @@ where gas_oracle: GasPriceOracle, gas_cap: u64, task_spawner: Box, - tracing_call_pool: TracingCallPool, ) -> Self { // get the block number of the latest block let latest_block = provider @@ -134,7 +129,6 @@ where starting_block: U256::from(latest_block), task_spawner, pending_block: Default::default(), - tracing_call_pool, }; Self { inner: Arc::new(inner) } } @@ -427,6 +421,4 @@ struct EthApiInner { task_spawner: Box, /// Cached pending block if any pending_block: Mutex>, - /// A pool dedicated to tracing calls - tracing_call_pool: TracingCallPool, } diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 7631351b32f..2e6d55198ac 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -145,8 +145,6 @@ impl PendingBlockEnv { difficulty: U256::ZERO, gas_used: cumulative_gas_used, extra_data: Default::default(), - blob_gas_used: None, - excess_blob_gas: None, }; // seal the block diff --git a/crates/rpc/rpc/src/eth/api/server.rs b/crates/rpc/rpc/src/eth/api/server.rs index 663308cd895..1cca7addc90 100644 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ b/crates/rpc/rpc/src/eth/api/server.rs @@ -392,7 +392,7 @@ where mod tests { use crate::{ eth::{cache::EthStateCache, gas_oracle::GasPriceOracle}, - EthApi, TracingCallPool, + EthApi, }; use jsonrpsee::types::error::INVALID_PARAMS_CODE; use reth_interfaces::test_utils::{generators, generators::Rng}; @@ -428,7 +428,6 @@ mod tests { cache.clone(), GasPriceOracle::new(provider, Default::default(), cache), ETHEREUM_BLOCK_GAS_LIMIT, - TracingCallPool::build().expect("failed to build tracing pool"), ) } diff --git a/crates/rpc/rpc/src/eth/api/state.rs b/crates/rpc/rpc/src/eth/api/state.rs index 2887ac58fb8..0930bf0b6c5 100644 --- a/crates/rpc/rpc/src/eth/api/state.rs +++ b/crates/rpc/rpc/src/eth/api/state.rs @@ -146,10 +146,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{ - eth::{cache::EthStateCache, gas_oracle::GasPriceOracle}, - TracingCallPool, - }; + use crate::eth::{cache::EthStateCache, gas_oracle::GasPriceOracle}; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, StorageKey, StorageValue}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; use reth_transaction_pool::test_utils::testing_pool; @@ -168,7 +165,6 @@ mod tests { cache.clone(), GasPriceOracle::new(NoopProvider::default(), Default::default(), cache), ETHEREUM_BLOCK_GAS_LIMIT, - TracingCallPool::build().expect("failed to build tracing pool"), ); let address = Address::random(); let storage = eth_api.storage_at(address, U256::ZERO.into(), None).unwrap(); @@ -190,7 +186,6 @@ mod tests { cache.clone(), GasPriceOracle::new(mock_provider, Default::default(), cache), ETHEREUM_BLOCK_GAS_LIMIT, - TracingCallPool::build().expect("failed to build tracing pool"), ); let storage_key: U256 = storage_key.into(); diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index 6d869daa604..514d436b3ab 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -40,10 +40,7 @@ use revm_primitives::{utilities::create_address, Env, ResultAndState, SpecId}; /// Helper alias type for the state's [CacheDB] pub(crate) type StateCacheDB<'r> = CacheDB>>; -/// Commonly used transaction related functions for the [EthApi] type in the `eth_` namespace. -/// -/// Async functions that are spawned onto the -/// [TracingCallPool](crate::tracing_call::TracingCallPool) begin with `spawn_` +/// Commonly used transaction related functions for the [EthApi] type in the `eth_` namespace #[async_trait::async_trait] pub trait EthTransactions: Send + Sync { /// Returns default gas limit to use for `eth_call` and tracing RPC methods. @@ -57,12 +54,6 @@ pub trait EthTransactions: Send + Sync { where F: FnOnce(StateProviderBox<'_>) -> EthResult; - /// Executes the closure with the state that corresponds to the given [BlockId] on a new task - async fn spawn_with_state_at_block(&self, at: BlockId, f: F) -> EthResult - where - F: FnOnce(StateProviderBox<'_>) -> EthResult + Send + 'static, - T: Send + 'static; - /// Returns the revm evm env for the requested [BlockId] /// /// If the [BlockId] this will return the [BlockId::Hash] of the block the env was configured @@ -130,8 +121,8 @@ pub trait EthTransactions: Send + Sync { async fn send_transaction(&self, request: TransactionRequest) -> EthResult; /// Prepares the state and env for the given [CallRequest] at the given [BlockId] and executes - /// the closure on a new task returning the result of the closure. - async fn spawn_with_call_at( + /// the closure. + async fn with_call_at( &self, request: CallRequest, at: BlockId, @@ -139,8 +130,7 @@ pub trait EthTransactions: Send + Sync { f: F, ) -> EthResult where - F: for<'r> FnOnce(StateCacheDB<'r>, Env) -> EthResult + Send + 'static, - R: Send + 'static; + F: for<'r> FnOnce(StateCacheDB<'r>, Env) -> EthResult + Send; /// Executes the call request at the given [BlockId]. async fn transact_call_at( @@ -150,9 +140,8 @@ pub trait EthTransactions: Send + Sync { overrides: EvmOverrides, ) -> EthResult<(ResultAndState, Env)>; - /// Executes the call request at the given [BlockId] on a new task and returns the result of the - /// inspect call. - async fn spawn_inspect_call_at( + /// Executes the call request at the given [BlockId] + async fn inspect_call_at( &self, request: CallRequest, at: BlockId, @@ -160,15 +149,24 @@ pub trait EthTransactions: Send + Sync { inspector: I, ) -> EthResult<(ResultAndState, Env)> where - I: for<'r> Inspector> + Send + 'static; + I: for<'r> Inspector> + Send; + + /// Executes the call request at the given [BlockId] + async fn inspect_call_at_and_return_state<'a, I>( + &'a self, + request: CallRequest, + at: BlockId, + overrides: EvmOverrides, + inspector: I, + ) -> EthResult<(ResultAndState, Env, StateCacheDB<'a>)> + where + I: Inspector> + Send; /// Executes the transaction on top of the given [BlockId] with a tracer configured by the /// config. /// /// The callback is then called with the [TracingInspector] and the [ResultAndState] after the /// configured [Env] was inspected. - /// - /// Caution: this is blocking fn trace_at( &self, env: Env, @@ -186,7 +184,7 @@ pub trait EthTransactions: Send + Sync { /// /// The callback is then called with the [TracingInspector] and the [ResultAndState] after the /// configured [Env] was inspected. - async fn spawn_trace_at_with_state( + fn trace_at_with_state( &self, env: Env, config: TracingInspectorConfig, @@ -194,10 +192,7 @@ pub trait EthTransactions: Send + Sync { f: F, ) -> EthResult where - F: for<'a> FnOnce(TracingInspector, ResultAndState, StateCacheDB<'a>) -> EthResult - + Send - + 'static, - R: Send + 'static; + F: for<'a> FnOnce(TracingInspector, ResultAndState, StateCacheDB<'a>) -> EthResult; /// Fetches the transaction and the transaction's block async fn transaction_and_block( @@ -211,10 +206,7 @@ pub trait EthTransactions: Send + Sync { /// state by executing them first. /// The callback `f` is invoked with the [ResultAndState] after the transaction was executed and /// the database that points to the beginning of the transaction. - /// - /// Note: Implementers should use a threadpool where blocking is allowed, such as - /// [TracingCallPool](crate::tracing_call::TracingCallPool). - async fn spawn_trace_transaction_in_block( + async fn trace_transaction_in_block( &self, hash: H256, config: TracingInspectorConfig, @@ -227,9 +219,7 @@ pub trait EthTransactions: Send + Sync { ResultAndState, StateCacheDB<'a>, ) -> EthResult - + Send - + 'static, - R: Send + 'static; + + Send; } #[async_trait] @@ -255,22 +245,6 @@ where f(state) } - async fn spawn_with_state_at_block(&self, at: BlockId, f: F) -> EthResult - where - F: FnOnce(StateProviderBox<'_>) -> EthResult + Send + 'static, - T: Send + 'static, - { - let this = self.clone(); - self.inner - .tracing_call_pool - .spawn(move || { - let state = this.state_at(at)?; - f(state) - }) - .await - .map_err(|_| EthApiError::InternalTracingError)? - } - async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> { if at.is_pending() { let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?; @@ -499,7 +473,7 @@ where Ok(hash) } - async fn spawn_with_call_at( + async fn with_call_at( &self, request: CallRequest, at: BlockId, @@ -507,29 +481,15 @@ where f: F, ) -> EthResult where - F: for<'r> FnOnce(StateCacheDB<'r>, Env) -> EthResult + Send + 'static, - R: Send + 'static, + F: for<'r> FnOnce(StateCacheDB<'r>, Env) -> EthResult + Send, { let (cfg, block_env, at) = self.evm_env_at(at).await?; - let this = self.clone(); - self.inner - .tracing_call_pool - .spawn(move || { - let state = this.state_at(at)?; - let mut db = SubState::new(State::new(state)); - - let env = prepare_call_env( - cfg, - block_env, - request, - this.call_gas_limit(), - &mut db, - overrides, - )?; - f(db, env) - }) - .await - .map_err(|_| EthApiError::InternalTracingError)? + let state = self.state_at(at)?; + let mut db = SubState::new(State::new(state)); + + let env = + prepare_call_env(cfg, block_env, request, self.call_gas_limit(), &mut db, overrides)?; + f(db, env) } async fn transact_call_at( @@ -538,11 +498,10 @@ where at: BlockId, overrides: EvmOverrides, ) -> EthResult<(ResultAndState, Env)> { - self.spawn_with_call_at(request, at, overrides, move |mut db, env| transact(&mut db, env)) - .await + self.with_call_at(request, at, overrides, |mut db, env| transact(&mut db, env)).await } - async fn spawn_inspect_call_at( + async fn inspect_call_at( &self, request: CallRequest, at: BlockId, @@ -550,10 +509,28 @@ where inspector: I, ) -> EthResult<(ResultAndState, Env)> where - I: for<'r> Inspector> + Send + 'static, + I: for<'r> Inspector> + Send, + { + self.with_call_at(request, at, overrides, |db, env| inspect(db, env, inspector)).await + } + + async fn inspect_call_at_and_return_state<'a, I>( + &'a self, + request: CallRequest, + at: BlockId, + overrides: EvmOverrides, + inspector: I, + ) -> EthResult<(ResultAndState, Env, StateCacheDB<'a>)> + where + I: Inspector> + Send, { - self.spawn_with_call_at(request, at, overrides, move |db, env| inspect(db, env, inspector)) - .await + let (cfg, block_env, at) = self.evm_env_at(at).await?; + let state = self.state_at(at)?; + let mut db = SubState::new(State::new(state)); + + let env = + prepare_call_env(cfg, block_env, request, self.call_gas_limit(), &mut db, overrides)?; + inspect_and_return_db(db, env, inspector) } fn trace_at( @@ -576,7 +553,7 @@ where }) } - async fn spawn_trace_at_with_state( + fn trace_at_with_state( &self, env: Env, config: TracingInspectorConfig, @@ -584,19 +561,15 @@ where f: F, ) -> EthResult where - F: for<'a> FnOnce(TracingInspector, ResultAndState, StateCacheDB<'a>) -> EthResult - + Send - + 'static, - R: Send + 'static, + F: for<'a> FnOnce(TracingInspector, ResultAndState, StateCacheDB<'a>) -> EthResult, { - self.spawn_with_state_at_block(at, move |state| { + self.with_state_at_block(at, |state| { let db = SubState::new(State::new(state)); let mut inspector = TracingInspector::new(config); let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?; f(inspector, res, db) }) - .await } async fn transaction_and_block( @@ -617,7 +590,7 @@ where Ok(block.map(|block| (transaction, block.seal(block_hash)))) } - async fn spawn_trace_transaction_in_block( + async fn trace_transaction_in_block( &self, hash: H256, config: TracingInspectorConfig, @@ -630,9 +603,7 @@ where ResultAndState, StateCacheDB<'a>, ) -> EthResult - + Send - + 'static, - R: Send + 'static, + + Send, { let (transaction, block) = match self.transaction_and_block(hash).await? { None => return Ok(None), @@ -647,7 +618,7 @@ where let parent_block = block.parent_hash; let block_txs = block.body; - self.spawn_with_state_at_block(parent_block.into(), move |state| { + self.with_state_at_block(parent_block.into(), |state| { let mut db = SubState::new(State::new(state)); // replay all transactions prior to the targeted transaction @@ -659,7 +630,6 @@ where let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?; f(tx_info, inspector, res, db) }) - .await .map(Some) } } @@ -908,7 +878,7 @@ mod tests { use super::*; use crate::{ eth::{cache::EthStateCache, gas_oracle::GasPriceOracle}, - EthApi, TracingCallPool, + EthApi, }; use reth_network_api::noop::NoopNetwork; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, hex_literal::hex, Bytes}; @@ -930,7 +900,6 @@ mod tests { cache.clone(), GasPriceOracle::new(noop_provider, Default::default(), cache), ETHEREUM_BLOCK_GAS_LIMIT, - TracingCallPool::build().expect("failed to build tracing pool"), ); // https://etherscan.io/tx/0xa694b71e6c128a2ed8e2e0f6770bddbe52e3bb8f10e8472f9a79ab81497a8b5d diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 280bc0817f1..e7b39730799 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -363,9 +363,11 @@ where let mut all_logs = Vec::new(); let filter_params = FilteredParams::new(Some(filter.clone())); + let topics = filter.has_topics().then(|| filter_params.flat_topics.clone()); + // derive bloom filters from filter input let address_filter = FilteredParams::address_filter(&filter.address); - let topics_filter = FilteredParams::topics_filter(&filter.topics); + let topics_filter = FilteredParams::topics_filter(&topics); let is_multi_block_range = from_block != to_block; diff --git a/crates/rpc/rpc/src/layers/auth_layer.rs b/crates/rpc/rpc/src/layers/auth_layer.rs index 0548320eb11..b3a92de804b 100644 --- a/crates/rpc/rpc/src/layers/auth_layer.rs +++ b/crates/rpc/rpc/src/layers/auth_layer.rs @@ -286,7 +286,7 @@ mod tests { let mut module = RpcModule::new(()); module.register_method("greet_melkor", |_, _| "You are the dark lord").unwrap(); - server.start(module) + server.start(module).unwrap() } fn to_u64(time: SystemTime) -> u64 { diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index e1818523f29..b885608139a 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -31,6 +31,7 @@ //! disk-io, hence these calls are spawned as futures to a blocking task manually. mod admin; +mod call_guard; mod debug; mod engine; pub mod eth; @@ -40,11 +41,11 @@ mod otterscan; mod reth; mod rpc; mod trace; -pub mod tracing_call; mod txpool; mod web3; pub use admin::AdminApi; +pub use call_guard::TracingCallGuard; pub use debug::DebugApi; pub use engine::{EngineApi, EngineEthApi}; pub use eth::{EthApi, EthApiSpec, EthFilter, EthPubSub, EthSubscriptionIdProvider}; @@ -54,7 +55,6 @@ pub use otterscan::OtterscanApi; pub use reth::RethApi; pub use rpc::RPCApi; pub use trace::TraceApi; -pub use tracing_call::{TracingCallGuard, TracingCallPool}; pub use txpool::TxPoolApi; pub use web3::Web3Api; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 494741097c7..ff2d09e50c7 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -1,7 +1,8 @@ use crate::{ eth::{ + cache::EthStateCache, error::{EthApiError, EthResult}, - revm_utils::{inspect, inspect_and_return_db, prepare_call_env, EvmOverrides}, + revm_utils::{inspect, prepare_call_env, EvmOverrides}, utils::recover_raw_transaction, EthTransactions, }, @@ -28,10 +29,11 @@ use reth_rpc_types::{ trace::{filter::TraceFilter, parity::*}, BlockError, BlockOverrides, CallRequest, Index, TransactionInfo, }; +use reth_tasks::TaskSpawner; use revm::{db::CacheDB, primitives::Env}; use revm_primitives::{db::DatabaseCommit, ExecutionResult, ResultAndState}; -use std::{collections::HashSet, sync::Arc}; -use tokio::sync::{AcquireError, OwnedSemaphorePermit}; +use std::{collections::HashSet, future::Future, sync::Arc}; +use tokio::sync::{oneshot, AcquireError, OwnedSemaphorePermit}; /// `trace` API implementation. /// @@ -49,8 +51,20 @@ impl TraceApi { } /// Create a new instance of the [TraceApi] - pub fn new(provider: Provider, eth_api: Eth, tracing_call_guard: TracingCallGuard) -> Self { - let inner = Arc::new(TraceApiInner { provider, eth_api, tracing_call_guard }); + pub fn new( + provider: Provider, + eth_api: Eth, + eth_cache: EthStateCache, + task_spawner: Box, + tracing_call_guard: TracingCallGuard, + ) -> Self { + let inner = Arc::new(TraceApiInner { + provider, + eth_api, + eth_cache, + task_spawner, + tracing_call_guard, + }); Self { inner } } @@ -69,6 +83,23 @@ where Provider: BlockReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + 'static, Eth: EthTransactions + 'static, { + /// Executes the future on a new blocking task. + async fn on_blocking_task(&self, c: C) -> EthResult + where + C: FnOnce(Self) -> F, + F: Future> + Send + 'static, + R: Send + 'static, + { + let (tx, rx) = oneshot::channel(); + let this = self.clone(); + let f = c(this); + self.inner.task_spawner.spawn_blocking(Box::pin(async move { + let res = f.await; + let _ = tx.send(res); + })); + rx.await.map_err(|_| EthApiError::InternalTracingError)? + } + /// Executes the given call and returns a number of possible traces for it. pub async fn trace_call( &self, @@ -77,23 +108,43 @@ where block_id: Option, state_overrides: Option, block_overrides: Option>, + ) -> EthResult { + self.on_blocking_task(|this| async move { + this.try_trace_call( + call, + trace_types, + block_id, + EvmOverrides::new(state_overrides, block_overrides), + ) + .await + }) + .await + } + + async fn try_trace_call( + &self, + call: CallRequest, + trace_types: HashSet, + block_id: Option, + overrides: EvmOverrides, ) -> EthResult { let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); let config = tracing_config(&trace_types); - let overrides = EvmOverrides::new(state_overrides, block_overrides); let mut inspector = TracingInspector::new(config); - self.inner + + let (res, _, db) = self + .inner .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { - let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?; - let trace_res = inspector.into_parity_builder().into_trace_results_with_state( - res, - &trace_types, - &db, - )?; - Ok(trace_res) - }) - .await + .inspect_call_at_and_return_state(call, at, overrides, &mut inspector) + .await?; + + let trace_res = inspector.into_parity_builder().into_trace_results_with_state( + res, + &trace_types, + &db, + )?; + + Ok(trace_res) } /// Traces a call to `eth_sendRawTransaction` without making the call, returning the traces. @@ -115,16 +166,16 @@ where let config = tracing_config(&trace_types); - self.inner - .eth_api - .spawn_trace_at_with_state(env, config, at, move |inspector, res, db| { + self.on_blocking_task(|this| async move { + this.inner.eth_api.trace_at_with_state(env, config, at, |inspector, res, db| { Ok(inspector.into_parity_builder().into_trace_results_with_state( res, &trace_types, &db, )?) }) - .await + }) + .await } /// Performs multiple call traces on top of the same block. i.e. transaction n will be executed @@ -139,11 +190,10 @@ where let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Pending)); let (cfg, block_env, at) = self.inner.eth_api.evm_env_at(at).await?; - let gas_limit = self.inner.eth_api.call_gas_limit(); - // execute all transactions on top of each other and record the traces - self.inner - .eth_api - .spawn_with_state_at_block(at, move |state| { + self.on_blocking_task(|this| async move { + let gas_limit = this.inner.eth_api.call_gas_limit(); + // execute all transactions on top of each other and record the traces + this.inner.eth_api.with_state_at_block(at, move |state| { let mut results = Vec::with_capacity(calls.len()); let mut db = SubState::new(State::new(state)); @@ -189,7 +239,8 @@ where Ok(results) }) - .await + }) + .await } /// Replays a transaction, returning the traces. @@ -199,19 +250,22 @@ where trace_types: HashSet, ) -> EthResult { let config = tracing_config(&trace_types); - self.inner - .eth_api - .spawn_trace_transaction_in_block(hash, config, move |_, inspector, res, db| { - let trace_res = inspector.into_parity_builder().into_trace_results_with_state( - res, - &trace_types, - &db, - )?; - Ok(trace_res) - }) - .await - .transpose() - .ok_or_else(|| EthApiError::TransactionNotFound)? + self.on_blocking_task(|this| async move { + this.inner + .eth_api + .trace_transaction_in_block(hash, config, |_, inspector, res, db| { + let trace_res = inspector.into_parity_builder().into_trace_results_with_state( + res, + &trace_types, + &db, + )?; + Ok(trace_res) + }) + .await + .transpose() + .ok_or_else(|| EthApiError::TransactionNotFound)? + }) + .await } /// Returns transaction trace objects at the given index @@ -254,18 +308,22 @@ where &self, hash: H256, ) -> EthResult>> { - self.inner - .eth_api - .spawn_trace_transaction_in_block( - hash, - TracingInspectorConfig::default_parity(), - move |tx_info, inspector, _, _| { - let traces = - inspector.into_parity_builder().into_localized_transaction_traces(tx_info); - Ok(traces) - }, - ) - .await + self.on_blocking_task(|this| async move { + this.inner + .eth_api + .trace_transaction_in_block( + hash, + TracingInspectorConfig::default_parity(), + |tx_info, inspector, _, _| { + let traces = inspector + .into_parity_builder() + .into_localized_transaction_traces(tx_info); + Ok(traces) + }, + ) + .await + }) + .await } /// Executes all transactions of a block and returns a list of callback results. @@ -313,46 +371,48 @@ where let block_hash = block.hash; let transactions = block.body; - // replay all transactions of the block - self.inner - .eth_api - .spawn_with_state_at_block(state_at.into(), move |state| { - let mut results = Vec::with_capacity(transactions.len()); - let mut db = SubState::new(State::new(state)); - - let mut transactions = transactions.into_iter().enumerate().peekable(); - - while let Some((idx, tx)) = transactions.next() { - let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; - let tx_info = TransactionInfo { - hash: Some(tx.hash()), - index: Some(idx as u64), - block_hash: Some(block_hash), - block_number: Some(block_env.number.try_into().unwrap_or(u64::MAX)), - base_fee: Some(block_env.basefee.try_into().unwrap_or(u64::MAX)), - }; - - let tx = tx_env_with_recovered(&tx); - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; - - let mut inspector = TracingInspector::new(config); - let (res, _) = inspect(&mut db, env, &mut inspector)?; - let ResultAndState { result, state } = res; - results.push(f(tx_info, inspector, result, &state, &db)?); - - // need to apply the state changes of this transaction before executing the - // next transaction - if transactions.peek().is_some() { - // need to apply the state changes of this transaction before executing - // the next transaction - db.commit(state) + self.on_blocking_task(|this| async move { + // replay all transactions of the block + this.inner + .eth_api + .with_state_at_block(state_at.into(), move |state| { + let mut results = Vec::with_capacity(transactions.len()); + let mut db = SubState::new(State::new(state)); + + let mut transactions = transactions.into_iter().enumerate().peekable(); + + while let Some((idx, tx)) = transactions.next() { + let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?; + let tx_info = TransactionInfo { + hash: Some(tx.hash()), + index: Some(idx as u64), + block_hash: Some(block_hash), + block_number: Some(block_env.number.try_into().unwrap_or(u64::MAX)), + base_fee: Some(block_env.basefee.try_into().unwrap_or(u64::MAX)), + }; + + let tx = tx_env_with_recovered(&tx); + let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + + let mut inspector = TracingInspector::new(config); + let (res, _) = inspect(&mut db, env, &mut inspector)?; + let ResultAndState { result, state } = res; + results.push(f(tx_info, inspector, result, &state, &db)?); + + // need to apply the state changes of this transaction before executing the + // next transaction + if transactions.peek().is_some() { + // need to apply the state changes of this transaction before executing + // the next transaction + db.commit(state) + } } - } - Ok(results) - }) - .await - .map(Some) + Ok(results) + }) + .map(Some) + }) + .await } /// Returns traces created at given block. @@ -566,6 +626,11 @@ struct TraceApiInner { provider: Provider, /// Access to commonly used code of the `eth` namespace eth_api: Eth, + /// The async cache frontend for eth-related data + #[allow(unused)] // we need this for trace_filter eventually + eth_cache: EthStateCache, + /// The type that can spawn tasks which would otherwise be blocking. + task_spawner: Box, // restrict the number of concurrent calls to `trace_*` tracing_call_guard: TracingCallGuard, } diff --git a/crates/stages/Cargo.toml b/crates/stages/Cargo.toml index 960ca15aa57..9d975e28e8c 100644 --- a/crates/stages/Cargo.toml +++ b/crates/stages/Cargo.toml @@ -40,7 +40,7 @@ serde.workspace = true # misc thiserror.workspace = true aquamarine = "0.3.0" -itertools.workspace = true +itertools = "0.10.5" rayon.workspace = true num-traits = "0.2.15" @@ -56,7 +56,7 @@ reth-rlp.workspace = true reth-revm = { path = "../revm" } reth-trie = { path = "../trie", features = ["test-utils"] } -itertools.workspace = true +itertools = "0.10.5" tokio = { workspace = true, features = ["rt", "sync", "macros"] } assert_matches = "1.5.0" rand.workspace = true diff --git a/crates/stages/benches/criterion.rs b/crates/stages/benches/criterion.rs index d9b079d2984..8fce2e37035 100644 --- a/crates/stages/benches/criterion.rs +++ b/crates/stages/benches/criterion.rs @@ -95,7 +95,7 @@ fn merkle(c: &mut Criterion) { // don't need to run each stage for that many times group.sample_size(10); - let stage = MerkleStage::Both { clean_threshold: u64::MAX, prune_modes: Default::default() }; + let stage = MerkleStage::Both { clean_threshold: u64::MAX }; measure_stage( &mut group, setup::unwind_hashes, @@ -104,7 +104,7 @@ fn merkle(c: &mut Criterion) { "Merkle-incremental".to_string(), ); - let stage = MerkleStage::Both { clean_threshold: 0, prune_modes: Default::default() }; + let stage = MerkleStage::Both { clean_threshold: 0 }; measure_stage( &mut group, setup::unwind_hashes, diff --git a/crates/stages/src/error.rs b/crates/stages/src/error.rs index b5158f3e155..20310111ca9 100644 --- a/crates/stages/src/error.rs +++ b/crates/stages/src/error.rs @@ -49,9 +49,6 @@ pub enum StageError { #[source] error: executor::BlockExecutionError, }, - /// Invalid pruning configuration - #[error(transparent)] - PruningConfiguration(#[from] reth_primitives::PrunePartError), /// Invalid checkpoint passed to the stage #[error("Invalid stage checkpoint: {0}")] StageCheckpoint(u64), diff --git a/crates/stages/src/pipeline/mod.rs b/crates/stages/src/pipeline/mod.rs index d15fefacf67..a108695cfad 100644 --- a/crates/stages/src/pipeline/mod.rs +++ b/crates/stages/src/pipeline/mod.rs @@ -431,19 +431,6 @@ where "Stage encountered a validation error: {error}" ); - // FIXME: When handling errors, we do not commit the database transaction. - // This leads to the Merkle stage not clearing its - // checkpoint, and restarting from an invalid place. - drop(provider_rw); - provider_rw = factory.provider_rw().map_err(PipelineError::Interface)?; - provider_rw - .save_stage_checkpoint_progress(StageId::MerkleExecute, vec![])?; - provider_rw.save_stage_checkpoint( - StageId::MerkleExecute, - prev_checkpoint.unwrap_or_default(), - )?; - provider_rw.commit()?; - // We unwind because of a validation error. If the unwind itself fails, // we bail entirely, otherwise we restart the execution loop from the // beginning. diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index fc8e789a1f0..366e10e7c3c 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -60,7 +60,7 @@ pub struct ExecutionStage { /// The commit thresholds of the execution stage. thresholds: ExecutionStageThresholds, /// Pruning configuration. - prune_modes: PruneModes, + prune_targets: PruneModes, } impl ExecutionStage { @@ -68,9 +68,9 @@ impl ExecutionStage { pub fn new( executor_factory: EF, thresholds: ExecutionStageThresholds, - prune_modes: PruneModes, + prune_targets: PruneModes, ) -> Self { - Self { metrics_tx: None, executor_factory, thresholds, prune_modes } + Self { metrics_tx: None, executor_factory, thresholds, prune_targets } } /// Create an execution stage with the provided executor factory. @@ -110,7 +110,7 @@ impl ExecutionStage { // Execute block range let mut state = PostState::default(); - state.add_prune_modes(self.prune_modes); + state.add_prune_targets(self.prune_targets); for block_number in start_block..=max_block { let td = provider @@ -425,7 +425,8 @@ mod tests { use reth_db::{models::AccountBeforeTx, test_utils::create_test_rw_db}; use reth_primitives::{ hex_literal::hex, keccak256, stage::StageUnitCheckpoint, Account, Bytecode, - ChainSpecBuilder, PruneModes, SealedBlock, StorageEntry, H160, H256, MAINNET, U256, + ChainSpecBuilder, PruneMode, PruneModes, SealedBlock, StorageEntry, H160, H256, MAINNET, + U256, }; use reth_provider::{AccountReader, BlockWriter, ProviderFactory, ReceiptProvider}; use reth_revm::Factory; @@ -893,4 +894,86 @@ mod tests { ] ); } + + #[tokio::test] + async fn test_prune() { + let test_tx = TestTransaction::default(); + let factory = Arc::new(ProviderFactory::new(test_tx.tx.as_ref(), MAINNET.clone())); + + let provider = factory.provider_rw().unwrap(); + let input = ExecInput { + target: Some(1), + /// The progress of this stage the last time it was executed. + checkpoint: None, + }; + let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); + let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); + let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); + let block = SealedBlock::decode(&mut block_rlp).unwrap(); + provider.insert_block(genesis, None).unwrap(); + provider.insert_block(block.clone(), None).unwrap(); + provider.commit().unwrap(); + + // insert pre state + let provider = factory.provider_rw().unwrap(); + let code = hex!("5a465a905090036002900360015500"); + let code_hash = keccak256(hex!("5a465a905090036002900360015500")); + provider + .tx_ref() + .put::( + H160(hex!("1000000000000000000000000000000000000000")), + Account { nonce: 0, balance: U256::ZERO, bytecode_hash: Some(code_hash) }, + ) + .unwrap(); + provider + .tx_ref() + .put::( + H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")), + Account { + nonce: 0, + balance: U256::from(0x3635c9adc5dea00000u128), + bytecode_hash: None, + }, + ) + .unwrap(); + provider + .tx_ref() + .put::(code_hash, Bytecode::new_raw(code.to_vec().into())) + .unwrap(); + provider.commit().unwrap(); + + let check_pruning = |factory: Arc>, + prune_targets: PruneModes, + expect_num_receipts: usize| async move { + let provider = factory.provider_rw().unwrap(); + + let mut execution_stage = ExecutionStage::new( + Factory::new(Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build())), + ExecutionStageThresholds { max_blocks: Some(100), max_changes: None }, + prune_targets, + ); + + execution_stage.execute(&provider, input).await.unwrap(); + assert_eq!( + provider.receipts_by_block(1.into()).unwrap().unwrap().len(), + expect_num_receipts + ); + }; + + let mut prune = PruneModes::none(); + + check_pruning(factory.clone(), prune, 1).await; + + prune.receipts = Some(PruneMode::Full); + check_pruning(factory.clone(), prune, 0).await; + + prune.receipts = Some(PruneMode::Before(1)); + check_pruning(factory.clone(), prune, 1).await; + + prune.receipts = Some(PruneMode::Before(2)); + check_pruning(factory.clone(), prune, 0).await; + + prune.receipts = Some(PruneMode::Distance(0)); + check_pruning(factory.clone(), prune, 1).await; + } } diff --git a/crates/stages/src/stages/hashing_account.rs b/crates/stages/src/stages/hashing_account.rs index 7eed29bd33d..ccb6fb960fd 100644 --- a/crates/stages/src/stages/hashing_account.rs +++ b/crates/stages/src/stages/hashing_account.rs @@ -15,7 +15,6 @@ use reth_primitives::{ AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint, StageCheckpoint, StageId, }, - PruneModes, }; use reth_provider::{AccountExtReader, DatabaseProviderRW, HashingWriter}; use std::{ @@ -35,25 +34,18 @@ pub struct AccountHashingStage { pub clean_threshold: u64, /// The maximum number of accounts to process before committing. pub commit_threshold: u64, - /// Prune mode configuration. Required to know if we can actually make an incremental - /// update based on how many changesets exist. - pub prune_modes: PruneModes, } impl AccountHashingStage { /// Create new instance of [AccountHashingStage]. - pub fn new(clean_threshold: u64, commit_threshold: u64, prune_modes: PruneModes) -> Self { - Self { clean_threshold, commit_threshold, prune_modes } + pub fn new(clean_threshold: u64, commit_threshold: u64) -> Self { + Self { clean_threshold, commit_threshold } } } impl Default for AccountHashingStage { fn default() -> Self { - Self { - clean_threshold: 500_000, - commit_threshold: 100_000, - prune_modes: PruneModes::default(), - } + Self { clean_threshold: 500_000, commit_threshold: 100_000 } } } @@ -151,19 +143,12 @@ impl Stage for AccountHashingStage { } let (from_block, to_block) = input.next_block_range().into_inner(); - let has_enough_changesets = self - .prune_modes - .prune_target_block_account_history(to_block)? - .map(|(block_number, _)| block_number) - .unwrap_or_default() < - from_block; // if there are more blocks then threshold it is faster to go over Plain state and hash all // account otherwise take changesets aggregate the sets and apply hashing to // AccountHashing table. Also, if we start from genesis, we need to hash from scratch, as // genesis accounts are not in changeset. - if to_block - from_block > self.clean_threshold || from_block == 1 || !has_enough_changesets - { + if to_block - from_block > self.clean_threshold || from_block == 1 { let tx = provider.tx_ref(); let stage_checkpoint = input .checkpoint @@ -463,7 +448,6 @@ mod tests { pub(crate) tx: TestTransaction, commit_threshold: u64, clean_threshold: u64, - prune_modes: PruneModes, } impl AccountHashingTestRunner { @@ -527,7 +511,6 @@ mod tests { tx: TestTransaction::default(), commit_threshold: 1000, clean_threshold: 1000, - prune_modes: PruneModes::default(), } } } @@ -543,7 +526,6 @@ mod tests { Self::S { commit_threshold: self.commit_threshold, clean_threshold: self.clean_threshold, - prune_modes: self.prune_modes, } } } diff --git a/crates/stages/src/stages/hashing_storage.rs b/crates/stages/src/stages/hashing_storage.rs index c6a65b3d80c..040b6375bd0 100644 --- a/crates/stages/src/stages/hashing_storage.rs +++ b/crates/stages/src/stages/hashing_storage.rs @@ -14,7 +14,7 @@ use reth_primitives::{ CheckpointBlockRange, EntitiesCheckpoint, StageCheckpoint, StageId, StorageHashingCheckpoint, }, - PruneModes, StorageEntry, + StorageEntry, }; use reth_provider::{DatabaseProviderRW, HashingWriter, StorageReader}; use std::{collections::BTreeMap, fmt::Debug}; @@ -29,25 +29,18 @@ pub struct StorageHashingStage { pub clean_threshold: u64, /// The maximum number of slots to process before committing. pub commit_threshold: u64, - /// Prune mode configuration. Required to know if we can actually make an incremental - /// update based on how many changesets exist. - pub prune_modes: PruneModes, } impl StorageHashingStage { /// Create new instance of [StorageHashingStage]. - pub fn new(clean_threshold: u64, commit_threshold: u64, prune_modes: PruneModes) -> Self { - Self { clean_threshold, commit_threshold, prune_modes } + pub fn new(clean_threshold: u64, commit_threshold: u64) -> Self { + Self { clean_threshold, commit_threshold } } } impl Default for StorageHashingStage { fn default() -> Self { - Self { - clean_threshold: 500_000, - commit_threshold: 100_000, - prune_modes: PruneModes::default(), - } + Self { clean_threshold: 500_000, commit_threshold: 100_000 } } } @@ -70,19 +63,12 @@ impl Stage for StorageHashingStage { } let (from_block, to_block) = input.next_block_range().into_inner(); - let has_enough_changesets = self - .prune_modes - .prune_target_block_storage_history(to_block)? - .map(|(block_number, _)| block_number) - .unwrap_or_default() < - from_block; // if there are more blocks then threshold it is faster to go over Plain state and hash all // account otherwise take changesets aggregate the sets and apply hashing to // AccountHashing table. Also, if we start from genesis, we need to hash from scratch, as // genesis accounts are not in changeset, along with their storages. - if to_block - from_block > self.clean_threshold || from_block == 1 || !has_enough_changesets - { + if to_block - from_block > self.clean_threshold || from_block == 1 { let stage_checkpoint = input .checkpoint .and_then(|checkpoint| checkpoint.storage_hashing_stage_checkpoint()); @@ -471,17 +457,11 @@ mod tests { tx: TestTransaction, commit_threshold: u64, clean_threshold: u64, - prune_modes: PruneModes, } impl Default for StorageHashingTestRunner { fn default() -> Self { - Self { - tx: TestTransaction::default(), - commit_threshold: 1000, - clean_threshold: 1000, - prune_modes: PruneModes::default(), - } + Self { tx: TestTransaction::default(), commit_threshold: 1000, clean_threshold: 1000 } } } @@ -496,7 +476,6 @@ mod tests { Self::S { commit_threshold: self.commit_threshold, clean_threshold: self.clean_threshold, - prune_modes: self.prune_modes, } } } diff --git a/crates/stages/src/stages/index_account_history.rs b/crates/stages/src/stages/index_account_history.rs index d259ec3f815..fe0b6d3b404 100644 --- a/crates/stages/src/stages/index_account_history.rs +++ b/crates/stages/src/stages/index_account_history.rs @@ -1,9 +1,6 @@ use crate::{ExecInput, ExecOutput, Stage, StageError, UnwindInput, UnwindOutput}; use reth_db::database::Database; -use reth_primitives::{ - stage::{StageCheckpoint, StageId}, - PruneModes, -}; +use reth_primitives::stage::{StageCheckpoint, StageId}; use reth_provider::{AccountExtReader, DatabaseProviderRW, HistoryWriter}; use std::fmt::Debug; @@ -15,20 +12,18 @@ pub struct IndexAccountHistoryStage { /// Number of blocks after which the control /// flow will be returned to the pipeline for commit. pub commit_threshold: u64, - /// Pruning configuration. - pub prune_modes: PruneModes, } impl IndexAccountHistoryStage { /// Create new instance of [IndexAccountHistoryStage]. pub fn new(commit_threshold: u64) -> Self { - Self { commit_threshold, prune_modes: PruneModes::default() } + Self { commit_threshold } } } impl Default for IndexAccountHistoryStage { fn default() -> Self { - Self { commit_threshold: 100_000, prune_modes: PruneModes::default() } + Self { commit_threshold: 100_000 } } } @@ -43,16 +38,8 @@ impl Stage for IndexAccountHistoryStage { async fn execute( &mut self, provider: &DatabaseProviderRW<'_, &DB>, - mut input: ExecInput, + input: ExecInput, ) -> Result { - if let Some((target_prunable_block, _)) = - self.prune_modes.prune_target_block_account_history(input.target())? - { - if target_prunable_block > input.checkpoint().block_number { - input.checkpoint = Some(StageCheckpoint::new(target_prunable_block)); - } - } - if input.target_reached() { return Ok(ExecOutput::done(input.checkpoint())) } @@ -385,16 +372,11 @@ mod tests { struct IndexAccountHistoryTestRunner { pub(crate) tx: TestTransaction, commit_threshold: u64, - prune_modes: PruneModes, } impl Default for IndexAccountHistoryTestRunner { fn default() -> Self { - Self { - tx: TestTransaction::default(), - commit_threshold: 1000, - prune_modes: PruneModes::default(), - } + Self { tx: TestTransaction::default(), commit_threshold: 1000 } } } @@ -406,7 +388,7 @@ mod tests { } fn stage(&self) -> Self::S { - Self::S { commit_threshold: self.commit_threshold, prune_modes: self.prune_modes } + Self::S { commit_threshold: self.commit_threshold } } } diff --git a/crates/stages/src/stages/index_storage_history.rs b/crates/stages/src/stages/index_storage_history.rs index 4759cd82c59..945bafc5f33 100644 --- a/crates/stages/src/stages/index_storage_history.rs +++ b/crates/stages/src/stages/index_storage_history.rs @@ -1,9 +1,6 @@ use crate::{ExecInput, ExecOutput, Stage, StageError, UnwindInput, UnwindOutput}; use reth_db::{database::Database, models::BlockNumberAddress}; -use reth_primitives::{ - stage::{StageCheckpoint, StageId}, - PruneModes, -}; +use reth_primitives::stage::{StageCheckpoint, StageId}; use reth_provider::{DatabaseProviderRW, HistoryWriter, StorageReader}; use std::fmt::Debug; @@ -15,20 +12,18 @@ pub struct IndexStorageHistoryStage { /// Number of blocks after which the control /// flow will be returned to the pipeline for commit. pub commit_threshold: u64, - /// Pruning configuration. - pub prune_modes: PruneModes, } impl IndexStorageHistoryStage { /// Create new instance of [IndexStorageHistoryStage]. pub fn new(commit_threshold: u64) -> Self { - Self { commit_threshold, prune_modes: PruneModes::default() } + Self { commit_threshold } } } impl Default for IndexStorageHistoryStage { fn default() -> Self { - Self { commit_threshold: 100_000, prune_modes: PruneModes::default() } + Self { commit_threshold: 100_000 } } } @@ -43,16 +38,8 @@ impl Stage for IndexStorageHistoryStage { async fn execute( &mut self, provider: &DatabaseProviderRW<'_, &DB>, - mut input: ExecInput, + input: ExecInput, ) -> Result { - if let Some((target_prunable_block, _)) = - self.prune_modes.prune_target_block_storage_history(input.target())? - { - if target_prunable_block > input.checkpoint().block_number { - input.checkpoint = Some(StageCheckpoint::new(target_prunable_block)); - } - } - if input.target_reached() { return Ok(ExecOutput::done(input.checkpoint())) } @@ -86,29 +73,17 @@ mod tests { use std::collections::BTreeMap; use super::*; - use crate::test_utils::{ - stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError, - TestTransaction, UnwindStageTestRunner, - }; - use itertools::Itertools; + use crate::test_utils::TestTransaction; use reth_db::{ - cursor::DbCursorRO, models::{ - sharded_key, storage_sharded_key::{StorageShardedKey, NUM_OF_INDICES_IN_SHARD}, BlockNumberAddress, ShardedKey, StoredBlockBodyIndices, }, tables, - transaction::{DbTx, DbTxMut}, + transaction::DbTxMut, BlockNumberList, }; - use reth_interfaces::test_utils::{ - generators, - generators::{random_block_range, random_contract_account_range, random_transition_range}, - }; - use reth_primitives::{ - hex_literal::hex, Address, BlockNumber, StorageEntry, H160, H256, MAINNET, U256, - }; + use reth_primitives::{hex_literal::hex, StorageEntry, H160, H256, MAINNET, U256}; const ADDRESS: H160 = H160(hex!("0000000000000000000000000000000000000001")); const STORAGE_KEY: H256 = @@ -393,147 +368,4 @@ mod tests { ]) ); } - - stage_test_suite_ext!(IndexStorageHistoryTestRunner, index_storage_history); - - struct IndexStorageHistoryTestRunner { - pub(crate) tx: TestTransaction, - commit_threshold: u64, - prune_modes: PruneModes, - } - - impl Default for IndexStorageHistoryTestRunner { - fn default() -> Self { - Self { - tx: TestTransaction::default(), - commit_threshold: 1000, - prune_modes: PruneModes::default(), - } - } - } - - impl StageTestRunner for IndexStorageHistoryTestRunner { - type S = IndexStorageHistoryStage; - - fn tx(&self) -> &TestTransaction { - &self.tx - } - - fn stage(&self) -> Self::S { - Self::S { commit_threshold: self.commit_threshold, prune_modes: self.prune_modes } - } - } - - impl ExecuteStageTestRunner for IndexStorageHistoryTestRunner { - type Seed = (); - - fn seed_execution(&mut self, input: ExecInput) -> Result { - let stage_process = input.checkpoint().block_number; - let start = stage_process + 1; - let end = input.target(); - let mut rng = generators::rng(); - - let num_of_accounts = 31; - let accounts = random_contract_account_range(&mut rng, &mut (0..num_of_accounts)) - .into_iter() - .collect::>(); - - let blocks = random_block_range(&mut rng, start..=end, H256::zero(), 0..3); - - let (transitions, _) = random_transition_range( - &mut rng, - blocks.iter(), - accounts.into_iter().map(|(addr, acc)| (addr, (acc, Vec::new()))), - 0..3, - 0..256, - ); - - // add block changeset from block 1. - self.tx.insert_transitions(transitions, Some(start))?; - - Ok(()) - } - - fn validate_execution( - &self, - input: ExecInput, - output: Option, - ) -> Result<(), TestRunnerError> { - if let Some(output) = output { - let start_block = input.next_block(); - let end_block = output.checkpoint.block_number; - if start_block > end_block { - return Ok(()) - } - - assert_eq!( - output, - ExecOutput { checkpoint: StageCheckpoint::new(input.target()), done: true } - ); - - let provider = self.tx.inner(); - let mut changeset_cursor = - provider.tx_ref().cursor_read::()?; - - let storage_transitions = changeset_cursor - .walk_range(BlockNumberAddress::range(start_block..=end_block))? - .try_fold( - BTreeMap::new(), - |mut storages: BTreeMap<(Address, H256), Vec>, - entry| - -> Result<_, TestRunnerError> { - let (index, storage) = entry?; - storages - .entry((index.address(), storage.key)) - .or_default() - .push(index.block_number()); - Ok(storages) - }, - )?; - - let mut result = BTreeMap::new(); - for (partial_key, indices) in storage_transitions { - // chunk indices and insert them in shards of N size. - let mut chunks = indices - .iter() - .chunks(sharded_key::NUM_OF_INDICES_IN_SHARD) - .into_iter() - .map(|chunks| chunks.map(|i| *i as usize).collect::>()) - .collect::>(); - let last_chunk = chunks.pop(); - - chunks.into_iter().for_each(|list| { - result.insert( - StorageShardedKey::new( - partial_key.0, - partial_key.1, - *list.last().expect("Chuck does not return empty list") - as BlockNumber, - ), - list, - ); - }); - - if let Some(last_list) = last_chunk { - result.insert( - StorageShardedKey::new(partial_key.0, partial_key.1, u64::MAX), - last_list, - ); - }; - } - - let table = cast(self.tx.table::().unwrap()); - assert_eq!(table, result); - } - Ok(()) - } - } - - impl UnwindStageTestRunner for IndexStorageHistoryTestRunner { - fn validate_unwind(&self, _input: UnwindInput) -> Result<(), TestRunnerError> { - let table = self.tx.table::().unwrap(); - assert!(table.is_empty()); - Ok(()) - } - } } diff --git a/crates/stages/src/stages/merkle.rs b/crates/stages/src/stages/merkle.rs index ffcc427b58c..1a95341d85e 100644 --- a/crates/stages/src/stages/merkle.rs +++ b/crates/stages/src/stages/merkle.rs @@ -10,7 +10,7 @@ use reth_primitives::{ hex, stage::{EntitiesCheckpoint, MerkleCheckpoint, StageCheckpoint, StageId}, trie::StoredSubNode, - BlockNumber, PruneModes, SealedHeader, H256, + BlockNumber, SealedHeader, H256, }; use reth_provider::{ DatabaseProviderRW, HeaderProvider, ProviderError, StageCheckpointReader, StageCheckpointWriter, @@ -47,9 +47,6 @@ pub enum MerkleStage { /// The threshold (in number of blocks) for switching from incremental trie building /// of changes to whole rebuild. clean_threshold: u64, - /// Prune mode configuration. Required to know if we can actually make an incremental root - /// update based on how many changesets exist. - prune_modes: PruneModes, }, /// The unwind portion of the merkle stage. Unwind, @@ -57,13 +54,13 @@ pub enum MerkleStage { /// Able to execute and unwind. Used for tests #[cfg(any(test, feature = "test-utils"))] #[allow(missing_docs)] - Both { clean_threshold: u64, prune_modes: PruneModes }, + Both { clean_threshold: u64 }, } impl MerkleStage { /// Stage default for the [MerkleStage::Execution]. pub fn default_execution() -> Self { - Self::Execution { clean_threshold: 50_000, prune_modes: PruneModes::default() } + Self::Execution { clean_threshold: 50_000 } } /// Stage default for the [MerkleStage::Unwind]. @@ -72,8 +69,8 @@ impl MerkleStage { } /// Create new instance of [MerkleStage::Execution]. - pub fn new_execution(clean_threshold: u64, prune_modes: PruneModes) -> Self { - Self::Execution { clean_threshold, prune_modes } + pub fn new_execution(clean_threshold: u64) -> Self { + Self::Execution { clean_threshold } } /// Check that the computed state root matches the root in the expected header. @@ -131,26 +128,6 @@ impl MerkleStage { } Ok(provider.save_stage_checkpoint_progress(StageId::MerkleExecute, buf)?) } - - /// When pruning is enabled for account and storage history, we might not have all changesets - /// required for an incremental state root update on a pipeline re-run. - pub fn has_enough_changesets( - &self, - prune_modes: PruneModes, - from_block: BlockNumber, - to_block: BlockNumber, - ) -> Result { - Ok(prune_modes - .prune_target_block_account_history(to_block)? - .map(|(block_number, _)| block_number) - .unwrap_or_default() < - from_block && - prune_modes - .prune_target_block_storage_history(to_block)? - .map(|(block_number, _)| block_number) - .unwrap_or_default() < - from_block) - } } #[async_trait::async_trait] @@ -171,16 +148,14 @@ impl Stage for MerkleStage { provider: &DatabaseProviderRW<'_, &DB>, input: ExecInput, ) -> Result { - let (threshold, prune_modes) = match self { + let threshold = match self { MerkleStage::Unwind => { info!(target: "sync::stages::merkle::unwind", "Stage is always skipped"); return Ok(ExecOutput::done(StageCheckpoint::new(input.target()))) } - MerkleStage::Execution { clean_threshold, prune_modes } => { - (*clean_threshold, *prune_modes) - } + MerkleStage::Execution { clean_threshold } => *clean_threshold, #[cfg(any(test, feature = "test-utils"))] - MerkleStage::Both { clean_threshold, prune_modes } => (*clean_threshold, *prune_modes), + MerkleStage::Both { clean_threshold } => *clean_threshold, }; let range = input.next_block_range(); @@ -193,12 +168,10 @@ impl Stage for MerkleStage { let target_block_root = target_block.state_root; let mut checkpoint = self.get_execution_checkpoint(provider)?; + let (trie_root, entities_checkpoint) = if range.is_empty() { (target_block_root, input.checkpoint().entities_stage_checkpoint().unwrap_or_default()) - } else if to_block - from_block > threshold || - from_block == 1 || - !self.has_enough_changesets(prune_modes, from_block, to_block)? - { + } else if to_block - from_block > threshold || from_block == 1 { // if there are more blocks than threshold it is faster to rebuild the trie let mut entities_checkpoint = if let Some(checkpoint) = checkpoint.as_ref().filter(|c| c.target_block == to_block) @@ -472,16 +445,11 @@ mod tests { struct MerkleTestRunner { tx: TestTransaction, clean_threshold: u64, - prune_modes: PruneModes, } impl Default for MerkleTestRunner { fn default() -> Self { - Self { - tx: TestTransaction::default(), - clean_threshold: 10000, - prune_modes: PruneModes::default(), - } + Self { tx: TestTransaction::default(), clean_threshold: 10000 } } } @@ -493,7 +461,7 @@ mod tests { } fn stage(&self) -> Self::S { - Self::S::Both { clean_threshold: self.clean_threshold, prune_modes: self.prune_modes } + Self::S::Both { clean_threshold: self.clean_threshold } } } diff --git a/crates/stages/src/stages/mod.rs b/crates/stages/src/stages/mod.rs index 3cf295abeb4..96f1ec5fecb 100644 --- a/crates/stages/src/stages/mod.rs +++ b/crates/stages/src/stages/mod.rs @@ -35,188 +35,3 @@ pub use merkle::*; pub use sender_recovery::*; pub use total_difficulty::*; pub use tx_lookup::*; - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - stage::Stage, - stages::{ExecutionStage, IndexAccountHistoryStage, IndexStorageHistoryStage}, - test_utils::TestTransaction, - ExecInput, - }; - use reth_db::{ - cursor::DbCursorRO, - mdbx::{cursor::Cursor, RW}, - tables, - transaction::{DbTx, DbTxMut}, - AccountHistory, DatabaseEnv, - }; - use reth_interfaces::test_utils::generators::{self, random_block}; - use reth_primitives::{ - hex_literal::hex, keccak256, Account, Bytecode, ChainSpecBuilder, PruneMode, PruneModes, - SealedBlock, H160, MAINNET, U256, - }; - use reth_provider::{ - AccountExtReader, BlockWriter, DatabaseProviderRW, ProviderFactory, ReceiptProvider, - StorageReader, - }; - use reth_revm::Factory; - use reth_rlp::Decodable; - use std::sync::Arc; - - #[tokio::test] - async fn test_prune() { - let test_tx = TestTransaction::default(); - let factory = Arc::new(ProviderFactory::new(test_tx.tx.as_ref(), MAINNET.clone())); - - let provider = factory.provider_rw().unwrap(); - let tip = 66; - let input = ExecInput { - target: Some(tip), - /// The progress of this stage the last time it was executed. - checkpoint: None, - }; - let mut genesis_rlp = hex!("f901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa045571b40ae66ca7480791bbb2887286e4e4c4b1b298b191c889d6959023a32eda056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0").as_slice(); - let genesis = SealedBlock::decode(&mut genesis_rlp).unwrap(); - let mut block_rlp = hex!("f90262f901f9a075c371ba45999d87f4542326910a11af515897aebce5265d3f6acd1f1161f82fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa098f2dcd87c8ae4083e7017a05456c14eea4b1db2032126e27b3b1563d57d7cc0a08151d548273f6683169524b66ca9fe338b9ce42bc3540046c828fd939ae23bcba03f4e5c2ec5b2170b711d97ee755c160457bb58d8daa338e835ec02ae6860bbabb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018502540be40082a8798203e800a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f863f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509bc0").as_slice(); - let block = SealedBlock::decode(&mut block_rlp).unwrap(); - provider.insert_block(genesis, None).unwrap(); - provider.insert_block(block.clone(), None).unwrap(); - - // Fill with bogus blocks to respect PruneMode distance. - let mut head = block.hash; - let mut rng = generators::rng(); - for block_number in 2..=tip { - let nblock = random_block(&mut rng, block_number, Some(head), Some(0), Some(0)); - head = nblock.hash; - provider.insert_block(nblock, None).unwrap(); - } - provider.commit().unwrap(); - - // insert pre state - let provider = factory.provider_rw().unwrap(); - let code = hex!("5a465a905090036002900360015500"); - let code_hash = keccak256(hex!("5a465a905090036002900360015500")); - provider - .tx_ref() - .put::( - H160(hex!("1000000000000000000000000000000000000000")), - Account { nonce: 0, balance: U256::ZERO, bytecode_hash: Some(code_hash) }, - ) - .unwrap(); - provider - .tx_ref() - .put::( - H160(hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b")), - Account { - nonce: 0, - balance: U256::from(0x3635c9adc5dea00000u128), - bytecode_hash: None, - }, - ) - .unwrap(); - provider - .tx_ref() - .put::(code_hash, Bytecode::new_raw(code.to_vec().into())) - .unwrap(); - provider.commit().unwrap(); - - let check_pruning = |factory: Arc>, - prune_modes: PruneModes, - expect_num_receipts: usize, - expect_num_acc_changesets: usize, - expect_num_storage_changesets: usize| async move { - let provider: DatabaseProviderRW<'_, &DatabaseEnv> = factory.provider_rw().unwrap(); - - // Check execution and create receipts and changesets according to the pruning - // configuration - let mut execution_stage = ExecutionStage::new( - Factory::new(Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build())), - ExecutionStageThresholds { max_blocks: Some(100), max_changes: None }, - prune_modes, - ); - - execution_stage.execute(&provider, input).await.unwrap(); - assert_eq!( - provider.receipts_by_block(1.into()).unwrap().unwrap().len(), - expect_num_receipts - ); - - assert_eq!( - provider.changed_storages_and_blocks_with_range(0..=1000).unwrap().len(), - expect_num_storage_changesets - ); - - assert_eq!( - provider.changed_accounts_and_blocks_with_range(0..=1000).unwrap().len(), - expect_num_acc_changesets - ); - - // Check AccountHistory - let mut acc_indexing_stage = - IndexAccountHistoryStage { prune_modes, ..Default::default() }; - - if let Some(PruneMode::Full) = prune_modes.account_history { - // Full is not supported - assert!(acc_indexing_stage.execute(&provider, input).await.is_err()); - } else { - acc_indexing_stage.execute(&provider, input).await.unwrap(); - let mut account_history: Cursor<'_, RW, AccountHistory> = - provider.tx_ref().cursor_read::().unwrap(); - assert_eq!(account_history.walk(None).unwrap().count(), expect_num_acc_changesets); - } - - // Check StorageHistory - let mut storage_indexing_stage = - IndexStorageHistoryStage { prune_modes, ..Default::default() }; - - if let Some(PruneMode::Full) = prune_modes.storage_history { - // Full is not supported - assert!(acc_indexing_stage.execute(&provider, input).await.is_err()); - } else { - storage_indexing_stage.execute(&provider, input).await.unwrap(); - - let mut storage_history = - provider.tx_ref().cursor_read::().unwrap(); - assert_eq!( - storage_history.walk(None).unwrap().count(), - expect_num_storage_changesets - ); - } - }; - - // In an unpruned configuration there is 1 receipt, 3 changed accounts and 1 changed - // storage. - let mut prune = PruneModes::none(); - check_pruning(factory.clone(), prune, 1, 3, 1).await; - - prune.receipts = Some(PruneMode::Full); - prune.account_history = Some(PruneMode::Full); - prune.storage_history = Some(PruneMode::Full); - // This will result in error for account_history and storage_history, which is caught. - check_pruning(factory.clone(), prune, 0, 0, 0).await; - - prune.receipts = Some(PruneMode::Before(1)); - prune.account_history = Some(PruneMode::Before(1)); - prune.storage_history = Some(PruneMode::Before(1)); - check_pruning(factory.clone(), prune, 1, 3, 1).await; - - prune.receipts = Some(PruneMode::Before(2)); - prune.account_history = Some(PruneMode::Before(2)); - prune.storage_history = Some(PruneMode::Before(2)); - // The one account is the miner - check_pruning(factory.clone(), prune, 0, 1, 0).await; - - prune.receipts = Some(PruneMode::Distance(66)); - prune.account_history = Some(PruneMode::Distance(66)); - prune.storage_history = Some(PruneMode::Distance(66)); - check_pruning(factory.clone(), prune, 1, 3, 1).await; - - prune.receipts = Some(PruneMode::Distance(64)); - prune.account_history = Some(PruneMode::Distance(64)); - prune.storage_history = Some(PruneMode::Distance(64)); - // The one account is the miner - check_pruning(factory.clone(), prune, 0, 1, 0).await; - } -} diff --git a/crates/stages/src/stages/tx_lookup.rs b/crates/stages/src/stages/tx_lookup.rs index 211266d45d8..09e0e6d674f 100644 --- a/crates/stages/src/stages/tx_lookup.rs +++ b/crates/stages/src/stages/tx_lookup.rs @@ -11,9 +11,9 @@ use reth_db::{ use reth_primitives::{ keccak256, stage::{EntitiesCheckpoint, StageCheckpoint, StageId}, - PrunePart, TransactionSignedNoHash, TxNumber, H256, + TransactionSignedNoHash, TxNumber, H256, }; -use reth_provider::{BlockReader, DatabaseProviderRW, PruneCheckpointReader}; +use reth_provider::DatabaseProviderRW; use tokio::sync::mpsc; use tracing::*; @@ -183,20 +183,9 @@ fn calculate_hash( fn stage_checkpoint( provider: &DatabaseProviderRW<'_, &DB>, -) -> Result { - let pruned_entries = provider - .get_prune_checkpoint(PrunePart::TransactionLookup)? - .map(|checkpoint| provider.block_body_indices(checkpoint.block_number)) - .transpose()? - .flatten() - // +1 is needed because TxNumber is 0-indexed - .map(|body| body.last_tx_num() + 1) - .unwrap_or_default(); +) -> Result { Ok(EntitiesCheckpoint { - // If `TxHashNumber` table was pruned, we will have a number of entries in it not matching - // the actual number of processed transactions. To fix that, we add the number of pruned - // `TxHashNumber` entries. - processed: provider.tx_ref().entries::()? as u64 + pruned_entries, + processed: provider.tx_ref().entries::()? as u64, total: provider.tx_ref().entries::()? as u64, }) } @@ -213,13 +202,8 @@ mod tests { generators, generators::{random_block, random_block_range}, }; - use reth_primitives::{ - stage::StageUnitCheckpoint, BlockNumber, PruneCheckpoint, PruneMode, SealedBlock, H256, - MAINNET, - }; - use reth_provider::{ - BlockReader, ProviderError, ProviderFactory, PruneCheckpointWriter, TransactionsProvider, - }; + use reth_primitives::{stage::StageUnitCheckpoint, BlockNumber, SealedBlock, H256}; + use reth_provider::{BlockReader, ProviderError, TransactionsProvider}; // Implement stage test suite. stage_test_suite_ext!(TransactionLookupTestRunner, transaction_lookup); @@ -337,57 +321,6 @@ mod tests { assert!(runner.validate_execution(first_input, result.ok()).is_ok(), "validation failed"); } - #[test] - fn stage_checkpoint_pruned() { - let tx = TestTransaction::default(); - let mut rng = generators::rng(); - - let blocks = random_block_range(&mut rng, 0..=100, H256::zero(), 0..10); - tx.insert_blocks(blocks.iter(), None).expect("insert blocks"); - - let max_pruned_block = 30; - let max_processed_block = 70; - - let mut tx_hash_numbers = Vec::new(); - let mut tx_hash_number = 0; - for block in &blocks[..=max_processed_block] { - for transaction in &block.body { - if block.number > max_pruned_block { - tx_hash_numbers.push((transaction.hash, tx_hash_number)); - } - tx_hash_number += 1; - } - } - tx.insert_tx_hash_numbers(tx_hash_numbers).expect("insert tx hash numbers"); - - let provider = tx.inner_rw(); - provider - .save_prune_checkpoint( - PrunePart::TransactionLookup, - PruneCheckpoint { - block_number: max_pruned_block as BlockNumber, - prune_mode: PruneMode::Full, - }, - ) - .expect("save stage checkpoint"); - provider.commit().expect("commit"); - - let db = tx.inner_raw(); - let factory = ProviderFactory::new(db.as_ref(), MAINNET.clone()); - let provider = factory.provider_rw().expect("provider rw"); - - assert_eq!( - stage_checkpoint(&provider).expect("stage checkpoint"), - EntitiesCheckpoint { - processed: blocks[..=max_processed_block] - .iter() - .map(|block| block.body.len() as u64) - .sum::(), - total: blocks.iter().map(|block| block.body.len() as u64).sum::() - } - ); - } - struct TransactionLookupTestRunner { tx: TestTransaction, threshold: u64, diff --git a/crates/storage/db/src/tables/models/accounts.rs b/crates/storage/db/src/tables/models/accounts.rs index c82b4740901..c1a50e95bc1 100644 --- a/crates/storage/db/src/tables/models/accounts.rs +++ b/crates/storage/db/src/tables/models/accounts.rs @@ -64,9 +64,7 @@ impl Compact for AccountBeforeTx { /// [`StorageChangeSet`](crate::tables::StorageChangeSet) /// /// Since it's used as a key, it isn't compressed when encoding it. -#[derive( - Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash, -)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)] pub struct BlockNumberAddress(pub (BlockNumber, Address)); impl BlockNumberAddress { diff --git a/crates/storage/db/src/tables/models/sharded_key.rs b/crates/storage/db/src/tables/models/sharded_key.rs index 5dedd349eb6..a38c3af3a31 100644 --- a/crates/storage/db/src/tables/models/sharded_key.rs +++ b/crates/storage/db/src/tables/models/sharded_key.rs @@ -1,7 +1,5 @@ //! Sharded key -use std::hash::Hash; - use crate::{ table::{Decode, Encode}, DatabaseError, @@ -76,13 +74,3 @@ where Ok(ShardedKey::new(key, highest_tx_number)) } } - -impl Hash for ShardedKey -where - T: Hash, -{ - fn hash(&self, state: &mut H) { - self.key.hash(state); - self.highest_block_number.hash(state); - } -} diff --git a/crates/storage/db/src/tables/models/storage_sharded_key.rs b/crates/storage/db/src/tables/models/storage_sharded_key.rs index 15e6736599f..984933d1f17 100644 --- a/crates/storage/db/src/tables/models/storage_sharded_key.rs +++ b/crates/storage/db/src/tables/models/storage_sharded_key.rs @@ -19,9 +19,7 @@ pub const NUM_OF_INDICES_IN_SHARD: usize = 2_000; /// `Address | Storagekey | 200` -> data is from transition 0 to 200. /// /// `Address | StorageKey | 300` -> data is from transition 201 to 300. -#[derive( - Debug, Default, Clone, Eq, Ord, PartialOrd, PartialEq, AsRef, Serialize, Deserialize, Hash, -)] +#[derive(Debug, Default, Clone, Eq, Ord, PartialOrd, PartialEq, AsRef, Serialize, Deserialize)] pub struct StorageShardedKey { /// Storage account address. pub address: H160, diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 89ee64066b9..db4adab112f 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -25,7 +25,7 @@ tracing.workspace = true # misc auto_impl = "1.0" -itertools.workspace = true +itertools = "0.10" pin-project.workspace = true derive_more = "0.99" parking_lot = "0.12" diff --git a/crates/storage/provider/src/chain.rs b/crates/storage/provider/src/chain.rs index 1633d360f06..b5d596c0164 100644 --- a/crates/storage/provider/src/chain.rs +++ b/crates/storage/provider/src/chain.rs @@ -136,11 +136,6 @@ impl Chain { Self { state, blocks: block_num_hash } } - /// Returns length of the chain. - pub fn len(&self) -> usize { - self.blocks.len() - } - /// Get all receipts for the given block. pub fn receipts_by_block_hash(&self, block_hash: BlockHash) -> Option<&[Receipt]> { let num = self.block_number(block_hash)?; diff --git a/crates/storage/provider/src/post_state/mod.rs b/crates/storage/provider/src/post_state/mod.rs index 300b7e27d6e..846012bffad 100644 --- a/crates/storage/provider/src/post_state/mod.rs +++ b/crates/storage/provider/src/post_state/mod.rs @@ -79,7 +79,7 @@ pub struct PostState { /// The receipt(s) of the executed transaction(s). receipts: BTreeMap>, /// Pruning configuration. - prune_modes: PruneModes, + prune_targets: PruneModes, } impl PostState { @@ -94,8 +94,8 @@ impl PostState { } /// Add a pruning configuration. - pub fn add_prune_modes(&mut self, prune_modes: PruneModes) { - self.prune_modes = prune_modes; + pub fn add_prune_targets(&mut self, prune_targets: PruneModes) { + self.prune_targets = prune_targets; } /// Return the current size of the poststate. @@ -518,7 +518,6 @@ impl PostState { pub fn write_history_to_db<'a, TX: DbTxMut<'a> + DbTx<'a>>( &mut self, tx: &TX, - tip: BlockNumber, ) -> Result<(), DbError> { // Write storage changes tracing::trace!(target: "provider::post_state", "Writing storage changes"); @@ -561,10 +560,6 @@ impl PostState { } } - if self.prune_modes.should_prune_storage_history(block_number, tip) { - continue - } - for (slot, old_value) in storage.storage { tracing::trace!(target: "provider::post_state", ?storage_id, ?slot, ?old_value, "Storage changed"); storage_changeset_cursor.append_dup( @@ -581,10 +576,6 @@ impl PostState { for (block_number, account_changes) in std::mem::take(&mut self.account_changes).inner.into_iter() { - if self.prune_modes.should_prune_account_history(block_number, tip) { - continue - } - for (address, info) in account_changes.into_iter() { tracing::trace!(target: "provider::post_state", block_number, ?address, old = ?info, "Account changed"); account_changeset_cursor @@ -601,7 +592,7 @@ impl PostState { tx: &TX, tip: BlockNumber, ) -> Result<(), DbError> { - self.write_history_to_db(tx, tip)?; + self.write_history_to_db(tx)?; // Write new storage state tracing::trace!(target: "provider::post_state", len = self.storage.len(), "Writing new storage state"); @@ -653,12 +644,12 @@ impl PostState { // Write the receipts of the transactions if not pruned tracing::trace!(target: "provider::post_state", len = self.receipts.len(), "Writing receipts"); - if !self.receipts.is_empty() && self.prune_modes.receipts != Some(PruneMode::Full) { + if !self.receipts.is_empty() && self.prune_targets.receipts != Some(PruneMode::Full) { let mut bodies_cursor = tx.cursor_read::()?; let mut receipts_cursor = tx.cursor_write::()?; for (block, receipts) in self.receipts { - if self.prune_modes.should_prune_receipts(block, tip) { + if self.prune_targets.should_prune_receipts(block, tip) { continue } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 446065457c3..1f871cfa29a 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -640,7 +640,7 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> DatabaseProvider<'this, TX> { &self, keys: impl IntoIterator, batch_size: usize, - mut batch_callback: impl FnMut(usize), + batch_callback: impl Fn(usize), ) -> std::result::Result where T: Table, @@ -650,9 +650,8 @@ impl<'this, TX: DbTxMut<'this> + DbTx<'this>> DatabaseProvider<'this, TX> { let mut deleted = 0; for key in keys { - if cursor.seek_exact(key)?.is_some() { - cursor.delete_current()?; - } + cursor.seek_exact(key)?; + cursor.delete_current()?; deleted += 1; if deleted % batch_size == 0 { diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 458a4c6421e..f62ab7b98c1 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -5,10 +5,8 @@ use crate::{ use reth_db::{ cursor::{DbCursorRO, DbDupCursorRO}, models::{storage_sharded_key::StorageShardedKey, ShardedKey}, - table::Table, tables, transaction::DbTx, - BlockNumberList, }; use reth_interfaces::Result; use reth_primitives::{ @@ -19,11 +17,11 @@ use std::marker::PhantomData; /// State provider for a given transition id which takes a tx reference. /// /// Historical state provider reads the following tables: -/// - [tables::AccountHistory] -/// - [tables::Bytecodes] -/// - [tables::StorageHistory] -/// - [tables::AccountChangeSet] -/// - [tables::StorageChangeSet] +/// [tables::AccountHistory] +/// [tables::Bytecodes] +/// [tables::StorageHistory] +/// [tables::AccountChangeSet] +/// [tables::StorageChangeSet] pub struct HistoricalStateProviderRef<'a, 'b, TX: DbTx<'a>> { /// Transaction tx: &'b TX, @@ -34,7 +32,7 @@ pub struct HistoricalStateProviderRef<'a, 'b, TX: DbTx<'a>> { } pub enum HistoryInfo { - NotYetWritten, + NotWritten, InChangeset(u64), InPlainState, } @@ -49,7 +47,24 @@ impl<'a, 'b, TX: DbTx<'a>> HistoricalStateProviderRef<'a, 'b, TX> { pub fn account_history_lookup(&self, address: Address) -> Result { // history key to search IntegerList of block number changesets. let history_key = ShardedKey::new(address, self.block_number); - self.history_info::(history_key, |key| key.key == address) + let mut cursor = self.tx.cursor_read::()?; + + if let Some(chunk) = + cursor.seek(history_key)?.filter(|(key, _)| key.key == address).map(|x| x.1 .0) + { + let chunk = chunk.enable_rank(); + let rank = chunk.rank(self.block_number as usize); + if rank == 0 && !cursor.prev()?.is_some_and(|(key, _)| key.key == address) { + return Ok(HistoryInfo::NotWritten) + } + if rank < chunk.len() { + Ok(HistoryInfo::InChangeset(chunk.select(rank) as u64)) + } else { + Ok(HistoryInfo::InPlainState) + } + } else { + Ok(HistoryInfo::NotWritten) + } } /// Lookup a storage key in the StorageHistory table @@ -60,47 +75,29 @@ impl<'a, 'b, TX: DbTx<'a>> HistoricalStateProviderRef<'a, 'b, TX> { ) -> Result { // history key to search IntegerList of block number changesets. let history_key = StorageShardedKey::new(address, storage_key, self.block_number); - self.history_info::(history_key, |key| { - key.address == address && key.sharded_key.key == storage_key - }) - } + let mut cursor = self.tx.cursor_read::()?; - fn history_info(&self, key: K, key_filter: impl Fn(&K) -> bool) -> Result - where - T: Table, - { - let mut cursor = self.tx.cursor_read::()?; - - // Lookup the history chunk in the history index. If they key does not appear in the - // index, the first chunk for the next key will be returned so we filter out chunks that - // have a different key. - if let Some(chunk) = cursor.seek(key)?.filter(|(key, _)| key_filter(key)).map(|x| x.1 .0) { + if let Some(chunk) = cursor + .seek(history_key)? + .filter(|(key, _)| key.address == address && key.sharded_key.key == storage_key) + .map(|x| x.1 .0) + { let chunk = chunk.enable_rank(); - - // Get the rank of the first entry after our block. let rank = chunk.rank(self.block_number as usize); - - // If our block is before the first entry in the index chunk, it might be before - // the first write ever. To check, we look at the previous entry and check if the - // key is the same. - // This check is worth it, the `cursor.prev()` check is rarely triggered (the if will - // short-circuit) and when it passes we save a full seek into the changeset/plain state - // table. - if rank == 0 && !cursor.prev()?.is_some_and(|(key, _)| key_filter(&key)) { - // The key is written to, but only after our block. - return Ok(HistoryInfo::NotYetWritten) + if rank == 0 && + !cursor.prev()?.is_some_and(|(key, _)| { + key.address == address && key.sharded_key.key == storage_key + }) + { + return Ok(HistoryInfo::NotWritten) } if rank < chunk.len() { - // The chunk contains an entry for a write after our block, return it. Ok(HistoryInfo::InChangeset(chunk.select(rank) as u64)) } else { - // The chunk does not contain an entry for a write after our block. This can only - // happen if this is the last chunk and so we need to look in the plain state. Ok(HistoryInfo::InPlainState) } } else { - // The key has not been written to at all. - Ok(HistoryInfo::NotYetWritten) + Ok(HistoryInfo::NotWritten) } } } @@ -109,7 +106,7 @@ impl<'a, 'b, TX: DbTx<'a>> AccountReader for HistoricalStateProviderRef<'a, 'b, /// Get basic account information. fn basic_account(&self, address: Address) -> Result> { match self.account_history_lookup(address)? { - HistoryInfo::NotYetWritten => Ok(None), + HistoryInfo::NotWritten => Ok(None), HistoryInfo::InChangeset(changeset_block_number) => Ok(self .tx .cursor_dup_read::()? @@ -155,7 +152,7 @@ impl<'a, 'b, TX: DbTx<'a>> StateProvider for HistoricalStateProviderRef<'a, 'b, /// Get storage. fn storage(&self, address: Address, storage_key: StorageKey) -> Result> { match self.storage_history_lookup(address, storage_key)? { - HistoryInfo::NotYetWritten => Ok(None), + HistoryInfo::NotWritten => Ok(None), HistoryInfo::InChangeset(changeset_block_number) => Ok(Some( self.tx .cursor_dup_read::()? diff --git a/crates/tracing/Cargo.toml b/crates/tracing/Cargo.toml index 8f652da2592..444f1b23afd 100644 --- a/crates/tracing/Cargo.toml +++ b/crates/tracing/Cargo.toml @@ -11,5 +11,5 @@ description = "tracing helpers" [dependencies] tracing.workspace = true tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] } -tracing-appender.workspace = true +tracing-appender = "0.2" tracing-journald = "0.3" diff --git a/crates/tracing/src/lib.rs b/crates/tracing/src/lib.rs index 074b6dc9f07..1695c336e2e 100644 --- a/crates/tracing/src/lib.rs +++ b/crates/tracing/src/lib.rs @@ -68,7 +68,6 @@ where /// /// The boxed layer and a guard is returned. When the guard is dropped the buffer for the log /// file is immediately flushed to disk. Any events after the guard is dropped may be missed. -#[must_use = "tracing guard must be kept alive to flush events to disk"] pub fn file( filter: EnvFilter, dir: impl AsRef, diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index 4f86ef60198..f1add2760e9 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -44,21 +44,13 @@ auto_impl = "1.0" # testing rand = { workspace = true, optional = true } paste = { version = "1.0", optional = true } -proptest = { version = "1.0", optional = true } [dev-dependencies] paste = "1.0" rand = "0.8" -proptest = "1.0" -criterion = "0.5" [features] default = ["serde"] serde = ["dep:serde"] test-utils = ["rand", "paste", "serde"] -arbitrary = ["proptest", "reth-primitives/arbitrary"] optimism = ["reth-primitives/optimism"] - -[[bench]] -name = "reorder" -harness = false diff --git a/crates/transaction-pool/benches/reorder.rs b/crates/transaction-pool/benches/reorder.rs deleted file mode 100644 index 129f1c17ff5..00000000000 --- a/crates/transaction-pool/benches/reorder.rs +++ /dev/null @@ -1,220 +0,0 @@ -use criterion::{ - black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, -}; -use proptest::{ - prelude::*, - strategy::{Strategy, ValueTree}, - test_runner::TestRunner, -}; -use reth_transaction_pool::test_utils::MockTransaction; - -/// Transaction Pool trait for benching. -pub trait BenchTxPool: Default { - fn add_transaction(&mut self, tx: MockTransaction); - fn reorder(&mut self, base_fee: u64); -} - -pub fn txpool_reordering(c: &mut Criterion) { - let mut group = c.benchmark_group("Transaction Pool Reordering"); - - for seed_size in [1_000, 10_000, 50_000, 100_000] { - for input_size in [10, 100, 1_000] { - let (txs, new_txs, base_fee) = generate_test_data(seed_size, input_size); - - use implementations::*; - - // Vanilla sorting of unsorted collection - txpool_reordering_bench::( - &mut group, - "VecTxPoolSortStable", - txs.clone(), - new_txs.clone(), - base_fee, - ); - - // Unstable sorting of unsorted collection - txpool_reordering_bench::( - &mut group, - "VecTxPoolSortUnstable", - txs.clone(), - new_txs.clone(), - base_fee, - ); - - // BinaryHeap that is resorted on each update - txpool_reordering_bench::( - &mut group, - "BinaryHeapTxPool", - txs, - new_txs, - base_fee, - ); - } - } -} - -fn txpool_reordering_bench( - group: &mut BenchmarkGroup, - description: &str, - seed: Vec, - new_txs: Vec, - base_fee: u64, -) { - let setup = || { - let mut txpool = T::default(); - txpool.reorder(base_fee); - - for tx in seed.iter() { - txpool.add_transaction(tx.clone()); - } - (txpool, new_txs.clone()) - }; - - let group_id = format!( - "txpool | seed size: {} | input size: {} | {}", - seed.len(), - new_txs.len(), - description - ); - group.bench_function(group_id, |b| { - b.iter_with_setup(setup, |(mut txpool, new_txs)| { - black_box({ - // Reorder with new base fee - let bigger_base_fee = base_fee.saturating_add(10); - txpool.reorder(bigger_base_fee); - - // Reorder with new base fee after adding transactions. - for new_tx in new_txs { - txpool.add_transaction(new_tx); - } - let smaller_base_fee = base_fee.saturating_sub(10); - txpool.reorder(smaller_base_fee); - }) - }); - }); -} - -fn generate_test_data( - seed_size: usize, - input_size: usize, -) -> (Vec, Vec, u64) { - let config = ProptestConfig::default(); - let mut runner = TestRunner::new(config); - - let txs = prop::collection::vec(any::(), seed_size) - .new_tree(&mut runner) - .unwrap() - .current(); - - let new_txs = prop::collection::vec(any::(), input_size) - .new_tree(&mut runner) - .unwrap() - .current(); - - let base_fee = any::().new_tree(&mut runner).unwrap().current(); - - (txs, new_txs, base_fee) -} - -mod implementations { - use super::*; - use reth_transaction_pool::PoolTransaction; - use std::collections::BinaryHeap; - - /// This implementation appends the transactions and uses [Vec::sort_by] function for sorting. - #[derive(Default)] - pub struct VecTxPoolSortStable { - inner: Vec, - } - - impl BenchTxPool for VecTxPoolSortStable { - fn add_transaction(&mut self, tx: MockTransaction) { - self.inner.push(tx); - } - - fn reorder(&mut self, base_fee: u64) { - self.inner.sort_by(|a, b| { - a.effective_tip_per_gas(base_fee) - .expect("exists") - .cmp(&b.effective_tip_per_gas(base_fee).expect("exists")) - }) - } - } - - /// This implementation appends the transactions and uses [Vec::sort_unstable_by] function for - /// sorting. - #[derive(Default)] - pub struct VecTxPoolSortUnstable { - inner: Vec, - } - - impl BenchTxPool for VecTxPoolSortUnstable { - fn add_transaction(&mut self, tx: MockTransaction) { - self.inner.push(tx); - } - - fn reorder(&mut self, base_fee: u64) { - self.inner.sort_unstable_by(|a, b| { - a.effective_tip_per_gas(base_fee) - .expect("exists") - .cmp(&b.effective_tip_per_gas(base_fee).expect("exists")) - }) - } - } - - struct MockTransactionWithPriority { - tx: MockTransaction, - priority: u128, - } - - impl PartialEq for MockTransactionWithPriority { - fn eq(&self, other: &Self) -> bool { - self.priority.eq(&other.priority) - } - } - - impl Eq for MockTransactionWithPriority {} - - impl PartialOrd for MockTransactionWithPriority { - fn partial_cmp(&self, other: &Self) -> Option { - self.priority.partial_cmp(&other.priority) - } - } - - impl Ord for MockTransactionWithPriority { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.priority.cmp(&other.priority) - } - } - - /// This implementation uses BinaryHeap which is drained and reconstructed on each reordering. - #[derive(Default)] - pub struct BinaryHeapTxPool { - inner: BinaryHeap, - base_fee: Option, - } - - impl BenchTxPool for BinaryHeapTxPool { - fn add_transaction(&mut self, tx: MockTransaction) { - let priority = self - .base_fee - .as_ref() - .map(|bf| tx.effective_tip_per_gas(*bf).expect("set")) - .unwrap_or_default(); - self.inner.push(MockTransactionWithPriority { tx, priority }); - } - - fn reorder(&mut self, base_fee: u64) { - self.base_fee = Some(base_fee); - - let drained = self.inner.drain(); - self.inner = BinaryHeap::from_iter(drained.map(|mock| { - let priority = mock.tx.effective_tip_per_gas(base_fee).expect("set"); - MockTransactionWithPriority { tx: mock.tx, priority } - })); - } - } -} - -criterion_group!(reorder, txpool_reordering); -criterion_main!(reorder); diff --git a/crates/transaction-pool/src/config.rs b/crates/transaction-pool/src/config.rs index aa6896305b4..faf0c0156b4 100644 --- a/crates/transaction-pool/src/config.rs +++ b/crates/transaction-pool/src/config.rs @@ -7,12 +7,6 @@ pub const TXPOOL_SUBPOOL_MAX_TXS_DEFAULT: usize = 10_000; /// The default maximum allowed size of the given subpool. pub const TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT: usize = 20; -/// Default price bump (in %) for the transaction pool underpriced check. -pub const DEFAULT_PRICE_BUMP: u128 = 10; - -/// Replace blob price bump (in %) for the transaction pool underpriced check. -pub const REPLACE_BLOB_PRICE_BUMP: u128 = 100; - /// Configuration options for the Transaction pool. #[derive(Debug, Clone)] pub struct PoolConfig { @@ -24,8 +18,6 @@ pub struct PoolConfig { pub queued_limit: SubPoolLimit, /// Max number of executable transaction slots guaranteed per account pub max_account_slots: usize, - /// Price bump (in %) for the transaction pool underpriced check. - pub price_bump: u128, } impl Default for PoolConfig { @@ -35,7 +27,6 @@ impl Default for PoolConfig { basefee_limit: Default::default(), queued_limit: Default::default(), max_account_slots: TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, - price_bump: PriceBumpConfig::default().default_price_bump, } } } @@ -66,21 +57,3 @@ impl Default for SubPoolLimit { } } } - -/// Price bump config (in %) for the transaction pool underpriced check. -#[derive(Debug, Clone)] -pub struct PriceBumpConfig { - /// Default price bump (in %) for the transaction pool underpriced check. - pub default_price_bump: u128, - /// Replace blob price bump (in %) for the transaction pool underpriced check. - pub replace_blob_tx_price_bump: u128, -} - -impl Default for PriceBumpConfig { - fn default() -> Self { - Self { - default_price_bump: DEFAULT_PRICE_BUMP, - replace_blob_tx_price_bump: REPLACE_BLOB_PRICE_BUMP, - } - } -} diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index 8c4ccc502db..d4c25f047e7 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -10,7 +10,8 @@ rust_2018_idioms, unreachable_pub, missing_debug_implementations, - rustdoc::broken_intra_doc_links + rustdoc::broken_intra_doc_links, + unused_crate_dependencies )] #![doc(test( no_crate_inject, @@ -153,12 +154,11 @@ use tracing::{instrument, trace}; pub use crate::{ config::{ - PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, REPLACE_BLOB_PRICE_BUMP, - TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, - TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, + PoolConfig, SubPoolLimit, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }, error::PoolResult, - ordering::{CoinbaseTipOrdering, Priority, TransactionOrdering}, + ordering::{GasCostOrdering, TransactionOrdering}, pool::{ state::SubPool, AllTransactionsEvents, FullTransactionEvent, TransactionEvent, TransactionEvents, @@ -190,6 +190,27 @@ mod traits; /// Common test helpers for mocking a pool pub mod test_utils; +// TX_SLOT_SIZE is used to calculate how many data slots a single transaction +// takes up based on its size. The slots are used as DoS protection, ensuring +// that validating a new transaction remains a constant operation (in reality +// O(maxslots), where max slots are 4 currently). +pub(crate) const TX_SLOT_SIZE: usize = 32 * 1024; + +// TX_MAX_SIZE is the maximum size a single transaction can have. This field has +// non-trivial consequences: larger transactions are significantly harder and +// more expensive to propagate; larger transactions also take more resources +// to validate whether they fit into the pool or not. +pub(crate) const TX_MAX_SIZE: usize = 4 * TX_SLOT_SIZE; //128KB + +// Maximum bytecode to permit for a contract +pub(crate) const MAX_CODE_SIZE: usize = 24576; + +// Maximum initcode to permit in a creation transaction and create instructions +pub(crate) const MAX_INIT_CODE_SIZE: usize = 2 * MAX_CODE_SIZE; + +// Price bump (in %) for the transaction pool underpriced check +pub(crate) const PRICE_BUMP: u128 = 10; + /// A shareable, generic, customizable `TransactionPool` implementation. #[derive(Debug)] pub struct Pool { @@ -260,12 +281,12 @@ where } impl - Pool, CoinbaseTipOrdering> + Pool, GasCostOrdering> where Client: StateProviderFactory + Clone + 'static, { /// Returns a new [Pool] that uses the default [EthTransactionValidator] when validating - /// [PooledTransaction]s and ords via [CoinbaseTipOrdering] + /// [PooledTransaction]s and ords via [GasCostOrdering] /// /// # Example /// @@ -285,7 +306,7 @@ where validator: EthTransactionValidator, config: PoolConfig, ) -> Self { - Self::new(validator, CoinbaseTipOrdering::default(), config) + Self::new(validator, GasCostOrdering::default(), config) } } diff --git a/crates/transaction-pool/src/ordering.rs b/crates/transaction-pool/src/ordering.rs index ffa185f1f0e..40ee1700661 100644 --- a/crates/transaction-pool/src/ordering.rs +++ b/crates/transaction-pool/src/ordering.rs @@ -2,26 +2,6 @@ use crate::traits::PoolTransaction; use reth_primitives::U256; use std::{fmt, marker::PhantomData}; -/// Priority of the transaction that can be missing. -/// -/// Transactions with missing priorities are ranked lower. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)] -pub enum Priority { - /// The value of the priority of the transaction. - Value(T), - /// Missing priority due to ordering internals. - None, -} - -impl From> for Priority { - fn from(value: Option) -> Self { - match value { - Some(val) => Priority::Value(val), - None => Priority::None, - } - } -} - /// Transaction ordering trait to determine the order of transactions. /// /// Decides how transactions should be ordered within the pool, depending on a `Priority` value. @@ -31,53 +11,42 @@ pub trait TransactionOrdering: Send + Sync + 'static { /// Priority of a transaction. /// /// Higher is better. - type PriorityValue: Ord + Clone + Default + fmt::Debug + Send + Sync; + type Priority: Ord + Clone + Default + fmt::Debug + Send + Sync; /// The transaction type to determine the priority of. type Transaction: PoolTransaction; /// Returns the priority score for the given transaction. - fn priority( - &self, - transaction: &Self::Transaction, - base_fee: u64, - ) -> Priority; + fn priority(&self, transaction: &Self::Transaction) -> Self::Priority; } /// Default ordering for the pool. /// -/// The transactions are ordered by their coinbase tip. -/// The higher the coinbase tip is, the higher the priority of the transaction. +/// The transactions are ordered by their gas cost. The higher the gas cost, +/// the higher the priority of this transaction is. #[derive(Debug)] #[non_exhaustive] -pub struct CoinbaseTipOrdering(PhantomData); +pub struct GasCostOrdering(PhantomData); -impl TransactionOrdering for CoinbaseTipOrdering +impl TransactionOrdering for GasCostOrdering where T: PoolTransaction + 'static, { - type PriorityValue = U256; + type Priority = U256; type Transaction = T; - /// Source: . - /// - /// NOTE: The implementation is incomplete for missing base fee. - fn priority( - &self, - transaction: &Self::Transaction, - base_fee: u64, - ) -> Priority { - transaction.effective_tip_per_gas(base_fee).map(U256::from).into() + fn priority(&self, transaction: &Self::Transaction) -> Self::Priority { + transaction.gas_cost() } } -impl Default for CoinbaseTipOrdering { +impl Default for GasCostOrdering { fn default() -> Self { Self(Default::default()) } } -impl Clone for CoinbaseTipOrdering { +impl Clone for GasCostOrdering { fn clone(&self) -> Self { Self::default() } diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index c5190327f09..071063aeda5 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -1,6 +1,7 @@ use crate::{ - identifier::TransactionId, pool::pending::PendingTransaction, PoolTransaction, - TransactionOrdering, ValidPoolTransaction, + identifier::TransactionId, + pool::pending::{PendingTransaction, PendingTransactionRef}, + PoolTransaction, TransactionOrdering, ValidPoolTransaction, }; use reth_primitives::H256 as TxHash; use std::{ @@ -53,12 +54,12 @@ impl Iterator for BestTransactionsWithBasefee { pub(crate) struct BestTransactions { /// Contains a copy of _all_ transactions of the pending pool at the point in time this /// iterator was created. - pub(crate) all: BTreeMap>, + pub(crate) all: BTreeMap>>, /// Transactions that can be executed right away: these have the expected nonce. /// /// Once an `independent` transaction with the nonce `N` is returned, it unlocks `N+1`, which /// then can be moved from the `all` set to the `independent` set. - pub(crate) independent: BTreeSet>, + pub(crate) independent: BTreeSet>, /// There might be the case where a yielded transactions is invalid, this will track it. pub(crate) invalid: HashSet, } @@ -73,7 +74,7 @@ impl BestTransactions { /// /// Note: for a transaction with nonce higher than the current on chain nonce this will always /// return an ancestor since all transaction in this pool are gapless. - pub(crate) fn ancestor(&self, id: &TransactionId) -> Option<&PendingTransaction> { + pub(crate) fn ancestor(&self, id: &TransactionId) -> Option<&Arc>> { self.all.get(&id.unchecked_ancestor()?) } } @@ -105,7 +106,7 @@ impl Iterator for BestTransactions { // Insert transactions that just got unlocked. if let Some(unlocked) = self.all.get(&best.unlocks()) { - self.independent.insert(unlocked.clone()); + self.independent.insert(unlocked.transaction.clone()); } return Some(best.transaction) @@ -132,7 +133,7 @@ mod tests { for nonce in 0..num_tx { let tx = tx.clone().rng_hash().with_nonce(nonce); let valid_tx = f.validated(tx); - pool.add_transaction(Arc::new(valid_tx), 0); + pool.add_transaction(Arc::new(valid_tx)); } let mut best = pool.best(); @@ -158,7 +159,7 @@ mod tests { for nonce in 0..num_tx { let tx = tx.clone().rng_hash().with_nonce(nonce); let valid_tx = f.validated(tx); - pool.add_transaction(Arc::new(valid_tx), 0); + pool.add_transaction(Arc::new(valid_tx)); } let mut best = pool.best(); diff --git a/crates/transaction-pool/src/pool/parked.rs b/crates/transaction-pool/src/pool/parked.rs index 740af02a971..1965fe8c8c1 100644 --- a/crates/transaction-pool/src/pool/parked.rs +++ b/crates/transaction-pool/src/pool/parked.rs @@ -306,11 +306,10 @@ pub(crate) struct QueuedOrd(Arc>); impl_ord_wrapper!(QueuedOrd); -// TODO: temporary solution for ordering the queued pool. impl Ord for QueuedOrd { fn cmp(&self, other: &Self) -> Ordering { - // Higher price is better - self.max_fee_per_gas().cmp(&self.max_fee_per_gas()).then_with(|| + // Higher cost is better + self.gas_cost().cmp(&other.gas_cost()).then_with(|| // Lower timestamp is better other.timestamp.cmp(&self.timestamp)) } diff --git a/crates/transaction-pool/src/pool/pending.rs b/crates/transaction-pool/src/pool/pending.rs index 0ec5be69b56..dd77997dcc7 100644 --- a/crates/transaction-pool/src/pool/pending.rs +++ b/crates/transaction-pool/src/pool/pending.rs @@ -1,7 +1,7 @@ use crate::{ identifier::TransactionId, pool::{best::BestTransactions, size::SizeTracker}, - Priority, TransactionOrdering, ValidPoolTransaction, + TransactionOrdering, ValidPoolTransaction, }; use crate::pool::best::BestTransactionsWithBasefee; @@ -30,14 +30,14 @@ pub(crate) struct PendingPool { /// This way we can determine when transactions where submitted to the pool. submission_id: u64, /// _All_ Transactions that are currently inside the pool grouped by their identifier. - by_id: BTreeMap>, + by_id: BTreeMap>>, /// _All_ transactions sorted by priority - all: BTreeSet>, + all: BTreeSet>, /// Independent transactions that can be included directly and don't require other /// transactions. /// /// Sorted by their scoring value. - independent_transactions: BTreeSet>, + independent_transactions: BTreeSet>, /// Keeps track of the size of this pool. /// /// See also [`PoolTransaction::size`](crate::traits::PoolTransaction::size). @@ -103,19 +103,19 @@ impl PendingPool { pub(crate) fn best_with_unlocked( &self, unlocked: Vec>>, - base_fee: u64, ) -> BestTransactions { let mut best = self.best(); let mut submission_id = self.submission_id; for tx in unlocked { submission_id += 1; debug_assert!(!best.all.contains_key(tx.id()), "transaction already included"); - let priority = self.ordering.priority(&tx.transaction, base_fee); + let priority = self.ordering.priority(&tx.transaction); let tx_id = *tx.id(); - let transaction = PendingTransaction { submission_id, transaction: tx, priority }; + let transaction = PendingTransactionRef { submission_id, transaction: tx, priority }; if best.ancestor(&tx_id).is_none() { best.independent.insert(transaction.clone()); } + let transaction = Arc::new(PendingTransaction { transaction }); best.all.insert(tx_id, transaction); } @@ -126,32 +126,25 @@ impl PendingPool { pub(crate) fn all( &self, ) -> impl Iterator>> + '_ { - self.by_id.values().map(|tx| tx.transaction.clone()) + self.by_id.values().map(|tx| tx.transaction.transaction.clone()) } - /// Updates the pool with the new base fee. Reorders transactions by new priorities. Removes - /// from the subpool all transactions and their dependents that no longer satisfy the given - /// base fee (`tx.fee < base_fee`). + /// Removes all transactions and their dependent transaction from the subpool that no longer + /// satisfy the given basefee (`tx.fee < basefee`) /// /// Note: the transactions are not returned in a particular order. - /// - /// # Returns - /// - /// Removed transactions that no longer satisfy the base fee. - pub(crate) fn update_base_fee( + pub(crate) fn enforce_basefee( &mut self, - base_fee: u64, + basefee: u64, ) -> Vec>> { - // Create a collection for txs to remove . let mut to_remove = Vec::new(); - // Iterate over transactions, find the ones we need to remove and update others in place. { - let mut iter = self.by_id.iter_mut().peekable(); + let mut iter = self.by_id.iter().peekable(); while let Some((id, tx)) = iter.next() { - if tx.transaction.max_fee_per_gas() < base_fee as u128 { - // This transaction no longer satisfies the basefee: remove it and all its - // descendants. + if tx.transaction.transaction.max_fee_per_gas() < basefee as u128 { + // this transaction no longer satisfies the basefee: remove it and all its + // descendants to_remove.push(*id); 'this: while let Some((peek, _)) = iter.peek() { if peek.sender != id.sender { @@ -160,13 +153,6 @@ impl PendingPool { to_remove.push(**peek); iter.next(); } - } else { - // Update the transaction with new priority. - let new_priority = - self.ordering.priority(&tx.transaction.transaction, base_fee); - tx.priority = new_priority; - - self.all.insert(tx.clone()); } } } @@ -176,10 +162,6 @@ impl PendingPool { removed.push(self.remove_transaction(&id).expect("transaction exists")); } - // Clear ordered lists since the priority would be changed. - self.independent_transactions.clear(); - self.all.clear(); - removed } @@ -187,7 +169,7 @@ impl PendingPool { /// /// Note: for a transaction with nonce higher than the current on chain nonce this will always /// return an ancestor since all transaction in this pool are gapless. - fn ancestor(&self, id: &TransactionId) -> Option<&PendingTransaction> { + fn ancestor(&self, id: &TransactionId) -> Option<&Arc>> { self.by_id.get(&id.unchecked_ancestor()?) } @@ -196,34 +178,33 @@ impl PendingPool { /// # Panics /// /// if the transaction is already included - pub(crate) fn add_transaction( - &mut self, - tx: Arc>, - base_fee: u64, - ) { + pub(crate) fn add_transaction(&mut self, tx: Arc>) { assert!( !self.by_id.contains_key(tx.id()), "transaction already included {:?}", self.by_id.contains_key(tx.id()) ); + let tx_id = *tx.id(); + let submission_id = self.next_id(); + + let priority = self.ordering.priority(&tx.transaction); + // keep track of size self.size_of += tx.size(); - let tx_id = *tx.id(); - - let submission_id = self.next_id(); - let priority = self.ordering.priority(&tx.transaction, base_fee); - let tx = PendingTransaction { submission_id, transaction: tx, priority }; + let transaction = PendingTransactionRef { submission_id, transaction: tx, priority }; // If there's __no__ ancestor in the pool, then this transaction is independent, this is // guaranteed because this pool is gapless. if self.ancestor(&tx_id).is_none() { - self.independent_transactions.insert(tx.clone()); + self.independent_transactions.insert(transaction.clone()); } - self.all.insert(tx.clone()); + self.all.insert(transaction.clone()); + + let transaction = Arc::new(PendingTransaction { transaction }); - self.by_id.insert(tx_id, tx); + self.by_id.insert(tx_id, transaction); } /// Removes a _mined_ transaction from the pool. @@ -235,7 +216,7 @@ impl PendingPool { ) -> Option>> { // mark the next as independent if it exists if let Some(unlocked) = self.by_id.get(&id.descendant()) { - self.independent_transactions.insert(unlocked.clone()); + self.independent_transactions.insert(unlocked.transaction.clone()); }; self.remove_transaction(id) } @@ -248,10 +229,10 @@ impl PendingPool { id: &TransactionId, ) -> Option>> { let tx = self.by_id.remove(id)?; - self.all.remove(&tx); - self.size_of -= tx.transaction.size(); - self.independent_transactions.remove(&tx); - Some(tx.transaction.clone()) + self.all.remove(&tx.transaction); + self.size_of -= tx.transaction.transaction.size(); + self.independent_transactions.remove(&tx.transaction); + Some(tx.transaction.transaction.clone()) } fn next_id(&mut self) -> u64 { @@ -285,22 +266,34 @@ impl PendingPool { /// A transaction that is ready to be included in a block. pub(crate) struct PendingTransaction { + /// Reference to the actual transaction. + pub(crate) transaction: PendingTransactionRef, +} + +impl Clone for PendingTransaction { + fn clone(&self) -> Self { + Self { transaction: self.transaction.clone() } + } +} + +/// A transaction that is ready to be included in a block. +pub(crate) struct PendingTransactionRef { /// Identifier that tags when transaction was submitted in the pool. pub(crate) submission_id: u64, /// Actual transaction. pub(crate) transaction: Arc>, /// The priority value assigned by the used `Ordering` function. - pub(crate) priority: Priority, + pub(crate) priority: T::Priority, } -impl PendingTransaction { +impl PendingTransactionRef { /// The next transaction of the sender: `nonce + 1` pub(crate) fn unlocks(&self) -> TransactionId { self.transaction.transaction_id.descendant() } } -impl Clone for PendingTransaction { +impl Clone for PendingTransactionRef { fn clone(&self) -> Self { Self { submission_id: self.submission_id, @@ -310,21 +303,21 @@ impl Clone for PendingTransaction { } } -impl Eq for PendingTransaction {} +impl Eq for PendingTransactionRef {} -impl PartialEq for PendingTransaction { +impl PartialEq for PendingTransactionRef { fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } } -impl PartialOrd for PendingTransaction { +impl PartialOrd for PendingTransactionRef { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for PendingTransaction { +impl Ord for PendingTransactionRef { fn cmp(&self, other: &Self) -> Ordering { // This compares by `priority` and only if two tx have the exact same priority this compares // the unique `submission_id`. This ensures that transactions with same priority are not @@ -345,15 +338,15 @@ mod tests { let mut f = MockTransactionFactory::default(); let mut pool = PendingPool::new(MockOrdering::default()); let tx = f.validated_arc(MockTransaction::eip1559().inc_price()); - pool.add_transaction(tx.clone(), 0); + pool.add_transaction(tx.clone()); assert!(pool.by_id.contains_key(tx.id())); assert_eq!(pool.len(), 1); - let removed = pool.update_base_fee(0); + let removed = pool.enforce_basefee(0); assert!(removed.is_empty()); - let removed = pool.update_base_fee((tx.max_fee_per_gas() + 1) as u64); + let removed = pool.enforce_basefee((tx.max_fee_per_gas() + 1) as u64); assert_eq!(removed.len(), 1); assert!(pool.is_empty()); } @@ -364,10 +357,10 @@ mod tests { let mut pool = PendingPool::new(MockOrdering::default()); let t = MockTransaction::eip1559().inc_price_by(10); let root_tx = f.validated_arc(t.clone()); - pool.add_transaction(root_tx.clone(), 0); + pool.add_transaction(root_tx.clone()); let descendant_tx = f.validated_arc(t.inc_nonce().decr_price()); - pool.add_transaction(descendant_tx.clone(), 0); + pool.add_transaction(descendant_tx.clone()); assert!(pool.by_id.contains_key(root_tx.id())); assert!(pool.by_id.contains_key(descendant_tx.id())); @@ -375,14 +368,14 @@ mod tests { assert_eq!(pool.independent_transactions.len(), 1); - let removed = pool.update_base_fee(0); + let removed = pool.enforce_basefee(0); assert!(removed.is_empty()); // two dependent tx in the pool with decreasing fee { let mut pool2 = pool.clone(); - let removed = pool2.update_base_fee((descendant_tx.max_fee_per_gas() + 1) as u64); + let removed = pool2.enforce_basefee((descendant_tx.max_fee_per_gas() + 1) as u64); assert_eq!(removed.len(), 1); assert_eq!(pool2.len(), 1); // descendant got popped @@ -391,7 +384,7 @@ mod tests { } // remove root transaction via fee - let removed = pool.update_base_fee((root_tx.max_fee_per_gas() + 1) as u64); + let removed = pool.enforce_basefee((root_tx.max_fee_per_gas() + 1) as u64); assert_eq!(removed.len(), 2); assert!(pool.is_empty()); } diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 29220699876..cd0d607387d 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -13,7 +13,8 @@ use crate::{ AddedPendingTransaction, AddedTransaction, OnNewCanonicalStateOutcome, }, traits::{BlockInfo, PoolSize}, - PoolConfig, PoolResult, PoolTransaction, TransactionOrdering, ValidPoolTransaction, U256, + PoolConfig, PoolResult, PoolTransaction, TransactionOrdering, ValidPoolTransaction, PRICE_BUMP, + U256, }; use fnv::FnvHashMap; use reth_primitives::{ @@ -148,8 +149,7 @@ impl TxPool { } Ordering::Greater => { // increased base fee: recheck pending pool and remove all that are no longer valid - let removed = self.pending_pool.update_base_fee(pending_basefee); - for tx in removed { + for tx in self.pending_pool.enforce_basefee(pending_basefee) { let to = { let tx = self.all_transactions.txs.get_mut(tx.id()).expect("tx exists in set"); @@ -162,8 +162,7 @@ impl TxPool { } Ordering::Less => { // decreased base fee: recheck basefee pool and promote all that are now valid - let removed = self.basefee_pool.enforce_basefee(pending_basefee); - for tx in removed { + for tx in self.basefee_pool.enforce_basefee(pending_basefee) { let to = { let tx = self.all_transactions.txs.get_mut(tx.id()).expect("tx exists in set"); @@ -184,7 +183,6 @@ impl TxPool { let BlockInfo { last_seen_block_hash, last_seen_block_number, pending_basefee } = info; self.all_transactions.last_seen_block_hash = last_seen_block_hash; self.all_transactions.last_seen_block_number = last_seen_block_number; - self.all_transactions.pending_basefee = pending_basefee; self.update_basefee(pending_basefee) } @@ -213,10 +211,7 @@ impl TxPool { // base fee decreased, we need to move transactions from the basefee pool to the // pending pool let unlocked = self.basefee_pool.satisfy_base_fee_transactions(basefee); - Box::new( - self.pending_pool - .best_with_unlocked(unlocked, self.all_transactions.pending_basefee), - ) + Box::new(self.pending_pool.best_with_unlocked(unlocked)) } } } @@ -550,7 +545,7 @@ impl TxPool { self.queued_pool.add_transaction(tx); } SubPool::Pending => { - self.pending_pool.add_transaction(tx, self.all_transactions.pending_basefee); + self.pending_pool.add_transaction(tx); } SubPool::BaseFee => { self.basefee_pool.add_transaction(tx); @@ -1110,7 +1105,7 @@ impl AllTransactions { if Self::is_underpriced( transaction.as_ref(), entry.get().transaction.as_ref(), - PoolConfig::default().price_bump, + PRICE_BUMP, ) { return Err(InsertErr::Underpriced { transaction: pool_tx.transaction, diff --git a/crates/transaction-pool/src/test_utils/mock.rs b/crates/transaction-pool/src/test_utils/mock.rs index c03a45168e1..bf2c8382c71 100644 --- a/crates/transaction-pool/src/test_utils/mock.rs +++ b/crates/transaction-pool/src/test_utils/mock.rs @@ -4,7 +4,7 @@ use crate::{ identifier::{SenderIdentifiers, TransactionId}, pool::txpool::TxPool, traits::TransactionOrigin, - PoolTransaction, Priority, TransactionOrdering, ValidPoolTransaction, + PoolTransaction, TransactionOrdering, ValidPoolTransaction, }; use paste::paste; use rand::{ @@ -14,7 +14,7 @@ use rand::{ use reth_primitives::{ constants::MIN_PROTOCOL_BASE_FEE, hex, Address, FromRecoveredTransaction, IntoRecoveredTransaction, Signature, Transaction, TransactionKind, TransactionSigned, - TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxHash, TxLegacy, TxType, H256, U128, U256, + TransactionSignedEcRecovered, TxEip1559, TxHash, TxLegacy, TxType, H256, U128, U256, }; use std::{ops::Range, sync::Arc, time::Instant}; @@ -370,6 +370,19 @@ impl PoolTransaction for MockTransaction { } } + fn gas_cost(&self) -> U256 { + match self { + MockTransaction::Legacy { gas_price, gas_limit, .. } => { + U256::from(*gas_limit) * U256::from(*gas_price) + } + MockTransaction::Eip1559 { max_fee_per_gas, gas_limit, .. } => { + U256::from(*gas_limit) * U256::from(*max_fee_per_gas) + } + #[cfg(feature = "optimism")] + MockTransaction::DepositTx { .. } => U256::ZERO, + } + } + fn gas_limit(&self) -> u64 { self.get_gas_limit() } @@ -394,28 +407,6 @@ impl PoolTransaction for MockTransaction { } } - fn effective_tip_per_gas(&self, base_fee: u64) -> Option { - let base_fee = base_fee as u128; - let max_fee_per_gas = self.max_fee_per_gas(); - if max_fee_per_gas < base_fee { - return None - } - - let fee = max_fee_per_gas - base_fee; - if let Some(priority_fee) = self.max_priority_fee_per_gas() { - return Some(fee.min(priority_fee)) - } - - Some(fee) - } - - fn priority_fee_or_price(&self) -> u128 { - match self { - MockTransaction::Legacy { gas_price, .. } => *gas_price, - MockTransaction::Eip1559 { max_priority_fee_per_gas, .. } => *max_priority_fee_per_gas, - } - } - fn kind(&self) -> &TransactionKind { match self { #[cfg(feature = "optimism")] @@ -542,66 +533,6 @@ impl IntoRecoveredTransaction for MockTransaction { } } -#[cfg(any(test, feature = "arbitrary"))] -impl proptest::arbitrary::Arbitrary for MockTransaction { - type Parameters = (); - type Strategy = proptest::strategy::BoxedStrategy; - - fn arbitrary_with(_: Self::Parameters) -> Self::Strategy { - use proptest::prelude::{any, Strategy}; - - any::<(Transaction, Address, H256)>() - .prop_map(|(tx, sender, tx_hash)| match &tx { - Transaction::Legacy(TxLegacy { - nonce, - gas_price, - gas_limit, - to, - value, - input, - .. - }) | - Transaction::Eip2930(TxEip2930 { - nonce, - gas_price, - gas_limit, - to, - value, - input, - .. - }) => MockTransaction::Legacy { - sender, - hash: tx_hash, - nonce: *nonce, - gas_price: *gas_price, - gas_limit: *gas_limit, - to: *to, - value: U256::from(*value), - }, - Transaction::Eip1559(TxEip1559 { - nonce, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - to, - value, - input, - .. - }) => MockTransaction::Eip1559 { - sender, - hash: tx_hash, - nonce: *nonce, - max_fee_per_gas: *max_fee_per_gas, - max_priority_fee_per_gas: *max_priority_fee_per_gas, - gas_limit: *gas_limit, - to: *to, - value: U256::from(*value), - }, - }) - .boxed() - } -} - #[derive(Default)] pub struct MockTransactionFactory { pub(crate) ids: SenderIdentifiers, @@ -654,15 +585,11 @@ impl MockTransactionFactory { pub struct MockOrdering; impl TransactionOrdering for MockOrdering { - type PriorityValue = U256; + type Priority = U256; type Transaction = MockTransaction; - fn priority( - &self, - transaction: &Self::Transaction, - base_fee: u64, - ) -> Priority { - transaction.effective_tip_per_gas(base_fee).map(U256::from).into() + fn priority(&self, transaction: &Self::Transaction) -> Self::Priority { + transaction.gas_cost() } } @@ -704,5 +631,5 @@ fn test_mock_priority() { let o = MockOrdering; let lo = MockTransaction::eip1559().with_gas_limit(100_000); let hi = lo.next().inc_price(); - assert!(o.priority(&hi, 0) > o.priority(&lo, 0)); + assert!(o.priority(&hi) > o.priority(&lo)); } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index c32dbe5181b..6c69d8df13e 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -470,6 +470,12 @@ pub trait PoolTransaction: /// For legacy transactions: `gas_price * gas_limit + tx_value`. fn cost(&self) -> U256; + /// Returns the gas cost for this transaction. + /// + /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit`. + /// For legacy transactions: `gas_price * gas_limit`. + fn gas_cost(&self) -> U256; + /// Amount of gas that should be used in executing this transaction. This is paid up-front. fn gas_limit(&self) -> u64; @@ -485,16 +491,6 @@ pub trait PoolTransaction: /// This will return `None` for non-EIP1559 transactions fn max_priority_fee_per_gas(&self) -> Option; - /// Returns the effective tip for this transaction. - /// - /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. - /// For legacy transactions: `gas_price - base_fee`. - fn effective_tip_per_gas(&self, base_fee: u64) -> Option; - - /// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and - /// otherwise returns the gas price. - fn priority_fee_or_price(&self) -> u128; - /// Returns the transaction's [`TransactionKind`], which is the address of the recipient or /// [`TransactionKind::Create`] if the transaction is a contract creation. fn kind(&self) -> &TransactionKind; @@ -529,27 +525,13 @@ pub struct PooledTransaction { /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit + tx_value`. /// For legacy transactions: `gas_price * gas_limit + tx_value`. pub(crate) cost: U256, + + /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit`. + /// For legacy transactions: `gas_price * gas_limit`. + pub(crate) gas_cost: U256, } impl PooledTransaction { - /// Create new instance of [Self]. - pub fn new(transaction: TransactionSignedEcRecovered) -> Self { - let gas_cost = match &transaction.transaction { - Transaction::Legacy(t) => U256::from(t.gas_price) * U256::from(t.gas_limit), - Transaction::Eip2930(t) => U256::from(t.gas_price) * U256::from(t.gas_limit), - Transaction::Eip1559(t) => U256::from(t.max_fee_per_gas) * U256::from(t.gas_limit), - #[cfg(feature = "optimism")] - Transaction::Deposit(_) => { - // Gas price is always set to 0 for deposits in order to zero out ETH refunds, - // because they already pay for their gas on L1. - U256::ZERO - } - }; - let cost = gas_cost + U256::from(transaction.value()); - - Self { transaction, cost } - } - /// Return the reference to the underlying transaction. pub fn transaction(&self) -> &TransactionSignedEcRecovered { &self.transaction @@ -580,6 +562,14 @@ impl PoolTransaction for PooledTransaction { self.cost } + /// Returns the gas cost for this transaction. + /// + /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit + tx_value`. + /// For legacy transactions: `gas_price * gas_limit + tx_value`. + fn gas_cost(&self) -> U256 { + self.gas_cost + } + /// Amount of gas that should be used in executing this transaction. This is paid up-front. fn gas_limit(&self) -> u64 { self.transaction.gas_limit() @@ -613,20 +603,6 @@ impl PoolTransaction for PooledTransaction { } } - /// Returns the effective tip for this transaction. - /// - /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. - /// For legacy transactions: `gas_price - base_fee`. - fn effective_tip_per_gas(&self, base_fee: u64) -> Option { - self.transaction.effective_tip_per_gas(base_fee) - } - - /// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and - /// otherwise returns the gas price. - fn priority_fee_or_price(&self) -> u128 { - self.transaction.priority_fee_or_price() - } - /// Returns the transaction's [`TransactionKind`], which is the address of the recipient or /// [`TransactionKind::Create`] if the transaction is a contract creation. fn kind(&self) -> &TransactionKind { @@ -656,7 +632,20 @@ impl PoolTransaction for PooledTransaction { impl FromRecoveredTransaction for PooledTransaction { fn from_recovered_transaction(tx: TransactionSignedEcRecovered) -> Self { - PooledTransaction::new(tx) + let gas_cost = match &tx.transaction { + Transaction::Legacy(t) => U256::from(t.gas_price) * U256::from(t.gas_limit), + Transaction::Eip2930(t) => U256::from(t.gas_price) * U256::from(t.gas_limit), + Transaction::Eip1559(t) => U256::from(t.max_fee_per_gas) * U256::from(t.gas_limit), + #[cfg(feature = "optimism")] + Transaction::Deposit(_) => { + // Gas price is always set to 0 for deposits in order to zero out ETH refunds, + // because they already pay for their gas on L1. + U256::ZERO + } + }; + let cost = gas_cost + U256::from(tx.value()); + + PooledTransaction { transaction: tx, cost, gas_cost } } } diff --git a/crates/transaction-pool/src/validate/constants.rs b/crates/transaction-pool/src/validate/constants.rs deleted file mode 100644 index 040087bdb02..00000000000 --- a/crates/transaction-pool/src/validate/constants.rs +++ /dev/null @@ -1,17 +0,0 @@ -/// TX_SLOT_SIZE is used to calculate how many data slots a single transaction -/// takes up based on its size. The slots are used as DoS protection, ensuring -/// that validating a new transaction remains a constant operation (in reality -/// O(maxslots), where max slots are 4 currently). -pub const TX_SLOT_SIZE: usize = 32 * 1024; - -/// TX_MAX_SIZE is the maximum size a single transaction can have. This field has -/// non-trivial consequences: larger transactions are significantly harder and -/// more expensive to propagate; larger transactions also take more resources -/// to validate whether they fit into the pool or not. -pub const TX_MAX_SIZE: usize = 4 * TX_SLOT_SIZE; // 128KB - -/// Maximum bytecode to permit for a contract -pub const MAX_CODE_SIZE: usize = 24576; - -/// Maximum initcode to permit in a creation transaction and create instructions -pub const MAX_INIT_CODE_SIZE: usize = 2 * MAX_CODE_SIZE; diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index bfcf04028ad..2a4bbbf8ec2 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -3,11 +3,8 @@ use crate::{ error::InvalidPoolTransactionError, traits::{PoolTransaction, TransactionOrigin}, - validate::{ - task::ValidationJobSender, TransactionValidatorError, ValidationTask, MAX_INIT_CODE_SIZE, - TX_MAX_SIZE, - }, - TransactionValidationOutcome, TransactionValidator, + validate::{task::ValidationJobSender, TransactionValidatorError, ValidationTask}, + TransactionValidationOutcome, TransactionValidator, MAX_INIT_CODE_SIZE, TX_MAX_SIZE, }; use reth_primitives::{ constants::ETHEREUM_BLOCK_GAS_LIMIT, ChainSpec, InvalidTransactionError, EIP1559_TX_TYPE_ID, @@ -140,8 +137,6 @@ pub struct EthTransactionValidatorBuilder { /// /// Default is 1 additional_tasks: usize, - /// Toggle to determine if a local transaction should be propagated - propagate_local_transactions: bool, } impl EthTransactionValidatorBuilder { @@ -155,8 +150,6 @@ impl EthTransactionValidatorBuilder { block_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT, minimum_priority_fee: None, additional_tasks: 1, - // default to true, can potentially take this as a param in the future - propagate_local_transactions: true, } } @@ -192,23 +185,6 @@ impl EthTransactionValidatorBuilder { self.eip1559 = eip1559; self } - /// Sets toggle to propagate transactions received locally by this client (e.g - /// transactions from eth_Sendtransaction to this nodes' RPC server) - /// - /// If set to false, only transactions received by network peers (via - /// p2p) will be marked as propagated in the local transaction pool and returned on a - /// GetPooledTransactions p2p request - pub fn set_propagate_local_transactions(mut self, propagate_local_txs: bool) -> Self { - self.propagate_local_transactions = propagate_local_txs; - self - } - /// Disables propagating transactions recieved locally by this client - /// - /// For more information, check docs for set_propagate_local_transactions - pub fn no_local_transaction_propagation(mut self) -> Self { - self.propagate_local_transactions = false; - self - } /// Sets a minimum priority fee that's enforced for acceptance into the pool. pub fn with_minimum_priority_fee(mut self, minimum_priority_fee: u128) -> Self { @@ -243,7 +219,6 @@ impl EthTransactionValidatorBuilder { block_gas_limit, minimum_priority_fee, additional_tasks, - propagate_local_transactions, } = self; let inner = EthTransactionValidatorInner { @@ -254,7 +229,6 @@ impl EthTransactionValidatorBuilder { eip1559, block_gas_limit, minimum_priority_fee, - propagate_local_transactions, _marker: Default::default(), }; @@ -300,8 +274,6 @@ struct EthTransactionValidatorInner { minimum_priority_fee: Option, /// Marker for the transaction type _marker: PhantomData, - /// Toggle to determine if a local transaction should be propagated - propagate_local_transactions: bool, } // === impl EthTransactionValidatorInner === @@ -460,9 +432,7 @@ where balance: account.balance, state_nonce: account.nonce, transaction, - // by this point assume all external transactions should be propagated - propagate: matches!(origin, TransactionOrigin::External) || - self.propagate_local_transactions, + propagate: true, } } } diff --git a/crates/transaction-pool/src/validate/mod.rs b/crates/transaction-pool/src/validate/mod.rs index aabe58845cc..2e96099f935 100644 --- a/crates/transaction-pool/src/validate/mod.rs +++ b/crates/transaction-pool/src/validate/mod.rs @@ -10,7 +10,6 @@ use reth_primitives::{ }; use std::{fmt, time::Instant}; -mod constants; mod eth; mod task; @@ -20,9 +19,6 @@ pub use eth::{EthTransactionValidator, EthTransactionValidatorBuilder}; /// A spawnable task that performs transaction validation. pub use task::ValidationTask; -/// Validation constants. -pub use constants::{MAX_CODE_SIZE, MAX_INIT_CODE_SIZE, TX_MAX_SIZE, TX_SLOT_SIZE}; - /// A Result type returned after checking a transaction's validity. #[derive(Debug)] pub enum TransactionValidationOutcome { @@ -168,6 +164,14 @@ impl ValidPoolTransaction { self.transaction.cost() } + /// Returns the effective tip for this transaction. + /// + /// For EIP-1559 transactions: `max_fee_per_gas * gas_limit`. + /// For legacy transactions: `gas_price * gas_limit`. + pub fn gas_cost(&self) -> U256 { + self.transaction.gas_cost() + } + /// Returns the EIP-1559 Max base fee the caller is willing to pay. /// /// For legacy transactions this is `gas_price`. @@ -175,20 +179,6 @@ impl ValidPoolTransaction { self.transaction.max_fee_per_gas() } - /// Returns the effective tip for this transaction. - /// - /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. - /// For legacy transactions: `gas_price - base_fee`. - pub fn effective_tip_per_gas(&self, base_fee: u64) -> Option { - self.transaction.effective_tip_per_gas(base_fee) - } - - /// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and - /// otherwise returns the gas price. - pub fn priority_fee_or_price(&self) -> u128 { - self.transaction.priority_fee_or_price() - } - /// Maximum amount of gas that the transaction is allowed to consume. pub fn gas_limit(&self) -> u64 { self.transaction.gas_limit() diff --git a/crates/trie/src/updates.rs b/crates/trie/src/updates.rs index dc5c086e0d7..b60df4aa78a 100644 --- a/crates/trie/src/updates.rs +++ b/crates/trie/src/updates.rs @@ -22,7 +22,7 @@ pub enum TrieKey { } /// The operation to perform on the trie. -#[derive(PartialEq, Eq, Debug, Clone)] +#[derive(Debug, Clone)] pub enum TrieOp { /// Delete the node entry. Delete, diff --git a/examples/db-access.rs b/examples/db-access.rs index 60089dba75b..5b8aec77f4f 100644 --- a/examples/db-access.rs +++ b/examples/db-access.rs @@ -186,8 +186,8 @@ fn receipts_provider_example eyre::Result<()> { let pool = reth_transaction_pool::Pool::new( OkValidator::default(), - CoinbaseTipOrdering::default(), + GasCostOrdering::default(), Default::default(), ); diff --git a/testing/ef-tests/Cargo.toml b/testing/ef-tests/Cargo.toml index 7145273a931..d415acde44c 100644 --- a/testing/ef-tests/Cargo.toml +++ b/testing/ef-tests/Cargo.toml @@ -23,4 +23,5 @@ tokio = "1.28.1" walkdir = "2.3.3" serde = "1.0.163" serde_json.workspace = true -thiserror.workspace = true \ No newline at end of file +thiserror.workspace = true +serde_bytes = "0.11.9" \ No newline at end of file diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index 989a0dd9e7f..52da1fc0259 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -36,6 +36,20 @@ pub struct BlockchainTest { #[serde(default)] /// Engine spec. pub self_engine: SealEngine, + #[serde(rename = "_info")] + #[allow(unused)] + info: BlockchainTestInfo, +} + +#[derive(Debug, PartialEq, Eq, Deserialize)] +struct BlockchainTestInfo { + #[serde(rename = "filling-rpc-server")] + #[allow(unused)] + // One test has an invalid string in this field, which breaks our CI: + // https://github.com/ethereum/tests/blob/6c252923bdd1bd5a70f680df1214f866f76839db/GeneralStateTests/stTransactionTest/ValueOverflow.json#L5 + // By using `serde_bytes::ByteBuf`, we ignore the validation of this field as a string. + // TODO(alexey): remove when `ethereum/tests` is fixed + filling_rpc_server: serde_bytes::ByteBuf, } /// A block header in an Ethereum blockchain test. @@ -100,8 +114,6 @@ impl From
for SealedHeader { parent_hash: value.parent_hash, logs_bloom: value.bloom, withdrawals_root: value.withdrawals_root, - blob_gas_used: None, - excess_blob_gas: None, }; header.seal(value.hash) }