mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
Compare commits
4 Commits
push
...
adaptive-h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aabb9c858b | ||
|
|
d123ba89ef | ||
|
|
0cb4df9b9e | ||
|
|
c405e72f6c |
@@ -1,4 +0,0 @@
|
||||
---
|
||||
---
|
||||
|
||||
Improved documentation overview page with better structure and clarity.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
reth-trie-sparse: patch
|
||||
---
|
||||
|
||||
Fixed a bug where trie nodes could appear in both `updated_nodes` and `removed_nodes` simultaneously by removing entries from `removed_nodes` when a node is inserted as updated.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
reth-trie: patch
|
||||
---
|
||||
|
||||
Fixed a potential panic in `ProofCalculator` by clearing internal computation state (`branch_stack`, `child_stack`, `branch_path`, etc.) after errors, preventing stale state from causing `usize` underflow panics when the calculator is reused. Added a test verifying correct behavior after simulated mid-computation errors.
|
||||
11
.github/workflows/docker.yml
vendored
11
.github/workflows/docker.yml
vendored
@@ -70,27 +70,18 @@ jobs:
|
||||
# Add 'latest' tag for non-RC releases
|
||||
if [[ ! "$VERSION" =~ -rc ]]; then
|
||||
echo "ethereum_tags=${REGISTRY}/reth:${VERSION},${REGISTRY}/reth:latest" >> "$GITHUB_OUTPUT"
|
||||
{
|
||||
echo "ethereum_set<<EOF"
|
||||
echo "ethereum.tags=${REGISTRY}/reth:${VERSION}"
|
||||
echo "ethereum.tags=${REGISTRY}/reth:latest"
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "ethereum_tags=${REGISTRY}/reth:${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "ethereum_set=ethereum.tags=${REGISTRY}/reth:${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
elif [[ "${{ github.event_name }}" == "schedule" ]] || [[ "${{ inputs.build_type }}" == "nightly" ]]; then
|
||||
echo "targets=nightly" >> "$GITHUB_OUTPUT"
|
||||
echo "ethereum_tags=${REGISTRY}/reth:nightly" >> "$GITHUB_OUTPUT"
|
||||
echo "ethereum_set=ethereum.tags=${REGISTRY}/reth:nightly" >> "$GITHUB_OUTPUT"
|
||||
|
||||
else
|
||||
# git-sha build
|
||||
echo "targets=ethereum" >> "$GITHUB_OUTPUT"
|
||||
echo "ethereum_tags=${REGISTRY}/reth:${{ github.sha }}" >> "$GITHUB_OUTPUT"
|
||||
echo "ethereum_set=ethereum.tags=${REGISTRY}/reth:${{ github.sha }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Build and push images
|
||||
@@ -106,7 +97,7 @@ jobs:
|
||||
targets: ${{ steps.params.outputs.targets }}
|
||||
push: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }}
|
||||
set: |
|
||||
${{ steps.params.outputs.ethereum_set }}
|
||||
ethereum.tags=${{ steps.params.outputs.ethereum_tags }}
|
||||
|
||||
- name: Verify image architectures
|
||||
env:
|
||||
|
||||
242
Cargo.lock
generated
242
Cargo.lock
generated
@@ -3300,7 +3300,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ef-test-runner"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ef-tests",
|
||||
@@ -3308,7 +3308,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ef-tests"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -3748,7 +3748,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "example-full-contract-state"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"eyre",
|
||||
@@ -3880,7 +3880,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "exex-subscription"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"clap",
|
||||
@@ -7532,7 +7532,7 @@ checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"
|
||||
|
||||
[[package]]
|
||||
name = "reth"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-node-bindings",
|
||||
"alloy-primitives",
|
||||
@@ -7579,7 +7579,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-basic-payload-builder"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7602,7 +7602,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-bench"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7649,7 +7649,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-bench-compare"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-provider",
|
||||
@@ -7677,7 +7677,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-chain-state"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7710,7 +7710,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-chainspec"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-consensus",
|
||||
@@ -7730,7 +7730,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-cli"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-genesis",
|
||||
"clap",
|
||||
@@ -7743,7 +7743,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-cli-commands"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-consensus",
|
||||
@@ -7830,7 +7830,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-cli-runner"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"reth-tasks",
|
||||
"tokio",
|
||||
@@ -7839,7 +7839,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-cli-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -7860,7 +7860,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-codecs"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7884,7 +7884,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-codecs-derive"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -7894,7 +7894,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-config"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"eyre",
|
||||
@@ -7912,7 +7912,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-consensus"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -7924,7 +7924,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-consensus-common"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7938,7 +7938,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-consensus-debug-client"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -7963,7 +7963,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-db"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -7998,7 +7998,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-db-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-genesis",
|
||||
@@ -8029,7 +8029,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-db-common"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-genesis",
|
||||
@@ -8060,7 +8060,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-db-models"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -8076,7 +8076,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-discv4"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@@ -8102,7 +8102,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-discv5"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@@ -8127,7 +8127,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-dns-discovery"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-primitives",
|
||||
@@ -8155,7 +8155,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-downloaders"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8193,7 +8193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-e2e-test-utils"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8250,7 +8250,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ecies"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"alloy-primitives",
|
||||
@@ -8277,7 +8277,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-engine-local"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -8300,7 +8300,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-engine-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8324,7 +8324,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-engine-service"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"futures",
|
||||
@@ -8354,7 +8354,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-engine-tree"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eip7928",
|
||||
@@ -8427,7 +8427,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-engine-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-rpc-types-engine",
|
||||
@@ -8454,7 +8454,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-era"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8476,7 +8476,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-era-downloader"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"bytes",
|
||||
@@ -8494,7 +8494,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-era-utils"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -8520,7 +8520,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-errors"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"reth-consensus",
|
||||
"reth-execution-errors",
|
||||
@@ -8530,7 +8530,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-eth-wire"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-consensus",
|
||||
@@ -8568,7 +8568,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-eth-wire-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-chains",
|
||||
"alloy-consensus",
|
||||
@@ -8593,7 +8593,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-rpc-types-engine",
|
||||
"alloy-rpc-types-eth",
|
||||
@@ -8633,7 +8633,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-cli"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"eyre",
|
||||
@@ -8656,7 +8656,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-consensus"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8672,7 +8672,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-engine-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -8690,7 +8690,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-forks"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eip2124",
|
||||
"alloy-hardforks 0.4.7",
|
||||
@@ -8703,7 +8703,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-payload-builder"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8731,7 +8731,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ethereum-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8758,7 +8758,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-etl"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"rayon",
|
||||
@@ -8768,7 +8768,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-evm"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8792,7 +8792,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-evm-ethereum"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8816,7 +8816,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-execution-errors"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-evm",
|
||||
"alloy-primitives",
|
||||
@@ -8828,7 +8828,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-execution-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8848,7 +8848,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-exex"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8893,7 +8893,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-exex-test-utils"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"eyre",
|
||||
@@ -8924,7 +8924,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-exex-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -8941,7 +8941,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-fs-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -8950,7 +8950,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-invalid-block-hooks"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -8983,7 +8983,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-ipc"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
@@ -9005,7 +9005,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-libmdbx"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"byteorder",
|
||||
@@ -9023,7 +9023,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-mdbx-sys"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
@@ -9031,7 +9031,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-metrics"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"metrics",
|
||||
@@ -9042,7 +9042,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-net-banlist"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"ipnet",
|
||||
@@ -9050,7 +9050,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-net-nat"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"if-addrs",
|
||||
@@ -9064,7 +9064,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-network"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9126,7 +9126,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-network-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -9150,7 +9150,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-network-p2p"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9172,7 +9172,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-network-peers"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@@ -9189,7 +9189,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-network-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eip2124",
|
||||
"humantime-serde",
|
||||
@@ -9202,7 +9202,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-nippy-jar"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode 1.3.3",
|
||||
@@ -9220,7 +9220,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-rpc-types-engine",
|
||||
"eyre",
|
||||
@@ -9243,7 +9243,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-builder"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9315,7 +9315,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-core"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9371,7 +9371,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-ethereum"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-contract",
|
||||
@@ -9431,7 +9431,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-ethstats"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -9454,7 +9454,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-events"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9477,7 +9477,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-metrics"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"eyre",
|
||||
@@ -9506,7 +9506,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-node-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"reth-chainspec",
|
||||
"reth-db-api",
|
||||
@@ -9517,7 +9517,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-payload-builder"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -9537,7 +9537,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-payload-builder-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"pin-project",
|
||||
"reth-payload-primitives",
|
||||
@@ -9548,7 +9548,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-payload-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9571,7 +9571,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-payload-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -9580,7 +9580,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-payload-validator"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-rpc-types-engine",
|
||||
@@ -9589,7 +9589,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-primitives"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9611,7 +9611,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-primitives-traits"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9649,7 +9649,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-provider"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9699,7 +9699,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-prune"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -9732,11 +9732,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-prune-db"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
|
||||
[[package]]
|
||||
name = "reth-prune-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"arbitrary",
|
||||
@@ -9756,7 +9756,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-revm"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -9770,7 +9770,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-dyn-abi",
|
||||
@@ -9850,7 +9850,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eip7928",
|
||||
"alloy-eips",
|
||||
@@ -9880,7 +9880,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-api-testing-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -9899,7 +9899,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-builder"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-network",
|
||||
@@ -9955,7 +9955,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-convert"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-evm",
|
||||
@@ -9979,7 +9979,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-e2e-tests"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-genesis",
|
||||
"alloy-rpc-types-engine",
|
||||
@@ -9999,7 +9999,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-engine-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -10035,7 +10035,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-eth-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-dyn-abi",
|
||||
@@ -10078,7 +10078,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-eth-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10126,7 +10126,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-layer"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-rpc-types-engine",
|
||||
"http",
|
||||
@@ -10143,7 +10143,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-rpc-server-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -10158,7 +10158,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-stages"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10220,7 +10220,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-stages-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -10253,7 +10253,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-stages-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"arbitrary",
|
||||
@@ -10269,7 +10269,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-static-file"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"assert_matches",
|
||||
@@ -10292,7 +10292,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-static-file-types"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"clap",
|
||||
@@ -10310,7 +10310,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-storage-api"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10333,7 +10333,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-storage-errors"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -10349,7 +10349,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-storage-rpc-provider"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10378,7 +10378,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-tasks"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"dyn-clone",
|
||||
@@ -10395,7 +10395,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-testing-utils"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10411,7 +10411,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-tokio-util"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -10420,7 +10420,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-tracing"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"eyre",
|
||||
@@ -10438,7 +10438,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-tracing-otlp"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"eyre",
|
||||
@@ -10455,7 +10455,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-transaction-pool"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10506,7 +10506,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-trie"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
@@ -10540,7 +10540,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-trie-common"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-genesis",
|
||||
@@ -10573,7 +10573,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-trie-db"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-primitives",
|
||||
@@ -10604,7 +10604,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-trie-parallel"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@@ -10634,7 +10634,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-trie-sparse"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
@@ -10665,7 +10665,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reth-zstd-compressors"
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
dependencies = [
|
||||
"zstd",
|
||||
]
|
||||
|
||||
51
Cargo.toml
51
Cargo.toml
@@ -1,5 +1,5 @@
|
||||
[workspace.package]
|
||||
version = "1.11.3"
|
||||
version = "1.10.2"
|
||||
edition = "2024"
|
||||
rust-version = "1.88"
|
||||
license = "MIT OR Apache-2.0"
|
||||
@@ -449,18 +449,14 @@ revm-inspectors = "0.34.2"
|
||||
|
||||
# eth
|
||||
alloy-dyn-abi = "1.5.6"
|
||||
alloy-primitives = { version = "1.5.6", default-features = false, features = [
|
||||
"map-foldhash",
|
||||
] }
|
||||
alloy-primitives = { version = "1.5.6", default-features = false, features = ["map-foldhash"] }
|
||||
alloy-sol-types = { version = "1.5.6", default-features = false }
|
||||
|
||||
alloy-chains = { version = "0.2.5", default-features = false }
|
||||
alloy-eip2124 = { version = "0.2.0", default-features = false }
|
||||
alloy-eip7928 = { version = "0.3.0", default-features = false }
|
||||
alloy-evm = { version = "0.27.2", default-features = false }
|
||||
alloy-rlp = { version = "0.3.13", default-features = false, features = [
|
||||
"core-net",
|
||||
] }
|
||||
alloy-rlp = { version = "0.3.13", default-features = false, features = ["core-net"] }
|
||||
alloy-trie = { version = "0.9.4", default-features = false }
|
||||
|
||||
alloy-hardforks = "0.4.5"
|
||||
@@ -472,15 +468,10 @@ alloy-genesis = { version = "1.6.3", default-features = false }
|
||||
alloy-json-rpc = { version = "1.6.3", default-features = false }
|
||||
alloy-network = { version = "1.6.3", default-features = false }
|
||||
alloy-network-primitives = { version = "1.6.3", default-features = false }
|
||||
alloy-provider = { version = "1.6.3", features = [
|
||||
"reqwest",
|
||||
"debug-api",
|
||||
], default-features = false }
|
||||
alloy-provider = { version = "1.6.3", features = ["reqwest", "debug-api"], default-features = false }
|
||||
alloy-pubsub = { version = "1.6.3", default-features = false }
|
||||
alloy-rpc-client = { version = "1.6.3", default-features = false }
|
||||
alloy-rpc-types = { version = "1.6.3", features = [
|
||||
"eth",
|
||||
], default-features = false }
|
||||
alloy-rpc-types = { version = "1.6.3", features = ["eth"], default-features = false }
|
||||
alloy-rpc-types-admin = { version = "1.6.3", default-features = false }
|
||||
alloy-rpc-types-anvil = { version = "1.6.3", default-features = false }
|
||||
alloy-rpc-types-beacon = { version = "1.6.3", default-features = false }
|
||||
@@ -494,9 +485,7 @@ alloy-serde = { version = "1.6.3", default-features = false }
|
||||
alloy-signer = { version = "1.6.3", default-features = false }
|
||||
alloy-signer-local = { version = "1.6.3", default-features = false }
|
||||
alloy-transport = { version = "1.6.3" }
|
||||
alloy-transport-http = { version = "1.6.3", features = [
|
||||
"reqwest-rustls-tls",
|
||||
], default-features = false }
|
||||
alloy-transport-http = { version = "1.6.3", features = ["reqwest-rustls-tls"], default-features = false }
|
||||
alloy-transport-ipc = { version = "1.6.3", default-features = false }
|
||||
alloy-transport-ws = { version = "1.6.3", default-features = false }
|
||||
|
||||
@@ -515,10 +504,7 @@ either = { version = "1.15.0", default-features = false }
|
||||
arrayvec = { version = "0.7.6", default-features = false }
|
||||
aquamarine = "0.6"
|
||||
auto_impl = "1"
|
||||
backon = { version = "1.2", default-features = false, features = [
|
||||
"std-blocking-sleep",
|
||||
"tokio-sleep",
|
||||
] }
|
||||
backon = { version = "1.2", default-features = false, features = ["std-blocking-sleep", "tokio-sleep"] }
|
||||
bincode = "1.3"
|
||||
bitflags = "2.4"
|
||||
boyer-moore-magiclen = "0.2.16"
|
||||
@@ -540,13 +526,9 @@ itertools = { version = "0.14", default-features = false }
|
||||
linked_hash_set = "0.1"
|
||||
lz4 = "1.28.1"
|
||||
modular-bitfield = "0.13.1"
|
||||
notify = { version = "8.0.0", default-features = false, features = [
|
||||
"macos_fsevent",
|
||||
] }
|
||||
notify = { version = "8.0.0", default-features = false, features = ["macos_fsevent"] }
|
||||
nybbles = { version = "0.4.8", default-features = false }
|
||||
once_cell = { version = "1.19", default-features = false, features = [
|
||||
"critical-section",
|
||||
] }
|
||||
once_cell = { version = "1.19", default-features = false, features = ["critical-section"] }
|
||||
parking_lot = "0.12"
|
||||
paste = "1.0"
|
||||
rand = "0.9"
|
||||
@@ -565,9 +547,7 @@ strum_macros = "0.27"
|
||||
syn = "2.0"
|
||||
thiserror = { version = "2.0.0", default-features = false }
|
||||
tar = "0.4.44"
|
||||
tracing = { version = "0.1.0", default-features = false, features = [
|
||||
"attributes",
|
||||
] }
|
||||
tracing = { version = "0.1.0", default-features = false, features = ["attributes"] }
|
||||
tracing-appender = "0.2"
|
||||
url = { version = "2.3", default-features = false }
|
||||
zstd = "0.13"
|
||||
@@ -605,11 +585,7 @@ futures-util = { version = "0.3", default-features = false }
|
||||
hyper = "1.3"
|
||||
hyper-util = "0.1.5"
|
||||
pin-project = "1.0.12"
|
||||
reqwest = { version = "0.12", default-features = false, features = [
|
||||
"rustls-tls",
|
||||
"rustls-tls-native-roots",
|
||||
"stream",
|
||||
] }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "rustls-tls-native-roots", "stream"] }
|
||||
tracing-futures = "0.2"
|
||||
tower = "0.5"
|
||||
tower-http = "0.6"
|
||||
@@ -634,10 +610,7 @@ proptest-arbitrary-interop = "0.1.0"
|
||||
# crypto
|
||||
enr = { version = "0.13", default-features = false }
|
||||
k256 = { version = "0.13", default-features = false, features = ["ecdsa"] }
|
||||
secp256k1 = { version = "0.30", default-features = false, features = [
|
||||
"global-context",
|
||||
"recovery",
|
||||
] }
|
||||
secp256k1 = { version = "0.30", default-features = false, features = ["global-context", "recovery"] }
|
||||
# rand 8 for secp256k1
|
||||
rand_08 = { package = "rand", version = "0.8" }
|
||||
|
||||
|
||||
@@ -312,11 +312,6 @@ impl DeferredTrieData {
|
||||
/// Given that invariant, circular wait dependencies are impossible.
|
||||
#[instrument(level = "debug", target = "engine::tree::deferred_trie", skip_all)]
|
||||
pub fn wait_cloned(&self) -> ComputedTrieData {
|
||||
#[cfg(feature = "rayon")]
|
||||
debug_assert!(
|
||||
rayon::current_thread_index().is_none(),
|
||||
"wait_cloned must not be called from a rayon worker thread"
|
||||
);
|
||||
let mut state = self.state.lock();
|
||||
match &mut *state {
|
||||
// If the deferred trie data is ready, return the cached result.
|
||||
|
||||
@@ -19,7 +19,7 @@ use reth_node_builder::{
|
||||
Node, NodeComponents, NodeComponentsBuilder, NodeTypes, NodeTypesWithDBAdapter,
|
||||
};
|
||||
use reth_node_core::{
|
||||
args::{DatabaseArgs, DatadirArgs, StaticFilesArgs, StorageArgs},
|
||||
args::{DatabaseArgs, DatadirArgs, RocksDbArgs, StaticFilesArgs, StorageArgs},
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
};
|
||||
use reth_provider::{
|
||||
@@ -67,23 +67,62 @@ pub struct EnvironmentArgs<C: ChainSpecParser> {
|
||||
#[command(flatten)]
|
||||
pub static_files: StaticFilesArgs,
|
||||
|
||||
/// All `RocksDB` related arguments
|
||||
#[command(flatten)]
|
||||
pub rocksdb: RocksDbArgs,
|
||||
|
||||
/// Storage mode configuration (v2 vs v1/legacy)
|
||||
#[command(flatten)]
|
||||
pub storage: StorageArgs,
|
||||
}
|
||||
|
||||
impl<C: ChainSpecParser> EnvironmentArgs<C> {
|
||||
/// Returns the effective storage settings derived from `--storage.v2`.
|
||||
/// Returns the effective storage settings derived from `--storage.v2`, static-file, and
|
||||
/// `RocksDB` CLI args.
|
||||
///
|
||||
/// The base storage mode is determined by `--storage.v2`:
|
||||
/// - When `--storage.v2` is set: uses [`StorageSettings::v2()`] defaults
|
||||
/// - Otherwise: uses [`StorageSettings::base()`] defaults
|
||||
/// - Otherwise: uses [`StorageSettings::v1()`] defaults
|
||||
///
|
||||
/// Individual `--static-files.*` and `--rocksdb.*` flags override the base when explicitly set.
|
||||
pub fn storage_settings(&self) -> StorageSettings {
|
||||
if self.storage.v2 {
|
||||
StorageSettings::v2()
|
||||
} else {
|
||||
StorageSettings::base()
|
||||
let mut s = if self.storage.v2 { StorageSettings::v2() } else { StorageSettings::base() };
|
||||
|
||||
// Apply static files overrides (only when explicitly set)
|
||||
if let Some(v) = self.static_files.receipts {
|
||||
s = s.with_receipts_in_static_files(v);
|
||||
}
|
||||
if let Some(v) = self.static_files.transaction_senders {
|
||||
s = s.with_transaction_senders_in_static_files(v);
|
||||
}
|
||||
if let Some(v) = self.static_files.account_changesets {
|
||||
s = s.with_account_changesets_in_static_files(v);
|
||||
}
|
||||
if let Some(v) = self.static_files.storage_changesets {
|
||||
s = s.with_storage_changesets_in_static_files(v);
|
||||
}
|
||||
|
||||
// Apply rocksdb overrides
|
||||
// --rocksdb.all sets all rocksdb flags to true
|
||||
if self.rocksdb.all {
|
||||
s = s
|
||||
.with_transaction_hash_numbers_in_rocksdb(true)
|
||||
.with_storages_history_in_rocksdb(true)
|
||||
.with_account_history_in_rocksdb(true);
|
||||
}
|
||||
|
||||
// Individual rocksdb flags override --rocksdb.all when explicitly set
|
||||
if let Some(v) = self.rocksdb.tx_hash {
|
||||
s = s.with_transaction_hash_numbers_in_rocksdb(v);
|
||||
}
|
||||
if let Some(v) = self.rocksdb.storages_history {
|
||||
s = s.with_storages_history_in_rocksdb(v);
|
||||
}
|
||||
if let Some(v) = self.rocksdb.account_history {
|
||||
s = s.with_account_history_in_rocksdb(v);
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
/// Initializes environment according to [`AccessRights`] and returns an instance of
|
||||
|
||||
@@ -23,7 +23,7 @@ impl Command {
|
||||
/// Execute `db account-storage` command
|
||||
pub fn execute<N: NodeTypesWithDB>(self, tool: &DbTool<N>) -> eyre::Result<()> {
|
||||
let address = self.address;
|
||||
let use_hashed_state = tool.provider_factory.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed_state = tool.provider_factory.cached_storage_settings().use_hashed_state;
|
||||
|
||||
let (slot_count, storage_size) = if use_hashed_state {
|
||||
let hashed_address = keccak256(address);
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use clap::Parser;
|
||||
use reth_db::mdbx::{self, ffi};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Copies the MDBX database to a new location.
|
||||
///
|
||||
/// Equivalent to the standalone `mdbx_copy` tool but bundled into reth.
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct Command {
|
||||
/// Destination path for the database copy.
|
||||
dest: PathBuf,
|
||||
|
||||
/// Compact the database while copying (reclaims free space).
|
||||
#[arg(short, long)]
|
||||
compact: bool,
|
||||
|
||||
/// Force dynamic size for the destination database.
|
||||
#[arg(short = 'd', long)]
|
||||
force_dynamic_size: bool,
|
||||
|
||||
/// Throttle to avoid MVCC pressure on writers.
|
||||
#[arg(short = 'p', long)]
|
||||
throttle_mvcc: bool,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
/// Execute `db copy` command
|
||||
pub fn execute(self, db: &mdbx::DatabaseEnv) -> eyre::Result<()> {
|
||||
let mut flags: ffi::MDBX_copy_flags_t = ffi::MDBX_CP_DEFAULTS;
|
||||
if self.compact {
|
||||
flags |= ffi::MDBX_CP_COMPACT;
|
||||
}
|
||||
if self.force_dynamic_size {
|
||||
flags |= ffi::MDBX_CP_FORCE_DYNAMIC_SIZE;
|
||||
}
|
||||
if self.throttle_mvcc {
|
||||
flags |= ffi::MDBX_CP_THROTTLE_MVCC;
|
||||
}
|
||||
|
||||
let dest = self
|
||||
.dest
|
||||
.to_str()
|
||||
.ok_or_else(|| eyre::eyre!("destination path must be valid UTF-8"))?;
|
||||
let dest_cstr = std::ffi::CString::new(dest)?;
|
||||
|
||||
println!("Copying database to {} ...", self.dest.display());
|
||||
|
||||
let rc = db.with_raw_env_ptr(|env_ptr| unsafe {
|
||||
ffi::mdbx_env_copy(env_ptr, dest_cstr.as_ptr(), flags)
|
||||
});
|
||||
|
||||
if rc != 0 {
|
||||
eyre::bail!("mdbx_env_copy failed with error code {rc}: {}", unsafe {
|
||||
std::ffi::CStr::from_ptr(ffi::mdbx_strerror(rc)).to_string_lossy()
|
||||
});
|
||||
}
|
||||
|
||||
println!("Done.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ use std::{
|
||||
mod account_storage;
|
||||
mod checksum;
|
||||
mod clear;
|
||||
mod copy;
|
||||
mod diff;
|
||||
mod get;
|
||||
mod list;
|
||||
@@ -43,8 +42,6 @@ pub enum Subcommands {
|
||||
List(list::Command),
|
||||
/// Calculates the content checksum of a table or static file segment
|
||||
Checksum(checksum::Command),
|
||||
/// Copies the MDBX database to a new location (bundled mdbx_copy)
|
||||
Copy(copy::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
|
||||
@@ -127,11 +124,6 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C>
|
||||
command.execute(&tool)?;
|
||||
});
|
||||
}
|
||||
Subcommands::Copy(command) => {
|
||||
db_exec!(self.env, tool, N, AccessRights::RO, {
|
||||
command.execute(tool.provider_factory.db_ref())?;
|
||||
});
|
||||
}
|
||||
Subcommands::Diff(command) => {
|
||||
db_exec!(self.env, tool, N, AccessRights::RO, {
|
||||
command.execute(&tool)?;
|
||||
|
||||
@@ -39,12 +39,50 @@ enum Subcommands {
|
||||
#[derive(Debug, Clone, Copy, Subcommand)]
|
||||
#[clap(rename_all = "snake_case")]
|
||||
pub enum SetCommand {
|
||||
/// Enable or disable v2 storage layout
|
||||
/// Store receipts in static files instead of the database
|
||||
Receipts {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store transaction senders in static files instead of the database
|
||||
TransactionSenders {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store account changesets in static files instead of the database
|
||||
AccountChangesets {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store storage history in rocksdb instead of MDBX
|
||||
StoragesHistory {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store transaction hash to number mapping in rocksdb instead of MDBX
|
||||
TransactionHashNumbers {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store account history in rocksdb instead of MDBX
|
||||
AccountHistory {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Store storage changesets in static files instead of the database
|
||||
StorageChangesets {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
/// Use hashed state tables (HashedAccounts/HashedStorages) as canonical state
|
||||
///
|
||||
/// When enabled, uses static files for receipts/senders/changesets and RocksDB for
|
||||
/// history indices and transaction hashes. When disabled, uses v1/legacy layout (everything in
|
||||
/// MDBX).
|
||||
V2 {
|
||||
/// When enabled, execution writes directly to hashed tables, eliminating need for
|
||||
/// separate hashing stages. State reads come from hashed tables.
|
||||
///
|
||||
/// WARNING: Changing this setting in either direction requires re-syncing the database.
|
||||
/// Enabling on an existing plain-state database leaves hashed tables empty.
|
||||
/// Disabling on an existing hashed-state database leaves plain tables empty.
|
||||
UseHashedState {
|
||||
#[clap(action(ArgAction::Set))]
|
||||
value: bool,
|
||||
},
|
||||
@@ -87,18 +125,87 @@ impl Command {
|
||||
println!("No storage settings found, creating new settings.");
|
||||
}
|
||||
|
||||
let mut settings @ StorageSettings { storage_v2: _ } =
|
||||
settings.unwrap_or_else(StorageSettings::v1);
|
||||
let mut settings @ StorageSettings {
|
||||
receipts_in_static_files: _,
|
||||
transaction_senders_in_static_files: _,
|
||||
storages_history_in_rocksdb: _,
|
||||
transaction_hash_numbers_in_rocksdb: _,
|
||||
account_history_in_rocksdb: _,
|
||||
account_changesets_in_static_files: _,
|
||||
storage_changesets_in_static_files: _,
|
||||
use_hashed_state: _,
|
||||
} = settings.unwrap_or_else(StorageSettings::v1);
|
||||
|
||||
// Update the setting based on the key
|
||||
match cmd {
|
||||
SetCommand::V2 { value } => {
|
||||
if settings.storage_v2 == value {
|
||||
println!("storage_v2 is already set to {}", value);
|
||||
SetCommand::Receipts { value } => {
|
||||
if settings.receipts_in_static_files == value {
|
||||
println!("receipts_in_static_files is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.storage_v2 = value;
|
||||
println!("Set storage_v2 = {}", value);
|
||||
settings.receipts_in_static_files = value;
|
||||
println!("Set receipts_in_static_files = {}", value);
|
||||
}
|
||||
SetCommand::TransactionSenders { value } => {
|
||||
if settings.transaction_senders_in_static_files == value {
|
||||
println!("transaction_senders_in_static_files is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.transaction_senders_in_static_files = value;
|
||||
println!("Set transaction_senders_in_static_files = {}", value);
|
||||
}
|
||||
SetCommand::AccountChangesets { value } => {
|
||||
if settings.account_changesets_in_static_files == value {
|
||||
println!("account_changesets_in_static_files is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.account_changesets_in_static_files = value;
|
||||
println!("Set account_changesets_in_static_files = {}", value);
|
||||
}
|
||||
SetCommand::StoragesHistory { value } => {
|
||||
if settings.storages_history_in_rocksdb == value {
|
||||
println!("storages_history_in_rocksdb is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.storages_history_in_rocksdb = value;
|
||||
println!("Set storages_history_in_rocksdb = {}", value);
|
||||
}
|
||||
SetCommand::TransactionHashNumbers { value } => {
|
||||
if settings.transaction_hash_numbers_in_rocksdb == value {
|
||||
println!("transaction_hash_numbers_in_rocksdb is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.transaction_hash_numbers_in_rocksdb = value;
|
||||
println!("Set transaction_hash_numbers_in_rocksdb = {}", value);
|
||||
}
|
||||
SetCommand::AccountHistory { value } => {
|
||||
if settings.account_history_in_rocksdb == value {
|
||||
println!("account_history_in_rocksdb is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.account_history_in_rocksdb = value;
|
||||
println!("Set account_history_in_rocksdb = {}", value);
|
||||
}
|
||||
SetCommand::StorageChangesets { value } => {
|
||||
if settings.storage_changesets_in_static_files == value {
|
||||
println!("storage_changesets_in_static_files is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
settings.storage_changesets_in_static_files = value;
|
||||
println!("Set storage_changesets_in_static_files = {}", value);
|
||||
}
|
||||
SetCommand::UseHashedState { value } => {
|
||||
if settings.use_hashed_state == value {
|
||||
println!("use_hashed_state is already set to {}", value);
|
||||
return Ok(());
|
||||
}
|
||||
if settings.use_hashed_state && !value {
|
||||
println!("WARNING: Disabling use_hashed_state on an existing hashed-state database requires a full resync.");
|
||||
} else {
|
||||
println!("WARNING: Enabling use_hashed_state on an existing plain-state database requires a full resync.");
|
||||
}
|
||||
settings.use_hashed_state = value;
|
||||
println!("Set use_hashed_state = {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ impl Command {
|
||||
address: Address,
|
||||
limit: usize,
|
||||
) -> eyre::Result<()> {
|
||||
let use_hashed_state = tool.provider_factory.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed_state = tool.provider_factory.cached_storage_settings().use_hashed_state;
|
||||
|
||||
let entries = tool.provider_factory.db_ref().view(|tx| {
|
||||
let (account, walker_entries) = if use_hashed_state {
|
||||
@@ -145,7 +145,7 @@ impl Command {
|
||||
|
||||
// Check storage settings to determine where history is stored
|
||||
let storage_settings = tool.provider_factory.cached_storage_settings();
|
||||
let history_in_rocksdb = storage_settings.storage_v2;
|
||||
let history_in_rocksdb = storage_settings.storages_history_in_rocksdb;
|
||||
|
||||
// For historical queries, enumerate keys from history indices only
|
||||
// (not PlainStorageState, which reflects current state)
|
||||
|
||||
@@ -37,14 +37,6 @@ pub struct DownloadDefaults {
|
||||
pub available_snapshots: Vec<Cow<'static, str>>,
|
||||
/// Default base URL for snapshots
|
||||
pub default_base_url: Cow<'static, str>,
|
||||
/// Default base URL for chain-aware snapshots.
|
||||
///
|
||||
/// When set, the chain ID is appended to form the full URL: `{base_url}/{chain_id}`.
|
||||
/// For example, given a base URL of `https://snapshots.example.com` and chain ID `1`,
|
||||
/// the resulting URL would be `https://snapshots.example.com/1`.
|
||||
///
|
||||
/// Falls back to [`default_base_url`](Self::default_base_url) when `None`.
|
||||
pub default_chain_aware_base_url: Option<Cow<'static, str>>,
|
||||
/// Optional custom long help text that overrides the generated help
|
||||
pub long_help: Option<String>,
|
||||
}
|
||||
@@ -68,7 +60,6 @@ impl DownloadDefaults {
|
||||
Cow::Borrowed("https://publicnode.com/snapshots (full nodes & testnets)"),
|
||||
],
|
||||
default_base_url: Cow::Borrowed(MERKLE_BASE_URL),
|
||||
default_chain_aware_base_url: None,
|
||||
long_help: None,
|
||||
}
|
||||
}
|
||||
@@ -93,11 +84,9 @@ impl DownloadDefaults {
|
||||
}
|
||||
|
||||
help.push_str(
|
||||
"\nIf no URL is provided, the latest archive snapshot for the selected chain\nwill be proposed for download from ",
|
||||
);
|
||||
help.push_str(
|
||||
self.default_chain_aware_base_url.as_deref().unwrap_or(&self.default_base_url),
|
||||
"\nIf no URL is provided, the latest mainnet archive snapshot\nwill be proposed for download from ",
|
||||
);
|
||||
help.push_str(self.default_base_url.as_ref());
|
||||
help.push_str(
|
||||
".\n\nLocal file:// URLs are also supported for extracting snapshots from disk.",
|
||||
);
|
||||
@@ -122,12 +111,6 @@ impl DownloadDefaults {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the default chain-aware base URL.
|
||||
pub fn with_chain_aware_base_url(mut self, url: impl Into<Cow<'static, str>>) -> Self {
|
||||
self.default_chain_aware_base_url = Some(url.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set custom long help text, overriding the generated help
|
||||
pub fn with_long_help(mut self, help: impl Into<String>) -> Self {
|
||||
self.long_help = Some(help.into());
|
||||
@@ -159,7 +142,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> DownloadCo
|
||||
let url = match self.url {
|
||||
Some(url) => url,
|
||||
None => {
|
||||
let url = get_latest_snapshot_url(self.env.chain.chain().id()).await?;
|
||||
let url = get_latest_snapshot_url().await?;
|
||||
info!(target: "reth::cli", "Using default snapshot URL: {}", url);
|
||||
url
|
||||
}
|
||||
@@ -526,12 +509,8 @@ async fn stream_and_extract(url: &str, target_dir: &Path) -> Result<()> {
|
||||
}
|
||||
|
||||
// Builds default URL for latest mainnet archive snapshot using configured defaults
|
||||
async fn get_latest_snapshot_url(chain_id: u64) -> Result<String> {
|
||||
let defaults = DownloadDefaults::get_global();
|
||||
let base_url = match &defaults.default_chain_aware_base_url {
|
||||
Some(url) => format!("{url}/{chain_id}"),
|
||||
None => defaults.default_base_url.to_string(),
|
||||
};
|
||||
async fn get_latest_snapshot_url() -> Result<String> {
|
||||
let base_url = &DownloadDefaults::get_global().default_base_url;
|
||||
let latest_url = format!("{base_url}/latest.txt");
|
||||
let filename = Client::new()
|
||||
.get(latest_url)
|
||||
|
||||
@@ -10,8 +10,8 @@ use reth_node_builder::NodeBuilder;
|
||||
use reth_node_core::{
|
||||
args::{
|
||||
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, EraArgs, MetricArgs,
|
||||
NetworkArgs, PayloadBuilderArgs, PruningArgs, RpcServerArgs, StaticFilesArgs, StorageArgs,
|
||||
TxPoolArgs,
|
||||
NetworkArgs, PayloadBuilderArgs, PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs,
|
||||
StorageArgs, TxPoolArgs,
|
||||
},
|
||||
node_config::NodeConfig,
|
||||
version,
|
||||
@@ -103,6 +103,10 @@ pub struct NodeCommand<C: ChainSpecParser, Ext: clap::Args + fmt::Debug = NoArgs
|
||||
#[command(flatten)]
|
||||
pub pruning: PruningArgs,
|
||||
|
||||
/// All `RocksDB` table routing arguments
|
||||
#[command(flatten)]
|
||||
pub rocksdb: RocksDbArgs,
|
||||
|
||||
/// Engine cli arguments
|
||||
#[command(flatten, next_help_heading = "Engine")]
|
||||
pub engine: EngineArgs,
|
||||
@@ -171,6 +175,7 @@ where
|
||||
db,
|
||||
dev,
|
||||
pruning,
|
||||
rocksdb,
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
@@ -178,6 +183,9 @@ where
|
||||
ext,
|
||||
} = self;
|
||||
|
||||
// Validate RocksDB arguments
|
||||
rocksdb.validate()?;
|
||||
|
||||
// set up node config
|
||||
let mut node_config = NodeConfig {
|
||||
datadir,
|
||||
@@ -193,6 +201,7 @@ where
|
||||
db,
|
||||
dev,
|
||||
pruning,
|
||||
rocksdb,
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
|
||||
@@ -133,7 +133,7 @@ impl<C: ChainSpecParser> Command<C> {
|
||||
reset_stage_checkpoint(tx, StageId::SenderRecovery)?;
|
||||
}
|
||||
StageEnum::Execution => {
|
||||
if provider_rw.cached_storage_settings().use_hashed_state() {
|
||||
if provider_rw.cached_storage_settings().use_hashed_state {
|
||||
tx.clear::<tables::HashedAccounts>()?;
|
||||
tx.clear::<tables::HashedStorages>()?;
|
||||
reset_stage_checkpoint(tx, StageId::AccountHashing)?;
|
||||
@@ -187,7 +187,7 @@ impl<C: ChainSpecParser> Command<C> {
|
||||
let settings = provider_rw.cached_storage_settings();
|
||||
let rocksdb = tool.provider_factory.rocksdb_provider();
|
||||
|
||||
if settings.storage_v2 {
|
||||
if settings.account_history_in_rocksdb {
|
||||
rocksdb.clear::<tables::AccountsHistory>()?;
|
||||
} else {
|
||||
tx.clear::<tables::AccountsHistory>()?;
|
||||
@@ -204,7 +204,7 @@ impl<C: ChainSpecParser> Command<C> {
|
||||
let settings = provider_rw.cached_storage_settings();
|
||||
let rocksdb = tool.provider_factory.rocksdb_provider();
|
||||
|
||||
if settings.storage_v2 {
|
||||
if settings.storages_history_in_rocksdb {
|
||||
rocksdb.clear::<tables::StoragesHistory>()?;
|
||||
} else {
|
||||
tx.clear::<tables::StoragesHistory>()?;
|
||||
@@ -218,7 +218,7 @@ impl<C: ChainSpecParser> Command<C> {
|
||||
)?;
|
||||
}
|
||||
StageEnum::TxLookup => {
|
||||
if provider_rw.cached_storage_settings().storage_v2 {
|
||||
if provider_rw.cached_storage_settings().transaction_hash_numbers_in_rocksdb {
|
||||
tool.provider_factory
|
||||
.rocksdb_provider()
|
||||
.clear::<tables::TransactionHashNumbers>()?;
|
||||
|
||||
@@ -10,6 +10,7 @@ use jsonrpsee::core::client::ClientT;
|
||||
use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET};
|
||||
use reth_db::tables;
|
||||
use reth_e2e_test_utils::{transaction::TransactionTestContext, wallet, E2ETestSetupBuilder};
|
||||
use reth_node_core::args::RocksDbArgs;
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
use reth_payload_builder::EthPayloadBuilderAttributes;
|
||||
use reth_provider::RocksDBProviderFactory;
|
||||
@@ -95,6 +96,22 @@ fn test_attributes_generator(timestamp: u64) -> EthPayloadBuilderAttributes {
|
||||
EthPayloadBuilderAttributes::new(B256::ZERO, attributes)
|
||||
}
|
||||
|
||||
/// Verifies that `RocksDB` CLI defaults are `None` (deferred to storage mode).
|
||||
#[test]
|
||||
fn test_rocksdb_defaults_are_none() {
|
||||
let args = RocksDbArgs::default();
|
||||
|
||||
assert!(args.tx_hash.is_none(), "tx_hash default should be None (deferred to --storage.v2)");
|
||||
assert!(
|
||||
args.storages_history.is_none(),
|
||||
"storages_history default should be None (deferred to --storage.v2)"
|
||||
);
|
||||
assert!(
|
||||
args.account_history.is_none(),
|
||||
"account_history default should be None (deferred to --storage.v2)"
|
||||
);
|
||||
}
|
||||
|
||||
/// Smoke test: node boots with `RocksDB` routing enabled.
|
||||
#[tokio::test]
|
||||
async fn test_rocksdb_node_startup() -> Result<()> {
|
||||
@@ -460,7 +477,7 @@ async fn test_rocksdb_pending_tx_not_in_storage() -> Result<()> {
|
||||
///
|
||||
/// This test exercises `unwind_trie_state_from` which previously failed with
|
||||
/// `UnsortedInput` errors because it read changesets directly from MDBX tables
|
||||
/// instead of using storage-aware methods that check `is_v2()`.
|
||||
/// instead of using storage-aware methods that check `storage_changesets_in_static_files`.
|
||||
#[tokio::test]
|
||||
async fn test_rocksdb_reorg_unwind() -> Result<()> {
|
||||
reth_tracing::init_test_tracing();
|
||||
|
||||
@@ -94,7 +94,7 @@ where
|
||||
if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum };
|
||||
|
||||
let downloader = BasicBlockDownloader::new(client, consensus.clone());
|
||||
let use_hashed_state = provider.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed_state = provider.cached_storage_settings().use_hashed_state;
|
||||
|
||||
let persistence_handle =
|
||||
PersistenceHandle::<N::Primitives>::spawn_service(provider, pruner, sync_metrics_tx);
|
||||
|
||||
@@ -845,10 +845,8 @@ impl SavedCache {
|
||||
self.caches.update_metrics(&self.metrics);
|
||||
}
|
||||
|
||||
/// Clears all caches, resetting them to empty state,
|
||||
/// and updates the hash of the block this cache belongs to.
|
||||
pub(crate) fn clear_with_hash(&mut self, hash: B256) {
|
||||
self.hash = hash;
|
||||
/// Clears all caches, resetting them to empty state.
|
||||
pub(crate) fn clear(&self) {
|
||||
self.caches.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1411,7 +1411,7 @@ where
|
||||
// Spawn a background task to trigger computation so it's ready when the next payload
|
||||
// arrives.
|
||||
if let Some(overlay) = self.state.tree_state.prepare_canonical_overlay() {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
rayon::spawn(move || {
|
||||
let _ = overlay.get();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ use std::{
|
||||
mpsc::{self, channel},
|
||||
Arc,
|
||||
},
|
||||
time::{Duration, Instant},
|
||||
time::Instant,
|
||||
};
|
||||
use tracing::{debug, debug_span, instrument, warn, Span};
|
||||
|
||||
@@ -444,8 +444,8 @@ where
|
||||
let _ = execute_tx.send(tx);
|
||||
next_for_execution += 1;
|
||||
|
||||
while let Some(entry) = queue.first_entry()
|
||||
&& *entry.key() == next_for_execution
|
||||
while let Some(entry) = queue.first_entry() &&
|
||||
*entry.key() == next_for_execution
|
||||
{
|
||||
let _ = execute_tx.send(entry.remove());
|
||||
next_for_execution += 1;
|
||||
@@ -926,7 +926,7 @@ impl PayloadExecutionCache {
|
||||
#[instrument(level = "debug", target = "engine::tree::payload_processor", skip(self))]
|
||||
pub(crate) fn get_cache_for(&self, parent_hash: B256) -> Option<SavedCache> {
|
||||
let start = Instant::now();
|
||||
let mut cache = self.inner.write();
|
||||
let cache = self.inner.read();
|
||||
|
||||
let elapsed = start.elapsed();
|
||||
self.metrics.execution_cache_wait_duration.record(elapsed.as_secs_f64());
|
||||
@@ -934,7 +934,7 @@ impl PayloadExecutionCache {
|
||||
warn!(blocked_for=?elapsed, "Blocked waiting for execution cache mutex");
|
||||
}
|
||||
|
||||
if let Some(c) = cache.as_mut() {
|
||||
if let Some(c) = cache.as_ref() {
|
||||
let cached_hash = c.executed_block_hash();
|
||||
// Check that the cache hash matches the parent hash of the current block. It won't
|
||||
// match in case it's a fork block.
|
||||
@@ -955,13 +955,13 @@ impl PayloadExecutionCache {
|
||||
);
|
||||
|
||||
if available {
|
||||
// If the has is available (no other threads are using it), but has a mismatching
|
||||
// parent hash, we can just clear it and keep using without re-creating from
|
||||
// scratch.
|
||||
if !hash_matches {
|
||||
// Fork block: clear and update the hash on the ORIGINAL before cloning.
|
||||
// This prevents the canonical chain from matching on the stale hash
|
||||
// and picking up polluted data if the fork block fails.
|
||||
c.clear_with_hash(parent_hash);
|
||||
c.clear();
|
||||
}
|
||||
return Some(c.clone());
|
||||
return Some(c.clone())
|
||||
} else if hash_matches {
|
||||
self.metrics.execution_cache_in_use.increment(1);
|
||||
}
|
||||
@@ -972,25 +972,10 @@ impl PayloadExecutionCache {
|
||||
None
|
||||
}
|
||||
|
||||
/// Waits until the execution cache becomes available for use.
|
||||
///
|
||||
/// This acquires a write lock to ensure exclusive access, then immediately releases it.
|
||||
/// This is useful for synchronization before starting payload processing.
|
||||
///
|
||||
/// Returns the time spent waiting for the lock.
|
||||
pub fn wait_for_availability(&self) -> Duration {
|
||||
let start = Instant::now();
|
||||
// Acquire write lock to wait for any current holders to finish
|
||||
let _guard = self.inner.write();
|
||||
let elapsed = start.elapsed();
|
||||
if elapsed.as_millis() > 5 {
|
||||
debug!(
|
||||
target: "engine::tree::payload_processor",
|
||||
blocked_for=?elapsed,
|
||||
"Waited for execution cache to become available"
|
||||
);
|
||||
}
|
||||
elapsed
|
||||
/// Clears the tracked cache
|
||||
#[expect(unused)]
|
||||
pub(crate) fn clear(&self) {
|
||||
self.inner.write().take();
|
||||
}
|
||||
|
||||
/// Updates the cache with a closure that has exclusive access to the guard.
|
||||
@@ -1143,18 +1128,10 @@ mod tests {
|
||||
|
||||
execution_cache.update_with_guard(|slot| *slot = Some(make_saved_cache(hash)));
|
||||
|
||||
// When the parent hash doesn't match (fork block), the cache is cleared,
|
||||
// hash updated on the original, and clone returned for reuse
|
||||
// When the parent hash doesn't match, the cache is cleared and returned for reuse
|
||||
let different_hash = B256::from([4u8; 32]);
|
||||
let cache = execution_cache.get_cache_for(different_hash);
|
||||
assert!(cache.is_some(), "cache should be returned for reuse after clearing");
|
||||
|
||||
drop(cache);
|
||||
|
||||
// The stored cache now has the fork block's parent hash.
|
||||
// Canonical chain looking for original hash sees a mismatch → clears and reuses.
|
||||
let original = execution_cache.get_cache_for(hash);
|
||||
assert!(original.is_some(), "canonical chain gets cache back via mismatch+clear");
|
||||
assert!(cache.is_some(), "cache should be returned for reuse after clearing")
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1378,61 +1355,4 @@ mod tests {
|
||||
"State root mismatch: task={root_from_task}, base={root_from_regular}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Tests the full prewarm lifecycle for a fork block:
|
||||
///
|
||||
/// 1. Cache is at canonical block 4.
|
||||
/// 2. Fork block (parent = block 2) checks out the cache via `get_cache_for`, simulating what
|
||||
/// `PrewarmCacheTask` does when it receives a `SavedCache`.
|
||||
/// 3. Prewarm populates the shared cache with fork-specific state.
|
||||
/// 4. While the prewarm clone is alive, the cache is unavailable (`usage_guard` > 1).
|
||||
/// 5. Prewarm drops without calling `save_cache` (fork block was invalid).
|
||||
/// 6. Canonical block 5 (parent = block 4) must get a cache with correct hash and no stale fork
|
||||
/// data.
|
||||
#[test]
|
||||
fn fork_prewarm_dropped_without_save_does_not_corrupt_cache() {
|
||||
let execution_cache = PayloadExecutionCache::default();
|
||||
|
||||
// Canonical chain at block 4.
|
||||
let block4_hash = B256::from([4u8; 32]);
|
||||
execution_cache.update_with_guard(|slot| *slot = Some(make_saved_cache(block4_hash)));
|
||||
|
||||
// Fork block arrives with parent = block 2. Prewarm task checks out the cache.
|
||||
// This simulates PrewarmCacheTask receiving a SavedCache clone from get_cache_for.
|
||||
let fork_parent = B256::from([2u8; 32]);
|
||||
let prewarm_cache = execution_cache.get_cache_for(fork_parent);
|
||||
assert!(prewarm_cache.is_some(), "prewarm should obtain cache for fork block");
|
||||
let prewarm_cache = prewarm_cache.unwrap();
|
||||
assert_eq!(prewarm_cache.executed_block_hash(), fork_parent);
|
||||
|
||||
// Prewarm populates cache with fork-specific state (ancestor data for block 2).
|
||||
// Since ExecutionCache uses Arc<Inner>, this data is shared with the stored original.
|
||||
let fork_addr = Address::from([0xBB; 20]);
|
||||
let fork_key = B256::from([0xCC; 32]);
|
||||
prewarm_cache.cache().insert_storage(fork_addr, fork_key, Some(U256::from(999)));
|
||||
|
||||
// While prewarm holds the clone, the usage_guard count > 1 → cache is in use.
|
||||
let during_prewarm = execution_cache.get_cache_for(block4_hash);
|
||||
assert!(
|
||||
during_prewarm.is_none(),
|
||||
"cache must be unavailable while prewarm holds a reference"
|
||||
);
|
||||
|
||||
// Fork block fails — prewarm task drops without calling save_cache/update_with_guard.
|
||||
drop(prewarm_cache);
|
||||
|
||||
// Canonical block 5 arrives (parent = block 4).
|
||||
// Stored hash = fork_parent (our fix), so get_cache_for sees a mismatch,
|
||||
// clears the stale fork data, and returns a cache with hash = block4_hash.
|
||||
let block5_cache = execution_cache.get_cache_for(block4_hash);
|
||||
assert!(
|
||||
block5_cache.is_some(),
|
||||
"canonical chain must get cache after fork prewarm is dropped"
|
||||
);
|
||||
assert_eq!(
|
||||
block5_cache.as_ref().unwrap().executed_block_hash(),
|
||||
block4_hash,
|
||||
"cache must carry the canonical parent hash, not the fork parent"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,9 +416,7 @@ where
|
||||
let update = match message {
|
||||
Ok(m) => m,
|
||||
Err(_) => {
|
||||
return Err(ParallelStateRootError::Other(
|
||||
"updates channel disconnected before state root calculation".to_string(),
|
||||
))
|
||||
break
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ impl TestHarness {
|
||||
EngineApiKind::Ethereum,
|
||||
evm_config,
|
||||
changeset_cache,
|
||||
provider.cached_storage_settings().use_hashed_state(),
|
||||
provider.cached_storage_settings().use_hashed_state,
|
||||
);
|
||||
|
||||
let block_builder = TestBlockBuilder::default().with_chain_spec((*chain_spec).clone());
|
||||
|
||||
@@ -208,9 +208,9 @@ impl<T> ExecutionOutcome<T> {
|
||||
}
|
||||
|
||||
/// Returns [`HashedPostState`] for this execution outcome.
|
||||
/// See [`HashedPostState::from_bundle_state`] for more info.
|
||||
/// See [`HashedPostState::from_bundle_state_adaptive`] for more info.
|
||||
pub fn hash_state_slow<KH: KeyHasher>(&self) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KH>(&self.bundle.state)
|
||||
HashedPostState::from_bundle_state_adaptive::<KH>(&self.bundle.state)
|
||||
}
|
||||
|
||||
/// Transform block number to the index of block.
|
||||
|
||||
@@ -25,7 +25,7 @@ use crate::{
|
||||
listener::ConnectionListener,
|
||||
message::{NewBlockMessage, PeerMessage},
|
||||
metrics::{
|
||||
BackedOffPeersMetrics, ClosedSessionsMetrics, DirectionalDisconnectMetrics, NetworkMetrics,
|
||||
BackedOffPeersMetrics, ClosedSessionsMetrics, DisconnectMetrics, NetworkMetrics,
|
||||
PendingSessionFailureMetrics, NETWORK_POOL_TRANSACTIONS_SCOPE,
|
||||
},
|
||||
network::{NetworkHandle, NetworkHandleMessage},
|
||||
@@ -140,8 +140,8 @@ pub struct NetworkManager<N: NetworkPrimitives = EthNetworkPrimitives> {
|
||||
num_active_peers: Arc<AtomicUsize>,
|
||||
/// Metrics for the Network
|
||||
metrics: NetworkMetrics,
|
||||
/// Disconnect metrics for the Network, split by connection direction.
|
||||
disconnect_metrics: DirectionalDisconnectMetrics,
|
||||
/// Disconnect metrics for the Network
|
||||
disconnect_metrics: DisconnectMetrics,
|
||||
/// Closed sessions metrics, split by direction.
|
||||
closed_sessions_metrics: ClosedSessionsMetrics,
|
||||
/// Pending session failure metrics, split by direction.
|
||||
@@ -864,9 +864,6 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
|
||||
"Session disconnected"
|
||||
);
|
||||
|
||||
// Capture direction before state is reset to Idle
|
||||
let is_inbound = self.swarm.state().peers().is_inbound_peer(&peer_id);
|
||||
|
||||
let reason = if let Some(ref err) = error {
|
||||
// If the connection was closed due to an error, we report
|
||||
// the peer
|
||||
@@ -890,11 +887,7 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
|
||||
self.update_active_connection_metrics();
|
||||
|
||||
if let Some(reason) = reason {
|
||||
if is_inbound {
|
||||
self.disconnect_metrics.increment_inbound(reason);
|
||||
} else {
|
||||
self.disconnect_metrics.increment_outbound(reason);
|
||||
}
|
||||
self.disconnect_metrics.increment(reason);
|
||||
}
|
||||
self.metrics
|
||||
.backed_off_peers
|
||||
@@ -917,7 +910,7 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
|
||||
.on_incoming_pending_session_dropped(remote_addr, err);
|
||||
self.pending_session_failure_metrics.inbound.increment(1);
|
||||
if let Some(reason) = err.as_disconnected() {
|
||||
self.disconnect_metrics.increment_inbound(reason);
|
||||
self.disconnect_metrics.increment(reason);
|
||||
}
|
||||
} else {
|
||||
self.swarm
|
||||
@@ -950,7 +943,7 @@ impl<N: NetworkPrimitives> NetworkManager<N> {
|
||||
BackoffReason::from_disconnect(err.as_disconnected()),
|
||||
);
|
||||
if let Some(reason) = err.as_disconnected() {
|
||||
self.disconnect_metrics.increment_outbound(reason);
|
||||
self.disconnect_metrics.increment(reason);
|
||||
}
|
||||
} else {
|
||||
self.swarm
|
||||
|
||||
@@ -301,34 +301,6 @@ macro_rules! duration_metered_exec {
|
||||
}};
|
||||
}
|
||||
|
||||
/// Direction-aware wrapper for disconnect metrics.
|
||||
///
|
||||
/// Tracks disconnect reasons for inbound and outbound connections separately, in addition to
|
||||
/// the combined (legacy) counters.
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct DirectionalDisconnectMetrics {
|
||||
/// Combined disconnect metrics (all directions).
|
||||
pub(crate) total: DisconnectMetrics,
|
||||
/// Disconnect metrics for inbound connections only.
|
||||
pub(crate) inbound: InboundDisconnectMetrics,
|
||||
/// Disconnect metrics for outbound connections only.
|
||||
pub(crate) outbound: OutboundDisconnectMetrics,
|
||||
}
|
||||
|
||||
impl DirectionalDisconnectMetrics {
|
||||
/// Increments disconnect counters for an inbound connection.
|
||||
pub(crate) fn increment_inbound(&self, reason: DisconnectReason) {
|
||||
self.total.increment(reason);
|
||||
self.inbound.increment(reason);
|
||||
}
|
||||
|
||||
/// Increments disconnect counters for an outbound connection.
|
||||
pub(crate) fn increment_outbound(&self, reason: DisconnectReason) {
|
||||
self.total.increment(reason);
|
||||
self.outbound.increment(reason);
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics for Disconnection types
|
||||
///
|
||||
/// These are just counters, and ideally we would implement these metrics on a peer-by-peer basis,
|
||||
@@ -398,144 +370,6 @@ impl DisconnectMetrics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Disconnect metrics scoped to inbound connections only.
|
||||
///
|
||||
/// These counters track disconnect reasons exclusively for sessions that were initiated by
|
||||
/// remote peers connecting to this node. This helps operators distinguish between being rejected
|
||||
/// by remote peers (outbound) vs rejecting incoming peers (inbound).
|
||||
#[derive(Metrics)]
|
||||
#[metrics(scope = "network.inbound")]
|
||||
pub struct InboundDisconnectMetrics {
|
||||
/// Number of inbound peer disconnects due to `DisconnectRequested` (0x00)
|
||||
pub(crate) disconnect_requested: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `TcpSubsystemError` (0x01)
|
||||
pub(crate) tcp_subsystem_error: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `ProtocolBreach` (0x02)
|
||||
pub(crate) protocol_breach: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `UselessPeer` (0x03)
|
||||
pub(crate) useless_peer: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `TooManyPeers` (0x04)
|
||||
pub(crate) too_many_peers: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `AlreadyConnected` (0x05)
|
||||
pub(crate) already_connected: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `IncompatibleP2PProtocolVersion` (0x06)
|
||||
pub(crate) incompatible: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `NullNodeIdentity` (0x07)
|
||||
pub(crate) null_node_identity: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `ClientQuitting` (0x08)
|
||||
pub(crate) client_quitting: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `UnexpectedHandshakeIdentity` (0x09)
|
||||
pub(crate) unexpected_identity: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `ConnectedToSelf` (0x0a)
|
||||
pub(crate) connected_to_self: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `PingTimeout` (0x0b)
|
||||
pub(crate) ping_timeout: Counter,
|
||||
|
||||
/// Number of inbound peer disconnects due to `SubprotocolSpecific` (0x10)
|
||||
pub(crate) subprotocol_specific: Counter,
|
||||
}
|
||||
|
||||
impl InboundDisconnectMetrics {
|
||||
/// Increments the proper counter for the given disconnect reason
|
||||
pub(crate) fn increment(&self, reason: DisconnectReason) {
|
||||
match reason {
|
||||
DisconnectReason::DisconnectRequested => self.disconnect_requested.increment(1),
|
||||
DisconnectReason::TcpSubsystemError => self.tcp_subsystem_error.increment(1),
|
||||
DisconnectReason::ProtocolBreach => self.protocol_breach.increment(1),
|
||||
DisconnectReason::UselessPeer => self.useless_peer.increment(1),
|
||||
DisconnectReason::TooManyPeers => self.too_many_peers.increment(1),
|
||||
DisconnectReason::AlreadyConnected => self.already_connected.increment(1),
|
||||
DisconnectReason::IncompatibleP2PProtocolVersion => self.incompatible.increment(1),
|
||||
DisconnectReason::NullNodeIdentity => self.null_node_identity.increment(1),
|
||||
DisconnectReason::ClientQuitting => self.client_quitting.increment(1),
|
||||
DisconnectReason::UnexpectedHandshakeIdentity => self.unexpected_identity.increment(1),
|
||||
DisconnectReason::ConnectedToSelf => self.connected_to_self.increment(1),
|
||||
DisconnectReason::PingTimeout => self.ping_timeout.increment(1),
|
||||
DisconnectReason::SubprotocolSpecific => self.subprotocol_specific.increment(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Disconnect metrics scoped to outbound connections only.
|
||||
///
|
||||
/// These counters track disconnect reasons exclusively for sessions that this node initiated
|
||||
/// by dialing out to remote peers. A high `too_many_peers` count here indicates remote peers
|
||||
/// are rejecting our connection attempts because they are full.
|
||||
#[derive(Metrics)]
|
||||
#[metrics(scope = "network.outbound")]
|
||||
pub struct OutboundDisconnectMetrics {
|
||||
/// Number of outbound peer disconnects due to `DisconnectRequested` (0x00)
|
||||
pub(crate) disconnect_requested: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `TcpSubsystemError` (0x01)
|
||||
pub(crate) tcp_subsystem_error: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `ProtocolBreach` (0x02)
|
||||
pub(crate) protocol_breach: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `UselessPeer` (0x03)
|
||||
pub(crate) useless_peer: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `TooManyPeers` (0x04)
|
||||
pub(crate) too_many_peers: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `AlreadyConnected` (0x05)
|
||||
pub(crate) already_connected: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `IncompatibleP2PProtocolVersion` (0x06)
|
||||
pub(crate) incompatible: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `NullNodeIdentity` (0x07)
|
||||
pub(crate) null_node_identity: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `ClientQuitting` (0x08)
|
||||
pub(crate) client_quitting: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `UnexpectedHandshakeIdentity` (0x09)
|
||||
pub(crate) unexpected_identity: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `ConnectedToSelf` (0x0a)
|
||||
pub(crate) connected_to_self: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `PingTimeout` (0x0b)
|
||||
pub(crate) ping_timeout: Counter,
|
||||
|
||||
/// Number of outbound peer disconnects due to `SubprotocolSpecific` (0x10)
|
||||
pub(crate) subprotocol_specific: Counter,
|
||||
}
|
||||
|
||||
impl OutboundDisconnectMetrics {
|
||||
/// Increments the proper counter for the given disconnect reason
|
||||
pub(crate) fn increment(&self, reason: DisconnectReason) {
|
||||
match reason {
|
||||
DisconnectReason::DisconnectRequested => self.disconnect_requested.increment(1),
|
||||
DisconnectReason::TcpSubsystemError => self.tcp_subsystem_error.increment(1),
|
||||
DisconnectReason::ProtocolBreach => self.protocol_breach.increment(1),
|
||||
DisconnectReason::UselessPeer => self.useless_peer.increment(1),
|
||||
DisconnectReason::TooManyPeers => self.too_many_peers.increment(1),
|
||||
DisconnectReason::AlreadyConnected => self.already_connected.increment(1),
|
||||
DisconnectReason::IncompatibleP2PProtocolVersion => self.incompatible.increment(1),
|
||||
DisconnectReason::NullNodeIdentity => self.null_node_identity.increment(1),
|
||||
DisconnectReason::ClientQuitting => self.client_quitting.increment(1),
|
||||
DisconnectReason::UnexpectedHandshakeIdentity => self.unexpected_identity.increment(1),
|
||||
DisconnectReason::ConnectedToSelf => self.connected_to_self.increment(1),
|
||||
DisconnectReason::PingTimeout => self.ping_timeout.increment(1),
|
||||
DisconnectReason::SubprotocolSpecific => self.subprotocol_specific.increment(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics for the `EthRequestHandler`
|
||||
#[derive(Metrics)]
|
||||
#[metrics(scope = "network")]
|
||||
|
||||
@@ -218,13 +218,6 @@ impl PeersManager {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns `true` if the given peer is connected via an inbound session.
|
||||
pub(crate) fn is_inbound_peer(&self, peer_id: &PeerId) -> bool {
|
||||
self.peers.get(peer_id).is_some_and(|p| {
|
||||
matches!(p.state, PeerConnectionState::In | PeerConnectionState::DisconnectingIn)
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns an iterator over all peer ids for peers with the given kind
|
||||
pub(crate) fn peers_by_kind(&self, kind: PeerKind) -> impl Iterator<Item = PeerId> + '_ {
|
||||
self.peers.iter().filter_map(move |(peer_id, peer)| (peer.kind == kind).then_some(*peer_id))
|
||||
|
||||
@@ -76,6 +76,10 @@ pub use era::{DefaultEraHost, EraArgs, EraSourceArgs};
|
||||
mod static_files;
|
||||
pub use static_files::{StaticFilesArgs, MINIMAL_BLOCKS_PER_FILE};
|
||||
|
||||
/// `RocksDbArgs` for configuring RocksDB table routing.
|
||||
mod rocksdb;
|
||||
pub use rocksdb::{RocksDbArgs, RocksDbArgsError};
|
||||
|
||||
/// `StorageArgs` for configuring storage settings.
|
||||
mod storage;
|
||||
pub use storage::StorageArgs;
|
||||
|
||||
160
crates/node/core/src/args/rocksdb.rs
Normal file
160
crates/node/core/src/args/rocksdb.rs
Normal file
@@ -0,0 +1,160 @@
|
||||
//! clap [Args](clap::Args) for `RocksDB` table routing configuration
|
||||
|
||||
use clap::{ArgAction, Args};
|
||||
|
||||
/// Parameters for `RocksDB` table routing configuration.
|
||||
///
|
||||
/// These flags control which database tables are stored in `RocksDB` instead of MDBX.
|
||||
/// All flags are genesis-initialization-only: changing them after genesis requires a re-sync.
|
||||
///
|
||||
/// When `--storage.v2` is used, the defaults for these flags change to enable `RocksDB` routing.
|
||||
/// Individual flags can still override those defaults when explicitly set.
|
||||
#[derive(Debug, Args, PartialEq, Eq, Clone, Copy, Default)]
|
||||
#[command(next_help_heading = "RocksDB")]
|
||||
pub struct RocksDbArgs {
|
||||
/// Route all supported tables to `RocksDB` instead of MDBX.
|
||||
///
|
||||
/// This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables.
|
||||
/// Cannot be combined with individual flags set to false.
|
||||
#[arg(long = "rocksdb.all", action = ArgAction::SetTrue)]
|
||||
pub all: bool,
|
||||
|
||||
/// Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
///
|
||||
/// This is a genesis-initialization-only flag: changing it after genesis requires a re-sync.
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "rocksdb.tx-hash", action = ArgAction::Set)]
|
||||
pub tx_hash: Option<bool>,
|
||||
|
||||
/// Route storages history tables to `RocksDB` instead of MDBX.
|
||||
///
|
||||
/// This is a genesis-initialization-only flag: changing it after genesis requires a re-sync.
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "rocksdb.storages-history", action = ArgAction::Set)]
|
||||
pub storages_history: Option<bool>,
|
||||
|
||||
/// Route account history tables to `RocksDB` instead of MDBX.
|
||||
///
|
||||
/// This is a genesis-initialization-only flag: changing it after genesis requires a re-sync.
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "rocksdb.account-history", action = ArgAction::Set)]
|
||||
pub account_history: Option<bool>,
|
||||
}
|
||||
|
||||
impl RocksDbArgs {
|
||||
/// Validates the `RocksDB` arguments.
|
||||
///
|
||||
/// Returns an error if `--rocksdb.all` is used with any individual flag explicitly set to
|
||||
/// `false`.
|
||||
pub const fn validate(&self) -> Result<(), RocksDbArgsError> {
|
||||
if self.all {
|
||||
if matches!(self.tx_hash, Some(false)) {
|
||||
return Err(RocksDbArgsError::ConflictingFlags("tx-hash"));
|
||||
}
|
||||
if matches!(self.storages_history, Some(false)) {
|
||||
return Err(RocksDbArgsError::ConflictingFlags("storages-history"));
|
||||
}
|
||||
if matches!(self.account_history, Some(false)) {
|
||||
return Err(RocksDbArgsError::ConflictingFlags("account-history"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type for `RocksDB` argument validation.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
|
||||
pub enum RocksDbArgsError {
|
||||
/// `--rocksdb.all` cannot be combined with an individual flag set to false.
|
||||
#[error("--rocksdb.all cannot be combined with --rocksdb.{0}=false")]
|
||||
ConflictingFlags(&'static str),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Parser)]
|
||||
struct CommandParser<T: Args> {
|
||||
#[command(flatten)]
|
||||
args: T,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_rocksdb_args() {
|
||||
let args = CommandParser::<RocksDbArgs>::parse_from(["reth"]).args;
|
||||
assert_eq!(args, RocksDbArgs::default());
|
||||
assert!(!args.all);
|
||||
assert!(args.tx_hash.is_none());
|
||||
assert!(args.storages_history.is_none());
|
||||
assert!(args.account_history.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_all_flag() {
|
||||
let args = CommandParser::<RocksDbArgs>::parse_from(["reth", "--rocksdb.all"]).args;
|
||||
assert!(args.all);
|
||||
assert!(args.tx_hash.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_individual_flags() {
|
||||
let args = CommandParser::<RocksDbArgs>::parse_from([
|
||||
"reth",
|
||||
"--rocksdb.tx-hash=true",
|
||||
"--rocksdb.storages-history=false",
|
||||
"--rocksdb.account-history=true",
|
||||
])
|
||||
.args;
|
||||
assert!(!args.all);
|
||||
assert_eq!(args.tx_hash, Some(true));
|
||||
assert_eq!(args.storages_history, Some(false));
|
||||
assert_eq!(args.account_history, Some(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_all_with_none_ok() {
|
||||
let args =
|
||||
RocksDbArgs { all: true, tx_hash: None, storages_history: None, account_history: None };
|
||||
assert!(args.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_all_with_true_ok() {
|
||||
let args = RocksDbArgs {
|
||||
all: true,
|
||||
tx_hash: Some(true),
|
||||
storages_history: Some(true),
|
||||
account_history: Some(true),
|
||||
};
|
||||
assert!(args.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_all_with_false_errors() {
|
||||
let args = RocksDbArgs {
|
||||
all: true,
|
||||
tx_hash: Some(false),
|
||||
storages_history: None,
|
||||
account_history: None,
|
||||
};
|
||||
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("tx-hash")));
|
||||
|
||||
let args = RocksDbArgs {
|
||||
all: true,
|
||||
tx_hash: None,
|
||||
storages_history: Some(false),
|
||||
account_history: None,
|
||||
};
|
||||
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("storages-history")));
|
||||
|
||||
let args = RocksDbArgs {
|
||||
all: true,
|
||||
tx_hash: None,
|
||||
storages_history: None,
|
||||
account_history: Some(false),
|
||||
};
|
||||
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("account-history")));
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,9 @@ use reth_config::config::{BlocksPerFileConfig, StaticFilesConfig};
|
||||
pub const MINIMAL_BLOCKS_PER_FILE: u64 = 10000;
|
||||
|
||||
/// Parameters for static files configuration
|
||||
///
|
||||
/// When `--storage.v2` is used, the defaults for the storage flags change to enable static file
|
||||
/// storage. Individual flags can still override those defaults when explicitly set.
|
||||
#[derive(Debug, Args, PartialEq, Eq, Clone, Copy, Default)]
|
||||
#[command(next_help_heading = "Static Files")]
|
||||
pub struct StaticFilesArgs {
|
||||
@@ -35,6 +38,53 @@ pub struct StaticFilesArgs {
|
||||
/// Number of blocks per file for the storage changesets segment.
|
||||
#[arg(long = "static-files.blocks-per-file.storage-change-sets")]
|
||||
pub blocks_per_file_storage_change_sets: Option<u64>,
|
||||
|
||||
/// Store receipts in static files instead of the database.
|
||||
///
|
||||
/// When enabled, receipts will be written to static files on disk instead of the database.
|
||||
///
|
||||
/// Note: This setting can only be configured at genesis initialization. Once
|
||||
/// the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
///
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "static-files.receipts", action = clap::ArgAction::Set)]
|
||||
pub receipts: Option<bool>,
|
||||
|
||||
/// Store transaction senders in static files instead of the database.
|
||||
///
|
||||
/// When enabled, transaction senders will be written to static files on disk instead of the
|
||||
/// database.
|
||||
///
|
||||
/// Note: This setting can only be configured at genesis initialization. Once
|
||||
/// the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
///
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "static-files.transaction-senders", action = clap::ArgAction::Set)]
|
||||
pub transaction_senders: Option<bool>,
|
||||
|
||||
/// Store account changesets in static files.
|
||||
///
|
||||
/// When enabled, account changesets will be written to static files on disk instead of the
|
||||
/// database.
|
||||
///
|
||||
/// Note: This setting can only be configured at genesis initialization. Once
|
||||
/// the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
///
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "static-files.account-change-sets", action = clap::ArgAction::Set)]
|
||||
pub account_changesets: Option<bool>,
|
||||
|
||||
/// Store storage changesets in static files.
|
||||
///
|
||||
/// When enabled, storage changesets will be written to static files on disk instead of the
|
||||
/// database.
|
||||
///
|
||||
/// Note: This setting can only be configured at genesis initialization. Once
|
||||
/// the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
///
|
||||
/// Defaults to the base storage mode (v1: false, v2: true).
|
||||
#[arg(long = "static-files.storage-change-sets", action = clap::ArgAction::Set)]
|
||||
pub storage_changesets: Option<bool>,
|
||||
}
|
||||
|
||||
impl StaticFilesArgs {
|
||||
|
||||
@@ -25,6 +25,16 @@ pub struct StorageArgs {
|
||||
/// flags.
|
||||
#[arg(long = "storage.v2", action = ArgAction::SetTrue)]
|
||||
pub v2: bool,
|
||||
|
||||
/// Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state
|
||||
/// representation instead of plain state tables.
|
||||
///
|
||||
/// When enabled, execution writes directly to hashed tables, eliminating the need for
|
||||
/// separate hashing stages. This should only be enabled for new databases.
|
||||
///
|
||||
/// WARNING: Changing this setting on an existing database requires a full resync.
|
||||
#[arg(long = "storage.use-hashed-state", default_value_t = false)]
|
||||
pub use_hashed_state: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::{
|
||||
args::{
|
||||
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, NetworkArgs, PayloadBuilderArgs,
|
||||
PruningArgs, RpcServerArgs, StaticFilesArgs, StorageArgs, TxPoolArgs,
|
||||
PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs, StorageArgs, TxPoolArgs,
|
||||
},
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
utils::get_single_header,
|
||||
@@ -152,6 +152,9 @@ pub struct NodeConfig<ChainSpec> {
|
||||
/// All static files related arguments
|
||||
pub static_files: StaticFilesArgs,
|
||||
|
||||
/// All `RocksDB` table routing arguments
|
||||
pub rocksdb: RocksDbArgs,
|
||||
|
||||
/// All storage related arguments with --storage prefix
|
||||
pub storage: StorageArgs,
|
||||
}
|
||||
@@ -185,6 +188,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine: EngineArgs::default(),
|
||||
era: EraArgs::default(),
|
||||
static_files: StaticFilesArgs::default(),
|
||||
rocksdb: RocksDbArgs::default(),
|
||||
storage: StorageArgs::default(),
|
||||
}
|
||||
}
|
||||
@@ -260,6 +264,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
rocksdb,
|
||||
storage,
|
||||
..
|
||||
} = self;
|
||||
@@ -280,6 +285,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
rocksdb,
|
||||
storage,
|
||||
}
|
||||
}
|
||||
@@ -363,17 +369,49 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
self.pruning.prune_config(&self.chain)
|
||||
}
|
||||
|
||||
/// Returns the effective storage settings derived from `--storage.v2`.
|
||||
/// Returns the effective storage settings derived from `--storage.v2`, static-file, and
|
||||
/// `RocksDB` CLI args.
|
||||
///
|
||||
/// The base storage mode is determined by `--storage.v2`:
|
||||
/// - When `--storage.v2` is set: uses [`StorageSettings::v2()`] defaults
|
||||
/// - Otherwise: uses [`StorageSettings::base()`] defaults
|
||||
/// - Otherwise: uses [`StorageSettings::v1()`] defaults
|
||||
///
|
||||
/// Individual `--static-files.*` and `--rocksdb.*` flags override the base when explicitly set.
|
||||
pub const fn storage_settings(&self) -> StorageSettings {
|
||||
if self.storage.v2 {
|
||||
StorageSettings::v2()
|
||||
} else {
|
||||
StorageSettings::base()
|
||||
let mut s = if self.storage.v2 { StorageSettings::v2() } else { StorageSettings::base() };
|
||||
|
||||
// Apply static files overrides (only when explicitly set)
|
||||
s = s
|
||||
.with_receipts_in_static_files_opt(self.static_files.receipts)
|
||||
.with_transaction_senders_in_static_files_opt(self.static_files.transaction_senders)
|
||||
.with_account_changesets_in_static_files_opt(self.static_files.account_changesets)
|
||||
.with_storage_changesets_in_static_files_opt(self.static_files.storage_changesets);
|
||||
|
||||
// Apply rocksdb overrides
|
||||
// --rocksdb.all sets all rocksdb flags to true
|
||||
if self.rocksdb.all {
|
||||
s = s
|
||||
.with_transaction_hash_numbers_in_rocksdb(true)
|
||||
.with_storages_history_in_rocksdb(true)
|
||||
.with_account_history_in_rocksdb(true);
|
||||
}
|
||||
|
||||
// Individual rocksdb flags override --rocksdb.all when explicitly set
|
||||
s = s
|
||||
.with_transaction_hash_numbers_in_rocksdb_opt(self.rocksdb.tx_hash)
|
||||
.with_storages_history_in_rocksdb_opt(self.rocksdb.storages_history)
|
||||
.with_account_history_in_rocksdb_opt(self.rocksdb.account_history);
|
||||
|
||||
s = s.with_use_hashed_state(self.storage.use_hashed_state);
|
||||
|
||||
if s.use_hashed_state {
|
||||
s = s.with_storage_changesets_in_static_files(true);
|
||||
}
|
||||
if s.storage_changesets_in_static_files {
|
||||
s = s.with_use_hashed_state(true);
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
/// Returns the max block that the node should run to, looking it up from the network if
|
||||
@@ -570,6 +608,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine: self.engine,
|
||||
era: self.era,
|
||||
static_files: self.static_files,
|
||||
rocksdb: self.rocksdb,
|
||||
storage: self.storage,
|
||||
}
|
||||
}
|
||||
@@ -612,6 +651,7 @@ impl<ChainSpec> Clone for NodeConfig<ChainSpec> {
|
||||
engine: self.engine.clone(),
|
||||
era: self.era.clone(),
|
||||
static_files: self.static_files,
|
||||
rocksdb: self.rocksdb,
|
||||
storage: self.storage,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ where
|
||||
|
||||
// Check where account history indices are stored
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_history_in_rocksdb {
|
||||
return self.prune_rocksdb(provider, input, range, range_end);
|
||||
}
|
||||
|
||||
@@ -405,7 +405,9 @@ mod tests {
|
||||
let segment = AccountHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_account_changesets_in_static_files(false),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
limiter.increment_deleted_entries_count_by(result.pruned);
|
||||
|
||||
@@ -506,11 +508,7 @@ mod tests {
|
||||
test_prune(1400, 3, (PruneProgress::Finished, 804));
|
||||
}
|
||||
|
||||
/// Tests the `prune_static_files` code path. On unix with rocksdb feature, v2 storage
|
||||
/// routes to `prune_rocksdb` instead, so this test only runs without rocksdb (the
|
||||
/// `prune_rocksdb_path` test covers that configuration).
|
||||
#[test]
|
||||
#[cfg(not(all(unix, feature = "rocksdb")))]
|
||||
fn prune_static_file() {
|
||||
let db = TestStageDB::default();
|
||||
let mut rng = generators::rng();
|
||||
@@ -566,7 +564,9 @@ mod tests {
|
||||
let segment = AccountHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v2());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_account_changesets_in_static_files(true),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
limiter.increment_deleted_entries_count_by(result.pruned);
|
||||
|
||||
@@ -714,7 +714,11 @@ mod tests {
|
||||
PruneInput { previous_checkpoint: None, to_block, limiter: PruneLimiter::default() };
|
||||
let segment = AccountHistory::new(prune_mode);
|
||||
|
||||
db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::default()
|
||||
.with_account_changesets_in_static_files(true)
|
||||
.with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
@@ -828,7 +832,9 @@ mod tests {
|
||||
let segment = AccountHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_account_changesets_in_static_files(false),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
|
||||
// Should report that there's more data
|
||||
@@ -886,7 +892,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let provider2 = db.factory.database_provider_rw().unwrap();
|
||||
provider2.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider2.set_storage_settings_cache(
|
||||
StorageSettings::default().with_account_changesets_in_static_files(false),
|
||||
);
|
||||
let result2 = segment.prune(&provider2, input2).unwrap();
|
||||
|
||||
assert!(result2.progress.is_finished(), "Second run should complete");
|
||||
|
||||
@@ -76,7 +76,7 @@ where
|
||||
|
||||
// Check where storage history indices are stored
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storages_history_in_rocksdb {
|
||||
return self.prune_rocksdb(provider, input, range, range_end);
|
||||
}
|
||||
|
||||
@@ -413,7 +413,9 @@ mod tests {
|
||||
let segment = StorageHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_storage_changesets_in_static_files(false),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
limiter.increment_deleted_entries_count_by(result.pruned);
|
||||
|
||||
@@ -518,11 +520,7 @@ mod tests {
|
||||
test_prune(1200, 3, (PruneProgress::Finished, 202));
|
||||
}
|
||||
|
||||
/// Tests the `prune_static_files` code path. On unix with rocksdb feature, v2 storage
|
||||
/// routes to `prune_rocksdb` instead, so this test only runs without rocksdb (the
|
||||
/// `prune_rocksdb_path` test covers that configuration).
|
||||
#[test]
|
||||
#[cfg(not(all(unix, feature = "rocksdb")))]
|
||||
fn prune_static_file() {
|
||||
let db = TestStageDB::default();
|
||||
let mut rng = generators::rng();
|
||||
@@ -579,7 +577,9 @@ mod tests {
|
||||
let segment = StorageHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v2());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_storage_changesets_in_static_files(true),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
limiter.increment_deleted_entries_count_by(result.pruned);
|
||||
|
||||
@@ -739,7 +739,9 @@ mod tests {
|
||||
let segment = StorageHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default().with_storage_changesets_in_static_files(false),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
|
||||
// Should report that there's more data
|
||||
@@ -791,7 +793,9 @@ mod tests {
|
||||
};
|
||||
|
||||
let provider2 = db.factory.database_provider_rw().unwrap();
|
||||
provider2.set_storage_settings_cache(StorageSettings::v1());
|
||||
provider2.set_storage_settings_cache(
|
||||
StorageSettings::default().with_storage_changesets_in_static_files(false),
|
||||
);
|
||||
let result2 = segment.prune(&provider2, input2).unwrap();
|
||||
|
||||
assert!(result2.progress.is_finished(), "Second run should complete");
|
||||
@@ -891,7 +895,11 @@ mod tests {
|
||||
let segment = StorageHistory::new(prune_mode);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
provider.set_storage_settings_cache(StorageSettings::v2());
|
||||
provider.set_storage_settings_cache(
|
||||
StorageSettings::default()
|
||||
.with_storage_changesets_in_static_files(true)
|
||||
.with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
provider.commit().expect("commit");
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ where
|
||||
|
||||
// Check where transaction hash numbers are stored
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().transaction_hash_numbers_in_rocksdb {
|
||||
return self.prune_rocksdb(provider, input, start, end);
|
||||
}
|
||||
|
||||
@@ -491,7 +491,9 @@ mod tests {
|
||||
let segment = TransactionLookup::new(prune_mode);
|
||||
|
||||
// Enable RocksDB storage for transaction hash numbers
|
||||
db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
let result = segment.prune(&provider, input).unwrap();
|
||||
@@ -576,7 +578,9 @@ mod tests {
|
||||
}
|
||||
|
||||
// Enable RocksDB storage for transaction hash numbers
|
||||
db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let to_block: BlockNumber = 6;
|
||||
let prune_mode = PruneMode::Before(to_block);
|
||||
|
||||
@@ -148,7 +148,7 @@ impl StateProofProvider for StateProviderTest {
|
||||
|
||||
impl HashedPostStateProvider for StateProviderTest {
|
||||
fn hashed_post_state(&self, bundle_state: &revm::database::BundleState) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(bundle_state.state())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -467,7 +467,7 @@ where
|
||||
// state is then written separately below.
|
||||
provider.write_state(&state, OriginalValuesKnown::Yes, StateWriteConfig::default())?;
|
||||
|
||||
if provider.cached_storage_settings().use_hashed_state() {
|
||||
if provider.cached_storage_settings().use_hashed_state {
|
||||
let hashed_state = state.hash_state_slow::<KeccakKeyHasher>();
|
||||
provider.write_hashed_state(&hashed_state.into_sorted())?;
|
||||
}
|
||||
@@ -1269,7 +1269,8 @@ mod tests {
|
||||
// but no receipt data is written.
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory
|
||||
.set_storage_settings_cache(StorageSettings::v1().with_receipts_in_static_files(true));
|
||||
|
||||
// Setup with block 1
|
||||
let provider_rw = factory.database_provider_rw().unwrap();
|
||||
|
||||
@@ -159,7 +159,7 @@ where
|
||||
|
||||
// If using hashed state as canonical, execution already writes to `HashedAccounts`,
|
||||
// so this stage becomes a no-op.
|
||||
if provider.cached_storage_settings().use_hashed_state() {
|
||||
if provider.cached_storage_settings().use_hashed_state {
|
||||
return Ok(ExecOutput::done(input.checkpoint().with_block_number(input.target())));
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ where
|
||||
|
||||
// If use_hashed_state is enabled, execution writes directly to `HashedStorages`,
|
||||
// so this stage becomes a no-op.
|
||||
if provider.cached_storage_settings().use_hashed_state() {
|
||||
if provider.cached_storage_settings().use_hashed_state {
|
||||
return Ok(ExecOutput::done(input.checkpoint().with_block_number(input.target())));
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ where
|
||||
|
||||
let mut range = input.next_block_range();
|
||||
let first_sync = input.checkpoint().block_number == 0;
|
||||
let use_rocksdb = provider.cached_storage_settings().storage_v2;
|
||||
let use_rocksdb = provider.cached_storage_settings().account_history_in_rocksdb;
|
||||
|
||||
// On first sync we might have history coming from genesis. We clear the table since it's
|
||||
// faster to rebuild from scratch.
|
||||
@@ -122,7 +122,7 @@ where
|
||||
|
||||
info!(target: "sync::stages::index_account_history::exec", ?first_sync, ?use_rocksdb, "Collecting indices");
|
||||
|
||||
let collector = if provider.cached_storage_settings().storage_v2 {
|
||||
let collector = if provider.cached_storage_settings().account_changesets_in_static_files {
|
||||
// Use the provider-based collection that can read from static files.
|
||||
collect_account_history_indices(provider, range.clone(), &self.etl_config)?
|
||||
} else {
|
||||
@@ -666,43 +666,32 @@ mod tests {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
mod rocksdb_tests {
|
||||
use super::*;
|
||||
use reth_provider::{
|
||||
providers::StaticFileWriter, RocksDBProviderFactory, StaticFileProviderFactory,
|
||||
};
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
use reth_provider::RocksDBProviderFactory;
|
||||
use reth_storage_api::StorageSettings;
|
||||
|
||||
/// Sets up v2 account test data: writes block body indices to MDBX and
|
||||
/// account changesets to static files (matching realistic v2 layout).
|
||||
fn setup_v2_account_data(db: &TestStageDB, block_range: std::ops::RangeInclusive<u64>) {
|
||||
db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in block_range.clone() {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let static_file_provider = db.factory.static_file_provider();
|
||||
let mut writer =
|
||||
static_file_provider.latest_writer(StaticFileSegment::AccountChangeSets).unwrap();
|
||||
for block in block_range {
|
||||
writer.append_account_changeset(vec![acc()], block).unwrap();
|
||||
}
|
||||
writer.commit().unwrap();
|
||||
}
|
||||
|
||||
/// Test that when `account_history_in_rocksdb` is enabled, the stage
|
||||
/// writes account history indices to `RocksDB` instead of MDBX.
|
||||
#[tokio::test]
|
||||
async fn execute_writes_to_rocksdb_when_enabled() {
|
||||
// init
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_account_data(&db, 0..=10);
|
||||
|
||||
// Enable RocksDB for account history
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::AccountChangeSets>(block, acc())?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), ..Default::default() };
|
||||
let mut stage = IndexAccountHistoryStage::default();
|
||||
@@ -732,7 +721,22 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn unwind_works_when_rocksdb_enabled() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_account_data(&db, 0..=10);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::AccountChangeSets>(block, acc())?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), ..Default::default() };
|
||||
let mut stage = IndexAccountHistoryStage::default();
|
||||
@@ -768,7 +772,22 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn execute_incremental_sync() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_account_data(&db, 0..=10);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=5 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::AccountChangeSets>(block, acc())?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(5), ..Default::default() };
|
||||
let mut stage = IndexAccountHistoryStage::default();
|
||||
@@ -783,6 +802,18 @@ mod tests {
|
||||
let blocks: Vec<u64> = result.unwrap().iter().collect();
|
||||
assert_eq!(blocks, (0..=5).collect::<Vec<_>>());
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 6..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::AccountChangeSets>(block, acc())?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), checkpoint: Some(StageCheckpoint::new(5)) };
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
let out = stage.execute(&provider, input).unwrap();
|
||||
|
||||
@@ -107,7 +107,7 @@ where
|
||||
|
||||
let mut range = input.next_block_range();
|
||||
let first_sync = input.checkpoint().block_number == 0;
|
||||
let use_rocksdb = provider.cached_storage_settings().storage_v2;
|
||||
let use_rocksdb = provider.cached_storage_settings().storages_history_in_rocksdb;
|
||||
|
||||
// On first sync we might have history coming from genesis. We clear the table since it's
|
||||
// faster to rebuild from scratch.
|
||||
@@ -125,7 +125,7 @@ where
|
||||
}
|
||||
|
||||
info!(target: "sync::stages::index_storage_history::exec", ?first_sync, ?use_rocksdb, "Collecting indices");
|
||||
let collector = if provider.cached_storage_settings().storage_v2 {
|
||||
let collector = if provider.cached_storage_settings().storage_changesets_in_static_files {
|
||||
collect_storage_history_indices(provider, range.clone(), &self.etl_config)?
|
||||
} else {
|
||||
collect_history_indices::<_, tables::StorageChangeSets, tables::StoragesHistory, _>(
|
||||
@@ -694,51 +694,33 @@ mod tests {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
mod rocksdb_tests {
|
||||
use super::*;
|
||||
use reth_db_api::models::StorageBeforeTx;
|
||||
use reth_provider::{providers::StaticFileWriter, RocksDBProviderFactory};
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
use reth_provider::RocksDBProviderFactory;
|
||||
use reth_storage_api::StorageSettings;
|
||||
|
||||
/// Sets up v2 storage test data: writes block body indices to MDBX and
|
||||
/// storage changesets to static files (matching realistic v2 layout).
|
||||
fn setup_v2_storage_data(db: &TestStageDB, block_range: std::ops::RangeInclusive<u64>) {
|
||||
db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in block_range.clone() {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let static_file_provider = db.factory.static_file_provider();
|
||||
let mut writer =
|
||||
static_file_provider.latest_writer(StaticFileSegment::StorageChangeSets).unwrap();
|
||||
for block in block_range {
|
||||
writer
|
||||
.append_storage_changeset(
|
||||
vec![StorageBeforeTx {
|
||||
address: ADDRESS,
|
||||
key: STORAGE_KEY,
|
||||
value: U256::ZERO,
|
||||
}],
|
||||
block,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writer.commit().unwrap();
|
||||
}
|
||||
|
||||
/// Test that when `storages_history_in_rocksdb` is enabled, the stage
|
||||
/// writes storage history indices to `RocksDB` instead of MDBX.
|
||||
#[tokio::test]
|
||||
async fn execute_writes_to_rocksdb_when_enabled() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_storage_data(&db, 0..=10);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), ..Default::default() };
|
||||
let mut stage = IndexStorageHistoryStage::default();
|
||||
@@ -766,7 +748,25 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn unwind_works_when_rocksdb_enabled() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_storage_data(&db, 0..=10);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), ..Default::default() };
|
||||
let mut stage = IndexStorageHistoryStage::default();
|
||||
@@ -803,7 +803,25 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn unwind_to_zero_keeps_block_zero() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_storage_data(&db, 0..=5);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=5 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(5), ..Default::default() };
|
||||
let mut stage = IndexStorageHistoryStage::default();
|
||||
@@ -834,7 +852,25 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn execute_incremental_sync() {
|
||||
let db = TestStageDB::default();
|
||||
setup_v2_storage_data(&db, 0..=10);
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..=5 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(5), ..Default::default() };
|
||||
let mut stage = IndexStorageHistoryStage::default();
|
||||
@@ -849,6 +885,21 @@ mod tests {
|
||||
let blocks: Vec<u64> = result.unwrap().iter().collect();
|
||||
assert_eq!(blocks, (0..=5).collect::<Vec<_>>());
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 6..=10 {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(10), checkpoint: Some(StageCheckpoint::new(5)) };
|
||||
let provider = db.factory.database_provider_rw().unwrap();
|
||||
let out = stage.execute(&provider, input).unwrap();
|
||||
@@ -868,8 +919,27 @@ mod tests {
|
||||
use reth_db_api::models::sharded_key::NUM_OF_INDICES_IN_SHARD;
|
||||
|
||||
let db = TestStageDB::default();
|
||||
|
||||
db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let num_blocks = (NUM_OF_INDICES_IN_SHARD * 2 + 100) as u64;
|
||||
setup_v2_storage_data(&db, 0..=num_blocks - 1);
|
||||
|
||||
db.commit(|tx| {
|
||||
for block in 0..num_blocks {
|
||||
tx.put::<tables::BlockBodyIndices>(
|
||||
block,
|
||||
StoredBlockBodyIndices { tx_count: 3, ..Default::default() },
|
||||
)?;
|
||||
tx.put::<tables::StorageChangeSets>(
|
||||
block_number_address(block),
|
||||
storage(STORAGE_KEY),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let input = ExecInput { target: Some(num_blocks - 1), ..Default::default() };
|
||||
let mut stage = IndexStorageHistoryStage::default();
|
||||
|
||||
@@ -540,7 +540,9 @@ mod tests {
|
||||
let mut rng = generators::rng();
|
||||
|
||||
let runner = SenderRecoveryTestRunner::default();
|
||||
runner.db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
runner.db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_senders_in_static_files(true),
|
||||
);
|
||||
let input = ExecInput {
|
||||
target: Some(target),
|
||||
checkpoint: Some(StageCheckpoint::new(stage_progress)),
|
||||
|
||||
@@ -200,7 +200,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().transaction_hash_numbers_in_rocksdb {
|
||||
provider.commit_pending_rocksdb_batches()?;
|
||||
provider.rocksdb_provider().flush(&[Tables::TransactionHashNumbers.name()])?;
|
||||
}
|
||||
@@ -618,7 +618,9 @@ mod tests {
|
||||
let runner = TransactionLookupTestRunner::default();
|
||||
|
||||
// Enable RocksDB for transaction hash numbers
|
||||
runner.db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
runner.db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let input = ExecInput {
|
||||
target: Some(previous_stage),
|
||||
@@ -684,7 +686,9 @@ mod tests {
|
||||
let runner = TransactionLookupTestRunner::default();
|
||||
|
||||
// Enable RocksDB for transaction hash numbers
|
||||
runner.db.factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
runner.db.factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Insert blocks with transactions
|
||||
let blocks = random_block_range(
|
||||
|
||||
@@ -79,7 +79,7 @@ fn assert_changesets_queryable(
|
||||
let settings = provider.cached_storage_settings();
|
||||
|
||||
// Verify storage changesets
|
||||
if settings.storage_v2 {
|
||||
if settings.storage_changesets_in_static_files {
|
||||
let static_file_provider = provider_factory.static_file_provider();
|
||||
static_file_provider.initialize_index()?;
|
||||
let storage_changesets =
|
||||
@@ -118,7 +118,7 @@ fn assert_changesets_queryable(
|
||||
}
|
||||
|
||||
// Verify account changesets
|
||||
if settings.storage_v2 {
|
||||
if settings.account_changesets_in_static_files {
|
||||
let static_file_provider = provider_factory.static_file_provider();
|
||||
static_file_provider.initialize_index()?;
|
||||
let account_changesets =
|
||||
@@ -359,7 +359,7 @@ async fn run_pipeline_forward_and_unwind(
|
||||
|
||||
// Convert bundle state to hashed post state and compute state root
|
||||
let hashed_state =
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(output.state.state());
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(output.state.state());
|
||||
let (state_root, _trie_updates) = StateRoot::overlay_root_with_updates(
|
||||
provider.tx_ref(),
|
||||
&hashed_state.clone().into_sorted(),
|
||||
@@ -604,7 +604,7 @@ async fn test_pipeline() -> eyre::Result<()> {
|
||||
}
|
||||
|
||||
/// Same as [`test_pipeline`] but runs with v2 storage settings (`use_hashed_state=true`,
|
||||
/// `is_v2()=true`, etc.).
|
||||
/// `storage_changesets_in_static_files=true`, etc.).
|
||||
///
|
||||
/// In v2 mode:
|
||||
/// - The execution stage writes directly to `HashedAccounts`/`HashedStorages`
|
||||
|
||||
@@ -5,25 +5,39 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Storage configuration settings for this node.
|
||||
///
|
||||
/// Controls whether this node uses v2 storage layout (static files + `RocksDB` routing)
|
||||
/// or v1/legacy layout (everything in MDBX).
|
||||
///
|
||||
/// These should be set during `init_genesis` or `init_db` depending on whether we want dictate
|
||||
/// behaviour of new or old nodes respectively.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Compact, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, Compact)]
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
||||
#[add_arbitrary_tests(compact)]
|
||||
pub struct StorageSettings {
|
||||
/// Whether this node uses v2 storage layout.
|
||||
/// Whether this node always writes receipts to static files.
|
||||
///
|
||||
/// When `true`, enables all v2 storage features:
|
||||
/// - Receipts and transaction senders in static files
|
||||
/// - History indices in `RocksDB` (accounts, storages, transaction hashes)
|
||||
/// - Account and storage changesets in static files
|
||||
/// - Hashed state tables as canonical state representation
|
||||
///
|
||||
/// When `false`, uses v1/legacy layout (everything in MDBX).
|
||||
pub storage_v2: bool,
|
||||
/// If this is set to FALSE AND receipt pruning IS ENABLED, all receipts should be written to DB. Otherwise, they should be written to static files. This ensures that older nodes do not need to migrate their current DB tables to static files. For more, read: <https://github.com/paradigmxyz/reth/issues/18890#issuecomment-3457760097>
|
||||
#[serde(default)]
|
||||
pub receipts_in_static_files: bool,
|
||||
/// Whether this node always writes transaction senders to static files.
|
||||
#[serde(default)]
|
||||
pub transaction_senders_in_static_files: bool,
|
||||
/// Whether `StoragesHistory` is stored in `RocksDB`.
|
||||
#[serde(default)]
|
||||
pub storages_history_in_rocksdb: bool,
|
||||
/// Whether `TransactionHashNumbers` is stored in `RocksDB`.
|
||||
#[serde(default)]
|
||||
pub transaction_hash_numbers_in_rocksdb: bool,
|
||||
/// Whether `AccountsHistory` is stored in `RocksDB`.
|
||||
#[serde(default)]
|
||||
pub account_history_in_rocksdb: bool,
|
||||
/// Whether this node should read and write account changesets from static files.
|
||||
#[serde(default)]
|
||||
pub account_changesets_in_static_files: bool,
|
||||
/// Whether this node should read and write storage changesets from static files.
|
||||
#[serde(default)]
|
||||
pub storage_changesets_in_static_files: bool,
|
||||
/// Whether to use hashed state tables (`HashedAccounts`/`HashedStorages`) as the canonical
|
||||
/// state representation instead of plain state tables.
|
||||
#[serde(default)]
|
||||
pub use_hashed_state: bool,
|
||||
}
|
||||
|
||||
impl StorageSettings {
|
||||
@@ -48,58 +62,159 @@ impl StorageSettings {
|
||||
/// - Receipts and transaction senders in static files
|
||||
/// - History indices in `RocksDB` (storages, accounts, transaction hashes)
|
||||
/// - Account and storage changesets in static files
|
||||
/// - Hashed state as canonical state representation
|
||||
///
|
||||
/// Use this when the `--storage.v2` CLI flag is set.
|
||||
pub const fn v2() -> Self {
|
||||
Self { storage_v2: true }
|
||||
Self {
|
||||
receipts_in_static_files: true,
|
||||
transaction_senders_in_static_files: true,
|
||||
account_changesets_in_static_files: true,
|
||||
storage_changesets_in_static_files: true,
|
||||
storages_history_in_rocksdb: true,
|
||||
transaction_hash_numbers_in_rocksdb: true,
|
||||
account_history_in_rocksdb: true,
|
||||
use_hashed_state: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates `StorageSettings` for v1/legacy nodes.
|
||||
///
|
||||
/// This keeps all data in MDBX, matching the original storage layout.
|
||||
/// This explicitly sets `receipts_in_static_files` and `transaction_senders_in_static_files` to
|
||||
/// `false`, ensuring older nodes continue writing receipts and transaction senders to the
|
||||
/// database when receipt pruning is enabled.
|
||||
pub const fn v1() -> Self {
|
||||
Self { storage_v2: false }
|
||||
Self {
|
||||
receipts_in_static_files: false,
|
||||
transaction_senders_in_static_files: false,
|
||||
storages_history_in_rocksdb: false,
|
||||
transaction_hash_numbers_in_rocksdb: false,
|
||||
account_history_in_rocksdb: false,
|
||||
account_changesets_in_static_files: false,
|
||||
storage_changesets_in_static_files: false,
|
||||
use_hashed_state: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this node uses v2 storage layout.
|
||||
pub const fn is_v2(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `receipts_in_static_files` flag to the provided value.
|
||||
pub const fn with_receipts_in_static_files(mut self, value: bool) -> Self {
|
||||
self.receipts_in_static_files = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether receipts are stored in static files.
|
||||
pub const fn receipts_in_static_files(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `transaction_senders_in_static_files` flag to the provided value.
|
||||
pub const fn with_transaction_senders_in_static_files(mut self, value: bool) -> Self {
|
||||
self.transaction_senders_in_static_files = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether transaction senders are stored in static files.
|
||||
pub const fn transaction_senders_in_static_files(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `storages_history_in_rocksdb` flag to the provided value.
|
||||
pub const fn with_storages_history_in_rocksdb(mut self, value: bool) -> Self {
|
||||
self.storages_history_in_rocksdb = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether storages history is stored in `RocksDB`.
|
||||
pub const fn storages_history_in_rocksdb(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `transaction_hash_numbers_in_rocksdb` flag to the provided value.
|
||||
pub const fn with_transaction_hash_numbers_in_rocksdb(mut self, value: bool) -> Self {
|
||||
self.transaction_hash_numbers_in_rocksdb = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether transaction hash numbers are stored in `RocksDB`.
|
||||
pub const fn transaction_hash_numbers_in_rocksdb(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `account_history_in_rocksdb` flag to the provided value.
|
||||
pub const fn with_account_history_in_rocksdb(mut self, value: bool) -> Self {
|
||||
self.account_history_in_rocksdb = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether account history is stored in `RocksDB`.
|
||||
pub const fn account_history_in_rocksdb(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `account_changesets_in_static_files` flag to the provided value.
|
||||
pub const fn with_account_changesets_in_static_files(mut self, value: bool) -> Self {
|
||||
self.account_changesets_in_static_files = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to use hashed state tables (`HashedAccounts`/`HashedStorages`) as the canonical
|
||||
/// state representation instead of plain state tables. Implied by v2 storage layout.
|
||||
pub const fn use_hashed_state(&self) -> bool {
|
||||
self.storage_v2
|
||||
/// Sets the `storage_changesets_in_static_files` flag to the provided value.
|
||||
pub const fn with_storage_changesets_in_static_files(mut self, value: bool) -> Self {
|
||||
self.storage_changesets_in_static_files = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `use_hashed_state` flag to the provided value.
|
||||
pub const fn with_use_hashed_state(mut self, value: bool) -> Self {
|
||||
self.use_hashed_state = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `receipts_in_static_files` if `value` is `Some`.
|
||||
pub const fn with_receipts_in_static_files_opt(mut self, value: Option<bool>) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.receipts_in_static_files = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `transaction_senders_in_static_files` if `value` is `Some`.
|
||||
pub const fn with_transaction_senders_in_static_files_opt(
|
||||
mut self,
|
||||
value: Option<bool>,
|
||||
) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.transaction_senders_in_static_files = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `account_changesets_in_static_files` if `value` is `Some`.
|
||||
pub const fn with_account_changesets_in_static_files_opt(
|
||||
mut self,
|
||||
value: Option<bool>,
|
||||
) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.account_changesets_in_static_files = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `storage_changesets_in_static_files` if `value` is `Some`.
|
||||
pub const fn with_storage_changesets_in_static_files_opt(
|
||||
mut self,
|
||||
value: Option<bool>,
|
||||
) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.storage_changesets_in_static_files = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `transaction_hash_numbers_in_rocksdb` if `value` is `Some`.
|
||||
pub const fn with_transaction_hash_numbers_in_rocksdb_opt(
|
||||
mut self,
|
||||
value: Option<bool>,
|
||||
) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.transaction_hash_numbers_in_rocksdb = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `storages_history_in_rocksdb` if `value` is `Some`.
|
||||
pub const fn with_storages_history_in_rocksdb_opt(mut self, value: Option<bool>) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.storages_history_in_rocksdb = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets `account_history_in_rocksdb` if `value` is `Some`.
|
||||
pub const fn with_account_history_in_rocksdb_opt(mut self, value: Option<bool>) -> Self {
|
||||
if let Some(v) = value {
|
||||
self.account_history_in_rocksdb = v;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns `true` if any tables are configured to be stored in `RocksDB`.
|
||||
pub const fn any_in_rocksdb(&self) -> bool {
|
||||
self.storage_v2
|
||||
self.transaction_hash_numbers_in_rocksdb ||
|
||||
self.account_history_in_rocksdb ||
|
||||
self.storages_history_in_rocksdb
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,13 +214,13 @@ where
|
||||
// not the genesis block number. This would cause increment_block(N) to fail.
|
||||
let static_file_provider = provider_rw.static_file_provider();
|
||||
if genesis_block_number > 0 {
|
||||
if genesis_storage_settings.storage_v2 {
|
||||
if genesis_storage_settings.account_changesets_in_static_files {
|
||||
static_file_provider
|
||||
.get_writer(genesis_block_number, StaticFileSegment::AccountChangeSets)?
|
||||
.user_header_mut()
|
||||
.set_expected_block_start(genesis_block_number);
|
||||
}
|
||||
if genesis_storage_settings.storage_v2 {
|
||||
if genesis_storage_settings.storage_changesets_in_static_files {
|
||||
static_file_provider
|
||||
.get_writer(genesis_block_number, StaticFileSegment::StorageChangeSets)?
|
||||
.user_header_mut()
|
||||
@@ -259,7 +259,7 @@ where
|
||||
.user_header_mut()
|
||||
.set_block_range(genesis_block_number, genesis_block_number);
|
||||
|
||||
if genesis_storage_settings.storage_v2 {
|
||||
if genesis_storage_settings.transaction_senders_in_static_files {
|
||||
static_file_provider
|
||||
.get_writer(genesis_block_number, StaticFileSegment::TransactionSenders)?
|
||||
.user_header_mut()
|
||||
@@ -1052,7 +1052,7 @@ mod tests {
|
||||
)
|
||||
};
|
||||
|
||||
let (accounts, storages) = if settings.storage_v2 {
|
||||
let (accounts, storages) = if settings.account_history_in_rocksdb {
|
||||
collect_rocksdb(&rocksdb)
|
||||
} else {
|
||||
collect_from_mdbx(&factory)
|
||||
@@ -1075,7 +1075,10 @@ mod tests {
|
||||
init_genesis_with_settings(&factory, StorageSettings::v1()).unwrap();
|
||||
|
||||
// Request different settings - should warn but succeed
|
||||
let result = init_genesis_with_settings(&factory, StorageSettings::v2());
|
||||
let result = init_genesis_with_settings(
|
||||
&factory,
|
||||
StorageSettings::v1().with_receipts_in_static_files(true),
|
||||
);
|
||||
|
||||
// Should succeed (warning is logged, not an error)
|
||||
assert!(result.is_ok());
|
||||
@@ -1084,7 +1087,7 @@ mod tests {
|
||||
#[test]
|
||||
fn allow_same_storage_settings() {
|
||||
let factory = create_test_provider_factory_with_chain_spec(MAINNET.clone());
|
||||
let settings = StorageSettings::v2();
|
||||
let settings = StorageSettings::v1().with_receipts_in_static_files(true);
|
||||
init_genesis_with_settings(&factory, settings).unwrap();
|
||||
|
||||
let result = init_genesis_with_settings(&factory, settings);
|
||||
|
||||
@@ -162,7 +162,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
P: DBProvider + NodePrimitivesProvider + StorageSettingsCache + StaticFileProviderFactory,
|
||||
P::Tx: DbTxMut,
|
||||
{
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_changesets_in_static_files {
|
||||
Ok(EitherWriter::StaticFile(
|
||||
provider
|
||||
.get_static_file_writer(block_number, StaticFileSegment::AccountChangeSets)?,
|
||||
@@ -183,7 +183,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
P: DBProvider + NodePrimitivesProvider + StorageSettingsCache + StaticFileProviderFactory,
|
||||
P::Tx: DbTxMut,
|
||||
{
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storage_changesets_in_static_files {
|
||||
Ok(EitherWriter::StaticFile(
|
||||
provider
|
||||
.get_static_file_writer(block_number, StaticFileSegment::StorageChangeSets)?,
|
||||
@@ -206,7 +206,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
pub fn receipts_destination<P: DBProvider + StorageSettingsCache>(
|
||||
provider: &P,
|
||||
) -> EitherWriterDestination {
|
||||
let receipts_in_static_files = provider.cached_storage_settings().storage_v2;
|
||||
let receipts_in_static_files = provider.cached_storage_settings().receipts_in_static_files;
|
||||
let prune_modes = provider.prune_modes_ref();
|
||||
|
||||
if !receipts_in_static_files && prune_modes.has_receipts_pruning() ||
|
||||
@@ -225,7 +225,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
pub fn account_changesets_destination<P: DBProvider + StorageSettingsCache>(
|
||||
provider: &P,
|
||||
) -> EitherWriterDestination {
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_changesets_in_static_files {
|
||||
EitherWriterDestination::StaticFile
|
||||
} else {
|
||||
EitherWriterDestination::Database
|
||||
@@ -238,7 +238,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
pub fn storage_changesets_destination<P: DBProvider + StorageSettingsCache>(
|
||||
provider: &P,
|
||||
) -> EitherWriterDestination {
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storage_changesets_in_static_files {
|
||||
EitherWriterDestination::StaticFile
|
||||
} else {
|
||||
EitherWriterDestination::Database
|
||||
@@ -255,7 +255,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
P::Tx: DbTxMut,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storages_history_in_rocksdb {
|
||||
return Ok(EitherWriter::RocksDB(_rocksdb_batch));
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
P::Tx: DbTxMut,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().transaction_hash_numbers_in_rocksdb {
|
||||
return Ok(EitherWriter::RocksDB(_rocksdb_batch));
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ impl<'a> EitherWriter<'a, (), ()> {
|
||||
P::Tx: DbTxMut,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_history_in_rocksdb {
|
||||
return Ok(EitherWriter::RocksDB(_rocksdb_batch));
|
||||
}
|
||||
|
||||
@@ -764,7 +764,7 @@ impl<'a> EitherReader<'a, (), ()> {
|
||||
P::Tx: DbTx,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storages_history_in_rocksdb {
|
||||
return Ok(EitherReader::RocksDB(
|
||||
_rocksdb_tx.expect("storages_history_in_rocksdb requires rocksdb tx"),
|
||||
));
|
||||
@@ -786,7 +786,7 @@ impl<'a> EitherReader<'a, (), ()> {
|
||||
P::Tx: DbTx,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().transaction_hash_numbers_in_rocksdb {
|
||||
return Ok(EitherReader::RocksDB(
|
||||
_rocksdb_tx.expect("transaction_hash_numbers_in_rocksdb requires rocksdb tx"),
|
||||
));
|
||||
@@ -808,7 +808,7 @@ impl<'a> EitherReader<'a, (), ()> {
|
||||
P::Tx: DbTx,
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_history_in_rocksdb {
|
||||
return Ok(EitherReader::RocksDB(
|
||||
_rocksdb_tx.expect("account_history_in_rocksdb requires rocksdb tx"),
|
||||
));
|
||||
@@ -1046,7 +1046,7 @@ impl EitherWriterDestination {
|
||||
P: StorageSettingsCache,
|
||||
{
|
||||
// Write senders to static files only if they're explicitly enabled
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().transaction_senders_in_static_files {
|
||||
Self::StaticFile
|
||||
} else {
|
||||
Self::Database
|
||||
@@ -1059,7 +1059,7 @@ impl EitherWriterDestination {
|
||||
P: StorageSettingsCache,
|
||||
{
|
||||
// Write account changesets to static files only if they're explicitly enabled
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().account_changesets_in_static_files {
|
||||
Self::StaticFile
|
||||
} else {
|
||||
Self::Database
|
||||
@@ -1072,7 +1072,7 @@ impl EitherWriterDestination {
|
||||
P: StorageSettingsCache,
|
||||
{
|
||||
// Write storage changesets to static files only if they're explicitly enabled
|
||||
if provider.cached_storage_settings().storage_v2 {
|
||||
if provider.cached_storage_settings().storage_changesets_in_static_files {
|
||||
Self::StaticFile
|
||||
} else {
|
||||
Self::Database
|
||||
@@ -1127,7 +1127,9 @@ mod tests {
|
||||
writer.commit().unwrap();
|
||||
}
|
||||
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::default().with_account_changesets_in_static_files(true),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_ro().unwrap();
|
||||
|
||||
@@ -1159,11 +1161,10 @@ mod tests {
|
||||
];
|
||||
|
||||
for transaction_senders_in_static_files in [false, true] {
|
||||
factory.set_storage_settings_cache(if transaction_senders_in_static_files {
|
||||
StorageSettings::v2()
|
||||
} else {
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
});
|
||||
.with_transaction_senders_in_static_files(transaction_senders_in_static_files),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_rw().unwrap();
|
||||
let mut writer = EitherWriter::new_senders(&provider, 0).unwrap();
|
||||
@@ -1233,7 +1234,9 @@ mod rocksdb_tests {
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Enable RocksDB for transaction hash numbers
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let hash1 = B256::from([1u8; 32]);
|
||||
let hash2 = B256::from([2u8; 32]);
|
||||
@@ -1275,7 +1278,9 @@ mod rocksdb_tests {
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Enable RocksDB for transaction hash numbers
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let hash = B256::from([1u8; 32]);
|
||||
let tx_num = 100u64;
|
||||
@@ -1827,7 +1832,9 @@ mod rocksdb_tests {
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
// Enable RocksDB for transaction hash numbers
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let hash1 = B256::from([1u8; 32]);
|
||||
let hash2 = B256::from([2u8; 32]);
|
||||
@@ -1885,7 +1892,9 @@ mod rocksdb_tests {
|
||||
fn test_settings_mismatch_panics() {
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_ro().unwrap();
|
||||
let _ = EitherReader::<(), ()>::new_accounts_history(&provider, None);
|
||||
|
||||
@@ -621,7 +621,7 @@ impl<N: ProviderNodeTypes> StateProviderFactory for BlockchainProvider<N> {
|
||||
|
||||
impl<N: NodeTypesWithDB> HashedPostStateProvider for BlockchainProvider<N> {
|
||||
fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(bundle_state.state())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1313,7 +1313,7 @@ impl<N: ProviderNodeTypes> StorageChangeSetReader for ConsistentProvider<N> {
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> ProviderResult<Vec<(BlockNumberAddress, ChangesetEntry)>> {
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state;
|
||||
if let Some(state) =
|
||||
self.head_block.as_ref().and_then(|b| b.block_on_chain(block_number.into()))
|
||||
{
|
||||
@@ -1368,7 +1368,7 @@ impl<N: ProviderNodeTypes> StorageChangeSetReader for ConsistentProvider<N> {
|
||||
address: Address,
|
||||
storage_key: B256,
|
||||
) -> ProviderResult<Option<ChangesetEntry>> {
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state;
|
||||
if let Some(state) =
|
||||
self.head_block.as_ref().and_then(|b| b.block_on_chain(block_number.into()))
|
||||
{
|
||||
@@ -1421,7 +1421,7 @@ impl<N: ProviderNodeTypes> StorageChangeSetReader for ConsistentProvider<N> {
|
||||
let database_start = range.start;
|
||||
let mut database_end = range.end;
|
||||
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed = self.storage_provider.cached_storage_settings().use_hashed_state;
|
||||
|
||||
if let Some(head_block) = &self.head_block {
|
||||
database_end = head_block.anchor().number;
|
||||
|
||||
@@ -719,7 +719,7 @@ impl<N: ProviderNodeTypes> PruneCheckpointReader for ProviderFactory<N> {
|
||||
|
||||
impl<N: ProviderNodeTypes> HashedPostStateProvider for ProviderFactory<N> {
|
||||
fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(bundle_state.state())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -559,7 +559,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
let rocksdb_ctx = self.rocksdb_write_ctx(first_number);
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
let rocksdb_enabled = rocksdb_ctx.storage_settings.storage_v2;
|
||||
let rocksdb_enabled = rocksdb_ctx.storage_settings.any_in_rocksdb();
|
||||
|
||||
let mut sf_result = None;
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
@@ -595,7 +595,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
|
||||
let mdbx_start = Instant::now();
|
||||
|
||||
// Collect all transaction hashes across all blocks, sort them, and write in batch
|
||||
if !self.cached_storage_settings().storage_v2 &&
|
||||
if !self.cached_storage_settings().transaction_hash_numbers_in_rocksdb &&
|
||||
self.prune_modes.transaction_lookup.is_none_or(|m| !m.is_full())
|
||||
{
|
||||
let start = Instant::now();
|
||||
@@ -1396,7 +1396,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
|
||||
|
||||
impl<TX: DbTx, N: NodeTypes> AccountReader for DatabaseProvider<TX, N> {
|
||||
fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
|
||||
if self.cached_storage_settings().use_hashed_state() {
|
||||
if self.cached_storage_settings().use_hashed_state {
|
||||
let hashed_address = keccak256(address);
|
||||
Ok(self.tx.get_by_encoded_key::<tables::HashedAccounts>(&hashed_address)?)
|
||||
} else {
|
||||
@@ -1419,7 +1419,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> AccountExtReader for DatabaseProvider<TX,
|
||||
&self,
|
||||
iter: impl IntoIterator<Item = Address>,
|
||||
) -> ProviderResult<Vec<(Address, Option<Account>)>> {
|
||||
if self.cached_storage_settings().use_hashed_state() {
|
||||
if self.cached_storage_settings().use_hashed_state {
|
||||
let mut hashed_accounts = self.tx.cursor_read::<tables::HashedAccounts>()?;
|
||||
Ok(iter
|
||||
.into_iter()
|
||||
@@ -1448,7 +1448,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> AccountExtReader for DatabaseProvider<TX,
|
||||
.get_highest_static_file_block(StaticFileSegment::AccountChangeSets);
|
||||
|
||||
if let Some(highest) = highest_static_block &&
|
||||
self.cached_storage_settings().storage_v2
|
||||
self.cached_storage_settings().account_changesets_in_static_files
|
||||
{
|
||||
let start = *range.start();
|
||||
let static_end = (*range.end()).min(highest);
|
||||
@@ -1489,7 +1489,7 @@ impl<TX: DbTx, N: NodeTypes> StorageChangeSetReader for DatabaseProvider<TX, N>
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> ProviderResult<Vec<(BlockNumberAddress, ChangesetEntry)>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.static_file_provider.storage_changeset(block_number)
|
||||
} else {
|
||||
let range = block_number..=block_number;
|
||||
@@ -1517,7 +1517,7 @@ impl<TX: DbTx, N: NodeTypes> StorageChangeSetReader for DatabaseProvider<TX, N>
|
||||
address: Address,
|
||||
storage_key: B256,
|
||||
) -> ProviderResult<Option<ChangesetEntry>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.static_file_provider.get_storage_before_block(block_number, address, storage_key)
|
||||
} else {
|
||||
Ok(self
|
||||
@@ -1536,7 +1536,7 @@ impl<TX: DbTx, N: NodeTypes> StorageChangeSetReader for DatabaseProvider<TX, N>
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<(BlockNumberAddress, ChangesetEntry)>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.static_file_provider.storage_changesets_range(range)
|
||||
} else {
|
||||
self.tx
|
||||
@@ -1557,7 +1557,7 @@ impl<TX: DbTx, N: NodeTypes> StorageChangeSetReader for DatabaseProvider<TX, N>
|
||||
}
|
||||
|
||||
fn storage_changeset_count(&self) -> ProviderResult<usize> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.static_file_provider.storage_changeset_count()
|
||||
} else {
|
||||
Ok(self.tx.entries::<tables::StorageChangeSets>()?)
|
||||
@@ -1570,7 +1570,7 @@ impl<TX: DbTx, N: NodeTypes> ChangeSetReader for DatabaseProvider<TX, N> {
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> ProviderResult<Vec<AccountBeforeTx>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().account_changesets_in_static_files {
|
||||
let static_changesets =
|
||||
self.static_file_provider.account_block_changeset(block_number)?;
|
||||
Ok(static_changesets)
|
||||
@@ -1592,7 +1592,7 @@ impl<TX: DbTx, N: NodeTypes> ChangeSetReader for DatabaseProvider<TX, N> {
|
||||
block_number: BlockNumber,
|
||||
address: Address,
|
||||
) -> ProviderResult<Option<AccountBeforeTx>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().account_changesets_in_static_files {
|
||||
Ok(self.static_file_provider.get_account_before_block(block_number, address)?)
|
||||
} else {
|
||||
self.tx
|
||||
@@ -1608,7 +1608,7 @@ impl<TX: DbTx, N: NodeTypes> ChangeSetReader for DatabaseProvider<TX, N> {
|
||||
&self,
|
||||
range: impl core::ops::RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<(BlockNumber, AccountBeforeTx)>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().account_changesets_in_static_files {
|
||||
self.static_file_provider.account_changesets_range(range)
|
||||
} else {
|
||||
self.tx
|
||||
@@ -1622,7 +1622,7 @@ impl<TX: DbTx, N: NodeTypes> ChangeSetReader for DatabaseProvider<TX, N> {
|
||||
fn account_changeset_count(&self) -> ProviderResult<usize> {
|
||||
// check if account changesets are in static files, otherwise just count the changeset
|
||||
// entries in the DB
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().account_changesets_in_static_files {
|
||||
self.static_file_provider.account_changeset_count()
|
||||
} else {
|
||||
Ok(self.tx.entries::<tables::AccountChangeSets>()?)
|
||||
@@ -2243,7 +2243,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> StorageReader for DatabaseProvider<TX, N>
|
||||
&self,
|
||||
addresses_with_keys: impl IntoIterator<Item = (Address, impl IntoIterator<Item = B256>)>,
|
||||
) -> ProviderResult<Vec<(Address, Vec<StorageEntry>)>> {
|
||||
if self.cached_storage_settings().use_hashed_state() {
|
||||
if self.cached_storage_settings().use_hashed_state {
|
||||
let mut hashed_storage = self.tx.cursor_dup_read::<tables::HashedStorages>()?;
|
||||
|
||||
addresses_with_keys
|
||||
@@ -2290,7 +2290,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> StorageReader for DatabaseProvider<TX, N>
|
||||
&self,
|
||||
range: RangeInclusive<BlockNumber>,
|
||||
) -> ProviderResult<BTreeMap<Address, BTreeSet<B256>>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.storage_changesets_range(range)?.into_iter().try_fold(
|
||||
BTreeMap::new(),
|
||||
|mut accounts: BTreeMap<Address, BTreeSet<B256>>, entry| {
|
||||
@@ -2320,7 +2320,7 @@ impl<TX: DbTx + 'static, N: NodeTypes> StorageReader for DatabaseProvider<TX, N>
|
||||
&self,
|
||||
range: RangeInclusive<BlockNumber>,
|
||||
) -> ProviderResult<BTreeMap<(Address, B256), Vec<u64>>> {
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storage_changesets_in_static_files {
|
||||
self.storage_changesets_range(range)?.into_iter().try_fold(
|
||||
BTreeMap::new(),
|
||||
|mut storages: BTreeMap<(Address, B256), Vec<u64>>, (index, storage)| {
|
||||
@@ -2470,7 +2470,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
first_block: BlockNumber,
|
||||
config: StateWriteConfig,
|
||||
) -> ProviderResult<()> {
|
||||
let use_hashed_state = self.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed_state = self.cached_storage_settings().use_hashed_state;
|
||||
|
||||
// Write storage changes
|
||||
if config.write_storage_changesets {
|
||||
@@ -2575,7 +2575,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
// When use_hashed_state is enabled, skip plain state writes for accounts and storage.
|
||||
// The hashed state is already written by the separate `write_hashed_state()` call.
|
||||
// Bytecode writes remain unconditional since Bytecodes is not a plain/hashed table.
|
||||
if !self.cached_storage_settings().use_hashed_state() {
|
||||
if !self.cached_storage_settings().use_hashed_state {
|
||||
// Write new account state
|
||||
tracing::trace!(len = changes.accounts.len(), "Writing new account state");
|
||||
let mut accounts_cursor = self.tx_ref().cursor_write::<tables::PlainAccountState>()?;
|
||||
@@ -2709,7 +2709,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
block_bodies.first().expect("already checked if there are blocks").first_tx_num();
|
||||
|
||||
let storage_range = BlockNumberAddress::range(range.clone());
|
||||
let storage_changeset = if self.cached_storage_settings().storage_v2 {
|
||||
let storage_changeset = if self.cached_storage_settings().storage_changesets_in_static_files
|
||||
{
|
||||
let changesets = self.storage_changesets_range(range.clone())?;
|
||||
let mut changeset_writer =
|
||||
self.static_file_provider.latest_writer(StaticFileSegment::StorageChangeSets)?;
|
||||
@@ -2723,7 +2724,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let account_changeset = if self.cached_storage_settings().storage_v2 {
|
||||
let account_changeset = if self.cached_storage_settings().account_changesets_in_static_files
|
||||
{
|
||||
let changesets = self.account_changesets_range(range)?;
|
||||
let mut changeset_writer =
|
||||
self.static_file_provider.latest_writer(StaticFileSegment::AccountChangeSets)?;
|
||||
@@ -2733,7 +2735,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
self.take::<tables::AccountChangeSets>(range)?
|
||||
};
|
||||
|
||||
if self.cached_storage_settings().use_hashed_state() {
|
||||
if self.cached_storage_settings().use_hashed_state {
|
||||
let mut hashed_accounts_cursor = self.tx.cursor_write::<tables::HashedAccounts>()?;
|
||||
let mut hashed_storage_cursor = self.tx.cursor_dup_write::<tables::HashedStorages>()?;
|
||||
|
||||
@@ -2866,7 +2868,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
let storage_changeset = if let Some(highest_block) = self
|
||||
.static_file_provider
|
||||
.get_highest_static_file_block(StaticFileSegment::StorageChangeSets) &&
|
||||
self.cached_storage_settings().storage_v2
|
||||
self.cached_storage_settings().storage_changesets_in_static_files
|
||||
{
|
||||
let changesets = self.storage_changesets_range(block + 1..=highest_block)?;
|
||||
let mut changeset_writer =
|
||||
@@ -2887,7 +2889,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
.static_file_provider
|
||||
.get_highest_static_file_block(StaticFileSegment::AccountChangeSets);
|
||||
let account_changeset = if let Some(highest_block) = highest_changeset_block &&
|
||||
self.cached_storage_settings().storage_v2
|
||||
self.cached_storage_settings().account_changesets_in_static_files
|
||||
{
|
||||
// TODO: add a `take` method that removes and returns the items instead of doing this
|
||||
let changesets = self.account_changesets_range(block + 1..highest_block + 1)?;
|
||||
@@ -2902,7 +2904,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> StateWriter
|
||||
self.take::<tables::AccountChangeSets>(range)?
|
||||
};
|
||||
|
||||
let (state, reverts) = if self.cached_storage_settings().use_hashed_state() {
|
||||
let (state, reverts) = if self.cached_storage_settings().use_hashed_state {
|
||||
let mut hashed_accounts_cursor = self.tx.cursor_write::<tables::HashedAccounts>()?;
|
||||
let mut hashed_storage_cursor = self.tx.cursor_dup_write::<tables::HashedStorages>()?;
|
||||
|
||||
@@ -3258,7 +3260,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HistoryWriter for DatabaseProvi
|
||||
.collect::<Vec<_>>();
|
||||
last_indices.sort_unstable_by_key(|(a, _)| *a);
|
||||
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().account_history_in_rocksdb {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
{
|
||||
let batch = self.rocksdb_provider.unwind_account_history_indices(&last_indices)?;
|
||||
@@ -3320,7 +3322,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HistoryWriter for DatabaseProvi
|
||||
.collect::<Vec<_>>();
|
||||
storage_changesets.sort_by_key(|(address, key, _)| (*address, *key));
|
||||
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().storages_history_in_rocksdb {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
{
|
||||
let batch =
|
||||
@@ -3379,12 +3381,12 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HistoryWriter for DatabaseProvi
|
||||
#[instrument(level = "debug", target = "providers::db", skip_all)]
|
||||
fn update_history_indices(&self, range: RangeInclusive<BlockNumber>) -> ProviderResult<()> {
|
||||
let storage_settings = self.cached_storage_settings();
|
||||
if !storage_settings.storage_v2 {
|
||||
if !storage_settings.account_history_in_rocksdb {
|
||||
let indices = self.changed_accounts_and_blocks_with_range(range.clone())?;
|
||||
self.insert_account_history_index(indices)?;
|
||||
}
|
||||
|
||||
if !storage_settings.storage_v2 {
|
||||
if !storage_settings.storages_history_in_rocksdb {
|
||||
let indices = self.changed_storages_and_blocks_with_range(range)?;
|
||||
self.insert_storage_history_index(indices)?;
|
||||
}
|
||||
@@ -3643,7 +3645,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> BlockWriter
|
||||
// This is necessary because with edge storage, changesets are written to static files
|
||||
// whose index isn't updated until commit, making them invisible to subsequent reads
|
||||
// within the same transaction.
|
||||
let use_hashed = self.cached_storage_settings().use_hashed_state();
|
||||
let use_hashed = self.cached_storage_settings().use_hashed_state;
|
||||
let (account_transitions, storage_transitions) = {
|
||||
let mut account_transitions: BTreeMap<Address, Vec<u64>> = BTreeMap::new();
|
||||
let mut storage_transitions: BTreeMap<(Address, B256), Vec<u64>> = BTreeMap::new();
|
||||
@@ -3679,7 +3681,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> BlockWriter
|
||||
// Note: For MDBX we use insert_*_history_index. For RocksDB we use
|
||||
// append_*_history_shard which handles read-merge-write internally.
|
||||
let storage_settings = self.cached_storage_settings();
|
||||
if storage_settings.storage_v2 {
|
||||
if storage_settings.account_history_in_rocksdb {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
self.with_rocksdb_batch(|mut batch| {
|
||||
for (address, blocks) in account_transitions {
|
||||
@@ -3690,7 +3692,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider> BlockWriter
|
||||
} else {
|
||||
self.insert_account_history_index(account_transitions)?;
|
||||
}
|
||||
if storage_settings.storage_v2 {
|
||||
if storage_settings.storages_history_in_rocksdb {
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
self.with_rocksdb_batch(|mut batch| {
|
||||
for ((address, key), blocks) in storage_transitions {
|
||||
@@ -4443,7 +4445,7 @@ mod tests {
|
||||
// Static files mode
|
||||
{
|
||||
let factory = create_test_provider_factory();
|
||||
let storage_settings = StorageSettings::v2();
|
||||
let storage_settings = StorageSettings::v1().with_receipts_in_static_files(true);
|
||||
factory.set_storage_settings_cache(storage_settings);
|
||||
let factory = factory.with_prune_modes(PruneModes {
|
||||
receipts: Some(PruneMode::Before(2)),
|
||||
@@ -4601,7 +4603,7 @@ mod tests {
|
||||
fn test_write_and_remove_state_roundtrip_legacy() {
|
||||
let factory = create_test_provider_factory();
|
||||
let storage_settings = StorageSettings::v1();
|
||||
assert!(!storage_settings.use_hashed_state());
|
||||
assert!(!storage_settings.use_hashed_state);
|
||||
factory.set_storage_settings_cache(storage_settings);
|
||||
|
||||
let address = Address::with_last_byte(1);
|
||||
@@ -4769,7 +4771,7 @@ mod tests {
|
||||
fn test_unwind_storage_hashing_legacy() {
|
||||
let factory = create_test_provider_factory();
|
||||
let storage_settings = StorageSettings::v1();
|
||||
assert!(!storage_settings.use_hashed_state());
|
||||
assert!(!storage_settings.use_hashed_state);
|
||||
factory.set_storage_settings_cache(storage_settings);
|
||||
|
||||
let address = Address::random();
|
||||
@@ -5203,7 +5205,7 @@ mod tests {
|
||||
fn test_write_and_remove_state_roundtrip_v2() {
|
||||
let factory = create_test_provider_factory();
|
||||
let storage_settings = StorageSettings::v2();
|
||||
assert!(storage_settings.use_hashed_state());
|
||||
assert!(storage_settings.use_hashed_state);
|
||||
factory.set_storage_settings_cache(storage_settings);
|
||||
|
||||
let address = Address::with_last_byte(1);
|
||||
|
||||
@@ -62,21 +62,21 @@ impl RocksDBProvider {
|
||||
let mut unwind_target: Option<BlockNumber> = None;
|
||||
|
||||
// Heal TransactionHashNumbers if stored in RocksDB
|
||||
if provider.cached_storage_settings().storage_v2 &&
|
||||
if provider.cached_storage_settings().transaction_hash_numbers_in_rocksdb &&
|
||||
let Some(target) = self.heal_transaction_hash_numbers(provider)?
|
||||
{
|
||||
unwind_target = Some(unwind_target.map_or(target, |t| t.min(target)));
|
||||
}
|
||||
|
||||
// Heal StoragesHistory if stored in RocksDB
|
||||
if provider.cached_storage_settings().storage_v2 &&
|
||||
if provider.cached_storage_settings().storages_history_in_rocksdb &&
|
||||
let Some(target) = self.heal_storages_history(provider)?
|
||||
{
|
||||
unwind_target = Some(unwind_target.map_or(target, |t| t.min(target)));
|
||||
}
|
||||
|
||||
// Heal AccountsHistory if stored in RocksDB
|
||||
if provider.cached_storage_settings().storage_v2 &&
|
||||
if provider.cached_storage_settings().account_history_in_rocksdb &&
|
||||
let Some(target) = self.heal_accounts_history(provider)?
|
||||
{
|
||||
unwind_target = Some(unwind_target.map_or(target, |t| t.min(target)));
|
||||
@@ -496,11 +496,19 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_empty_rocksdb_no_checkpoint_is_ok() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::TransactionHashNumbers>()
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
.with_transaction_hash_numbers_in_rocksdb(true)
|
||||
.with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_ro().unwrap();
|
||||
|
||||
@@ -512,11 +520,16 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_empty_rocksdb_with_checkpoint_is_first_run() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::TransactionHashNumbers>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Set a checkpoint indicating we should have processed up to block 100
|
||||
{
|
||||
@@ -540,10 +553,15 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_checkpoint_zero_with_rocksdb_data_prunes_all() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::TransactionHashNumbers>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Generate blocks with real transactions and insert them
|
||||
let mut rng = generators::rng();
|
||||
@@ -571,18 +589,12 @@ mod tests {
|
||||
provider.commit().unwrap();
|
||||
}
|
||||
|
||||
// Explicitly clear the checkpoints to simulate crash recovery
|
||||
// Explicitly clear the TransactionLookup checkpoint to simulate crash recovery
|
||||
{
|
||||
let provider = factory.database_provider_rw().unwrap();
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::TransactionLookup, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexStorageHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexAccountHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider.commit().unwrap();
|
||||
}
|
||||
|
||||
@@ -608,11 +620,16 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_storages_history_empty_with_checkpoint_is_first_run() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Set a checkpoint indicating we should have processed up to block 100
|
||||
{
|
||||
@@ -635,7 +652,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_storages_history_has_data_no_checkpoint_prunes_data() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert data into RocksDB
|
||||
let key = StorageShardedKey::new(Address::ZERO, B256::ZERO, 50);
|
||||
@@ -647,7 +667,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX with NO checkpoint
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_ro().unwrap();
|
||||
|
||||
@@ -665,10 +687,15 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_mdbx_behind_checkpoint_needs_unwind() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::TransactionHashNumbers>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Generate blocks with real transactions (blocks 0-2, 6 transactions total)
|
||||
let mut rng = generators::rng();
|
||||
@@ -702,13 +729,6 @@ mod tests {
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::TransactionLookup, StageCheckpoint::new(10))
|
||||
.unwrap();
|
||||
// Reset history checkpoints so they don't interfere
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexStorageHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexAccountHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider.commit().unwrap();
|
||||
}
|
||||
|
||||
@@ -722,11 +742,16 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_rocksdb_ahead_of_checkpoint_prunes_excess() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::TransactionHashNumbers>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Generate blocks with real transactions:
|
||||
// Blocks 0-5, each with 2 transactions = 12 total transactions (0-11)
|
||||
@@ -784,13 +809,6 @@ mod tests {
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::TransactionLookup, StageCheckpoint::new(2))
|
||||
.unwrap();
|
||||
// Reset history checkpoints so they don't interfere
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexStorageHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider
|
||||
.save_stage_checkpoint(StageId::IndexAccountHistory, StageCheckpoint::new(0))
|
||||
.unwrap();
|
||||
provider.commit().unwrap();
|
||||
}
|
||||
|
||||
@@ -825,7 +843,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_storages_history_sentinel_only_with_checkpoint_is_first_run() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert ONLY sentinel entries (highest_block_number = u64::MAX)
|
||||
// This simulates a scenario where history tracking started but no shards were completed
|
||||
@@ -840,7 +861,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Set a checkpoint indicating we should have processed up to block 100
|
||||
{
|
||||
@@ -865,7 +888,10 @@ mod tests {
|
||||
use reth_db_api::models::ShardedKey;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert ONLY sentinel entries (highest_block_number = u64::MAX)
|
||||
let key_sentinel_1 = ShardedKey::new(Address::ZERO, u64::MAX);
|
||||
@@ -879,7 +905,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Set a checkpoint indicating we should have processed up to block 100
|
||||
{
|
||||
@@ -912,7 +940,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_transaction_hash_numbers_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Generate random blocks with unique transactions
|
||||
// Block 0 (genesis) has no transactions
|
||||
@@ -1016,11 +1046,16 @@ mod tests {
|
||||
#[test]
|
||||
fn test_check_consistency_accounts_history_empty_with_checkpoint_is_first_run() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Set a checkpoint indicating we should have processed up to block 100
|
||||
{
|
||||
@@ -1045,7 +1080,10 @@ mod tests {
|
||||
use reth_db_api::models::ShardedKey;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert data into RocksDB
|
||||
let key = ShardedKey::new(Address::ZERO, 50);
|
||||
@@ -1057,7 +1095,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX with NO checkpoint
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
let provider = factory.database_provider_ro().unwrap();
|
||||
|
||||
@@ -1080,7 +1120,10 @@ mod tests {
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert some AccountsHistory entries with various highest_block_numbers
|
||||
let key1 = ShardedKey::new(Address::ZERO, 50);
|
||||
@@ -1100,7 +1143,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory for MDBX
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_account_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Write account changesets to static files for blocks 0-100
|
||||
{
|
||||
@@ -1179,10 +1224,17 @@ mod tests {
|
||||
const CHECKPOINT_BLOCK: u64 = 5_000;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
.with_storages_history_in_rocksdb(true)
|
||||
.with_storage_changesets_in_static_files(true),
|
||||
);
|
||||
|
||||
// Helper to generate address from block number (reuses stack arrays)
|
||||
#[inline]
|
||||
@@ -1296,10 +1348,17 @@ mod tests {
|
||||
const SF_TIP: u64 = 200;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
.with_storages_history_in_rocksdb(true)
|
||||
.with_storage_changesets_in_static_files(true),
|
||||
);
|
||||
|
||||
let checkpoint_addr = Address::repeat_byte(0xAA);
|
||||
let checkpoint_slot = B256::repeat_byte(0xBB);
|
||||
@@ -1394,11 +1453,18 @@ mod tests {
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Create test provider factory
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
.with_account_history_in_rocksdb(true)
|
||||
.with_account_changesets_in_static_files(true),
|
||||
);
|
||||
|
||||
const TOTAL_BLOCKS: u64 = 15_000;
|
||||
const CHECKPOINT_BLOCK: u64 = 5_000;
|
||||
@@ -1509,10 +1575,17 @@ mod tests {
|
||||
const SF_TIP: u64 = 200;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::AccountsHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1()
|
||||
.with_account_history_in_rocksdb(true)
|
||||
.with_account_changesets_in_static_files(true),
|
||||
);
|
||||
|
||||
let checkpoint_addr = Address::repeat_byte(0xAA);
|
||||
let stale_addr = Address::repeat_byte(0xCC);
|
||||
@@ -1579,7 +1652,10 @@ mod tests {
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path()).with_default_tables().build().unwrap();
|
||||
let rocksdb = RocksDBBuilder::new(temp_dir.path())
|
||||
.with_table::<tables::StoragesHistory>()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Insert StoragesHistory entries into RocksDB
|
||||
let key1 = StorageShardedKey::new(Address::ZERO, B256::ZERO, 50);
|
||||
@@ -1595,7 +1671,9 @@ mod tests {
|
||||
|
||||
// Create a test provider factory
|
||||
let factory = create_test_provider_factory();
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
factory.set_storage_settings_cache(
|
||||
StorageSettings::v1().with_storages_history_in_rocksdb(true),
|
||||
);
|
||||
|
||||
// Write storage changesets to static files for blocks 0-100
|
||||
{
|
||||
|
||||
@@ -1204,7 +1204,7 @@ impl RocksDBProvider {
|
||||
ctx: RocksDBWriteCtx,
|
||||
runtime: &reth_tasks::Runtime,
|
||||
) -> ProviderResult<()> {
|
||||
if !ctx.storage_settings.storage_v2 {
|
||||
if !ctx.storage_settings.any_in_rocksdb() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -1212,10 +1212,10 @@ impl RocksDBProvider {
|
||||
let mut r_account_history = None;
|
||||
let mut r_storage_history = None;
|
||||
|
||||
let write_tx_hash =
|
||||
ctx.storage_settings.storage_v2 && ctx.prune_tx_lookup.is_none_or(|m| !m.is_full());
|
||||
let write_account_history = ctx.storage_settings.storage_v2;
|
||||
let write_storage_history = ctx.storage_settings.storage_v2;
|
||||
let write_tx_hash = ctx.storage_settings.transaction_hash_numbers_in_rocksdb &&
|
||||
ctx.prune_tx_lookup.is_none_or(|m| !m.is_full());
|
||||
let write_account_history = ctx.storage_settings.account_history_in_rocksdb;
|
||||
let write_storage_history = ctx.storage_settings.storages_history_in_rocksdb;
|
||||
|
||||
runtime.storage_pool().in_place_scope(|s| {
|
||||
if write_tx_hash {
|
||||
|
||||
@@ -159,7 +159,7 @@ impl<'b, Provider: DBProvider + ChangeSetReader + StorageChangeSetReader + Block
|
||||
return Err(ProviderError::StateAtBlockPruned(self.block_number))
|
||||
}
|
||||
|
||||
let lookup_key = if self.provider.cached_storage_settings().use_hashed_state() {
|
||||
let lookup_key = if self.provider.cached_storage_settings().use_hashed_state {
|
||||
storage_key.to_hashed()
|
||||
} else {
|
||||
debug_assert!(
|
||||
@@ -193,7 +193,7 @@ impl<'b, Provider: DBProvider + ChangeSetReader + StorageChangeSetReader + Block
|
||||
where
|
||||
Provider: StorageSettingsCache + RocksDBProviderFactory + NodePrimitivesProvider,
|
||||
{
|
||||
let lookup_key = if self.provider.cached_storage_settings().use_hashed_state() {
|
||||
let lookup_key = if self.provider.cached_storage_settings().use_hashed_state {
|
||||
storage_key.to_hashed()
|
||||
} else {
|
||||
debug_assert!(
|
||||
@@ -216,7 +216,7 @@ impl<'b, Provider: DBProvider + ChangeSetReader + StorageChangeSetReader + Block
|
||||
.map(|entry| entry.value)
|
||||
.map(Some),
|
||||
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => {
|
||||
if self.provider.cached_storage_settings().use_hashed_state() {
|
||||
if self.provider.cached_storage_settings().use_hashed_state {
|
||||
let hashed_address = alloy_primitives::keccak256(address);
|
||||
Ok(self
|
||||
.tx()
|
||||
@@ -337,7 +337,7 @@ impl<
|
||||
.map(|account_before| account_before.info)
|
||||
}
|
||||
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => {
|
||||
if self.provider.cached_storage_settings().use_hashed_state() {
|
||||
if self.provider.cached_storage_settings().use_hashed_state {
|
||||
let hashed_address = alloy_primitives::keccak256(address);
|
||||
Ok(self.tx().get_by_encoded_key::<tables::HashedAccounts>(&hashed_address)?)
|
||||
} else {
|
||||
@@ -491,7 +491,7 @@ impl<
|
||||
|
||||
impl<Provider> HashedPostStateProvider for HistoricalStateProviderRef<'_, Provider> {
|
||||
fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(bundle_state.state())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ impl<
|
||||
address: Address,
|
||||
hashed_storage_key: StorageKey,
|
||||
) -> ProviderResult<Option<StorageValue>> {
|
||||
if !self.provider.cached_storage_settings().use_hashed_state() {
|
||||
if !self.provider.cached_storage_settings().use_hashed_state {
|
||||
return Err(ProviderError::UnsupportedProvider)
|
||||
}
|
||||
self.storage_by_lookup_key(address, StorageSlotKey::hashed(hashed_storage_key))
|
||||
@@ -1033,7 +1033,7 @@ mod tests {
|
||||
fn history_provider_get_storage_legacy() {
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state());
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state);
|
||||
|
||||
let tx = factory.provider_rw().unwrap().into_tx();
|
||||
|
||||
@@ -1277,7 +1277,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_historical_storage_by_hashed_key_unsupported_in_v1() {
|
||||
let factory = create_test_provider_factory();
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state());
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state);
|
||||
|
||||
let db = factory.provider().unwrap();
|
||||
let provider = HistoricalStateProviderRef::new(&db, 1);
|
||||
|
||||
@@ -54,7 +54,7 @@ impl<Provider: DBProvider + StorageSettingsCache> AccountReader
|
||||
{
|
||||
/// Get basic account information.
|
||||
fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
|
||||
if self.0.cached_storage_settings().use_hashed_state() {
|
||||
if self.0.cached_storage_settings().use_hashed_state {
|
||||
let hashed_address = alloy_primitives::keccak256(address);
|
||||
self.tx()
|
||||
.get_by_encoded_key::<tables::HashedAccounts>(&hashed_address)
|
||||
@@ -167,7 +167,7 @@ impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Pro
|
||||
|
||||
impl<Provider: DBProvider> HashedPostStateProvider for LatestStateProviderRef<'_, Provider> {
|
||||
fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> HashedPostState {
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(bundle_state.state())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ impl<Provider: DBProvider + BlockHashReader + StorageSettingsCache> StateProvide
|
||||
account: Address,
|
||||
storage_key: StorageKey,
|
||||
) -> ProviderResult<Option<StorageValue>> {
|
||||
if self.0.cached_storage_settings().use_hashed_state() {
|
||||
if self.0.cached_storage_settings().use_hashed_state {
|
||||
self.hashed_storage_lookup(
|
||||
alloy_primitives::keccak256(account),
|
||||
alloy_primitives::keccak256(storage_key),
|
||||
@@ -201,7 +201,7 @@ impl<Provider: DBProvider + BlockHashReader + StorageSettingsCache> StateProvide
|
||||
address: Address,
|
||||
hashed_storage_key: StorageKey,
|
||||
) -> ProviderResult<Option<StorageValue>> {
|
||||
if self.0.cached_storage_settings().use_hashed_state() {
|
||||
if self.0.cached_storage_settings().use_hashed_state {
|
||||
self.hashed_storage_lookup(alloy_primitives::keccak256(address), hashed_storage_key)
|
||||
} else {
|
||||
Err(ProviderError::UnsupportedProvider)
|
||||
@@ -321,7 +321,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_latest_storage_legacy() {
|
||||
let factory = create_test_provider_factory();
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state());
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state);
|
||||
|
||||
let address = address!("0x0000000000000000000000000000000000000001");
|
||||
let slot = b256!("0x0000000000000000000000000000000000000000000000000000000000000005");
|
||||
@@ -347,7 +347,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_latest_storage_legacy_does_not_read_hashed() {
|
||||
let factory = create_test_provider_factory();
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state());
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state);
|
||||
|
||||
let address = address!("0x0000000000000000000000000000000000000001");
|
||||
let slot = b256!("0x0000000000000000000000000000000000000000000000000000000000000005");
|
||||
@@ -400,7 +400,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_latest_storage_by_hashed_key_unsupported_in_v1() {
|
||||
let factory = create_test_provider_factory();
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state());
|
||||
assert!(!factory.provider().unwrap().cached_storage_settings().use_hashed_state);
|
||||
|
||||
let address = address!("0x0000000000000000000000000000000000000001");
|
||||
let slot = b256!("0x0000000000000000000000000000000000000000000000000000000000000001");
|
||||
|
||||
@@ -39,7 +39,7 @@ pub trait RocksDBProviderFactory {
|
||||
{
|
||||
#[cfg(all(unix, feature = "rocksdb"))]
|
||||
{
|
||||
if self.cached_storage_settings().storage_v2 {
|
||||
if self.cached_storage_settings().any_in_rocksdb() {
|
||||
let rocksdb = self.rocksdb_provider();
|
||||
let tx = rocksdb.tx();
|
||||
return f(Some(&tx));
|
||||
@@ -183,7 +183,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_rocksdb_settings_create_tx() {
|
||||
let settings = StorageSettings::v2();
|
||||
let settings =
|
||||
StorageSettings { account_history_in_rocksdb: true, ..StorageSettings::v1() };
|
||||
let provider = TestProvider::new(settings);
|
||||
|
||||
let result = provider.with_rocksdb_tx(|tx| {
|
||||
|
||||
@@ -16,15 +16,11 @@ pub trait MetadataProvider: Send {
|
||||
/// Get a metadata value by key
|
||||
fn get_metadata(&self, key: &str) -> ProviderResult<Option<Vec<u8>>>;
|
||||
|
||||
/// Get storage settings for this node.
|
||||
///
|
||||
/// If the stored metadata can't be deserialized (e.g. the format changed),
|
||||
/// this returns `None` instead of an error so commands like `db clear` can
|
||||
/// still operate without requiring a compatible metadata schema.
|
||||
/// Get storage settings for this node
|
||||
fn storage_settings(&self) -> ProviderResult<Option<StorageSettings>> {
|
||||
Ok(self
|
||||
.get_metadata(keys::STORAGE_SETTINGS)?
|
||||
.and_then(|bytes| serde_json::from_slice(&bytes).ok()))
|
||||
self.get_metadata(keys::STORAGE_SETTINGS)?
|
||||
.map(|bytes| serde_json::from_slice(&bytes).map_err(ProviderError::other))
|
||||
.transpose()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -816,17 +816,6 @@ impl RuntimeBuilder {
|
||||
let (task_manager, on_shutdown, task_events_tx, graceful_tasks) =
|
||||
TaskManager::new_parts(handle.clone());
|
||||
|
||||
#[cfg(feature = "rayon")]
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn rayon_panic_handler(payload: Box<dyn std::any::Any + Send>) {
|
||||
let msg = payload
|
||||
.downcast_ref::<&str>()
|
||||
.copied()
|
||||
.or_else(|| payload.downcast_ref::<String>().map(|s| s.as_str()))
|
||||
.unwrap_or("(no message)");
|
||||
error!(target: "reth::tasks", %msg, "panic in worker pool thread");
|
||||
}
|
||||
|
||||
#[cfg(feature = "rayon")]
|
||||
let (
|
||||
cpu_pool,
|
||||
@@ -864,7 +853,6 @@ impl RuntimeBuilder {
|
||||
let proof_storage_worker_pool = rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(proof_storage_worker_threads)
|
||||
.thread_name(|i| format!("proof-strg-{i:02}"))
|
||||
.panic_handler(rayon_panic_handler)
|
||||
.build()?;
|
||||
|
||||
let proof_account_worker_threads =
|
||||
@@ -872,7 +860,6 @@ impl RuntimeBuilder {
|
||||
let proof_account_worker_pool = rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(proof_account_worker_threads)
|
||||
.thread_name(|i| format!("proof-acct-{i:02}"))
|
||||
.panic_handler(rayon_panic_handler)
|
||||
.build()?;
|
||||
|
||||
debug!(
|
||||
|
||||
@@ -52,20 +52,7 @@ impl HashedPostState {
|
||||
) -> Self {
|
||||
state
|
||||
.into_par_iter()
|
||||
.map(|(address, account)| {
|
||||
let hashed_address = KH::hash_key(address);
|
||||
let hashed_account = account.info.as_ref().map(Into::into);
|
||||
let hashed_storage = HashedStorage::from_plain_storage(
|
||||
account.status,
|
||||
account.storage.iter().map(|(slot, value)| (slot, &value.present_value)),
|
||||
);
|
||||
|
||||
(
|
||||
hashed_address,
|
||||
hashed_account,
|
||||
(!hashed_storage.is_empty()).then_some(hashed_storage),
|
||||
)
|
||||
})
|
||||
.map(|(address, account)| Self::hash_bundle_account::<KH>(address, account))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -78,23 +65,57 @@ impl HashedPostState {
|
||||
) -> Self {
|
||||
state
|
||||
.into_iter()
|
||||
.map(|(address, account)| {
|
||||
let hashed_address = KH::hash_key(address);
|
||||
let hashed_account = account.info.as_ref().map(Into::into);
|
||||
let hashed_storage = HashedStorage::from_plain_storage(
|
||||
account.status,
|
||||
account.storage.iter().map(|(slot, value)| (slot, &value.present_value)),
|
||||
);
|
||||
|
||||
(
|
||||
hashed_address,
|
||||
hashed_account,
|
||||
(!hashed_storage.is_empty()).then_some(hashed_storage),
|
||||
)
|
||||
})
|
||||
.map(|(address, account)| Self::hash_bundle_account::<KH>(address, account))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Initialize [`HashedPostState`] from bundle state, choosing between sequential and parallel
|
||||
/// hashing based on the number of accounts.
|
||||
///
|
||||
/// For small account counts (≤ [`Self::ADAPTIVE_THRESHOLD`]), sequential iteration avoids
|
||||
/// rayon's fixed scheduling overhead, which can exceed the hashing work itself.
|
||||
#[cfg(feature = "rayon")]
|
||||
pub fn from_bundle_state_adaptive<KH: KeyHasher>(
|
||||
state: &HashMap<Address, BundleAccount>,
|
||||
) -> Self {
|
||||
if state.len() <= Self::ADAPTIVE_THRESHOLD {
|
||||
state
|
||||
.iter()
|
||||
.map(|(address, account)| Self::hash_bundle_account::<KH>(address, account))
|
||||
.collect()
|
||||
} else {
|
||||
let entries: Vec<_> = state.iter().collect();
|
||||
Self::from_bundle_state::<KH>(entries)
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize [`HashedPostState`] from bundle state sequentially (non-rayon fallback).
|
||||
#[cfg(not(feature = "rayon"))]
|
||||
pub fn from_bundle_state_adaptive<KH: KeyHasher>(
|
||||
state: &HashMap<Address, BundleAccount>,
|
||||
) -> Self {
|
||||
Self::from_bundle_state::<KH>(state)
|
||||
}
|
||||
|
||||
/// Account count at or below which sequential hashing outperforms rayon parallel iteration.
|
||||
#[cfg(feature = "rayon")]
|
||||
pub const ADAPTIVE_THRESHOLD: usize = 32;
|
||||
|
||||
/// Hashes a single bundle account entry into the tuple expected by [`FromIterator`].
|
||||
fn hash_bundle_account<KH: KeyHasher>(
|
||||
address: &Address,
|
||||
account: &BundleAccount,
|
||||
) -> (B256, Option<Account>, Option<HashedStorage>) {
|
||||
let hashed_address = KH::hash_key(address);
|
||||
let hashed_account = account.info.as_ref().map(Into::into);
|
||||
let hashed_storage = HashedStorage::from_plain_storage(
|
||||
account.status,
|
||||
account.storage.iter().map(|(slot, value)| (slot, &value.present_value)),
|
||||
);
|
||||
|
||||
(hashed_address, hashed_account, (!hashed_storage.is_empty()).then_some(hashed_storage))
|
||||
}
|
||||
|
||||
/// Construct [`HashedPostState`] from a single [`HashedStorage`].
|
||||
pub fn from_hashed_storage(hashed_address: B256, storage: HashedStorage) -> Self {
|
||||
Self {
|
||||
|
||||
@@ -528,12 +528,15 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn from_reverts_with_hashed_state() {
|
||||
use reth_db_api::models::{StorageBeforeTx, StorageSettings};
|
||||
use reth_db_api::models::StorageBeforeTx;
|
||||
use reth_provider::{StaticFileProviderFactory, StaticFileSegment, StaticFileWriter};
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
let mut settings = factory.cached_storage_settings();
|
||||
settings.use_hashed_state = true;
|
||||
settings.storage_changesets_in_static_files = true;
|
||||
factory.set_storage_settings_cache(settings);
|
||||
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
|
||||
@@ -545,32 +548,33 @@ mod tests {
|
||||
let hashed_slot1 = keccak256(plain_slot1);
|
||||
let hashed_slot2 = keccak256(plain_slot2);
|
||||
|
||||
{
|
||||
let sf = factory.static_file_provider();
|
||||
|
||||
// Write account changesets to static files (v2 reads from here)
|
||||
let mut aw = sf.latest_writer(StaticFileSegment::AccountChangeSets).unwrap();
|
||||
aw.append_account_changeset(vec![], 0).unwrap();
|
||||
aw.append_account_changeset(
|
||||
vec![AccountBeforeTx {
|
||||
provider
|
||||
.tx_ref()
|
||||
.put::<tables::AccountChangeSets>(
|
||||
1,
|
||||
AccountBeforeTx {
|
||||
address: address1,
|
||||
info: Some(Account { nonce: 1, ..Default::default() }),
|
||||
}],
|
||||
1,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
aw.append_account_changeset(
|
||||
vec![AccountBeforeTx {
|
||||
provider
|
||||
.tx_ref()
|
||||
.put::<tables::AccountChangeSets>(
|
||||
2,
|
||||
AccountBeforeTx {
|
||||
address: address1,
|
||||
info: Some(Account { nonce: 2, ..Default::default() }),
|
||||
}],
|
||||
2,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
aw.append_account_changeset(vec![AccountBeforeTx { address: address2, info: None }], 3)
|
||||
.unwrap();
|
||||
aw.commit().unwrap();
|
||||
provider
|
||||
.tx_ref()
|
||||
.put::<tables::AccountChangeSets>(3, AccountBeforeTx { address: address2, info: None })
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let sf = factory.static_file_provider();
|
||||
let mut writer = sf.latest_writer(StaticFileSegment::StorageChangeSets).unwrap();
|
||||
writer.append_storage_changeset(vec![], 0).unwrap();
|
||||
writer
|
||||
|
||||
@@ -149,7 +149,7 @@ mod tests {
|
||||
let factory = create_test_provider_factory();
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
|
||||
assert!(!provider.cached_storage_settings().use_hashed_state());
|
||||
assert!(!provider.cached_storage_settings().use_hashed_state);
|
||||
|
||||
let address = Address::with_last_byte(42);
|
||||
let slot1 = B256::from(U256::from(100));
|
||||
@@ -191,15 +191,18 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_hashed_storage_from_reverts_hashed_state() {
|
||||
use reth_db_api::models::{StorageBeforeTx, StorageSettings};
|
||||
use reth_db_api::models::StorageBeforeTx;
|
||||
|
||||
let factory = create_test_provider_factory();
|
||||
|
||||
factory.set_storage_settings_cache(StorageSettings::v2());
|
||||
let mut settings = factory.cached_storage_settings();
|
||||
settings.use_hashed_state = true;
|
||||
settings.storage_changesets_in_static_files = true;
|
||||
factory.set_storage_settings_cache(settings);
|
||||
|
||||
let provider = factory.provider_rw().unwrap();
|
||||
assert!(provider.cached_storage_settings().use_hashed_state());
|
||||
assert!(provider.cached_storage_settings().is_v2());
|
||||
assert!(provider.cached_storage_settings().use_hashed_state);
|
||||
assert!(provider.cached_storage_settings().storage_changesets_in_static_files);
|
||||
|
||||
let address = Address::with_last_byte(42);
|
||||
let plain_slot1 = B256::from(U256::from(100));
|
||||
|
||||
@@ -258,7 +258,7 @@ impl SparseTrie for ParallelSparseTrie {
|
||||
#[cfg(feature = "std")]
|
||||
// Reveal lower subtrie nodes in parallel
|
||||
{
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
|
||||
use tracing::Span;
|
||||
|
||||
// Capture the current span so it can be propagated to rayon worker threads
|
||||
@@ -267,39 +267,23 @@ impl SparseTrie for ParallelSparseTrie {
|
||||
// Capture reference to upper subtrie nodes for boundary leaf reachability checks
|
||||
let upper_nodes = &self.upper_subtrie.nodes;
|
||||
|
||||
// Group the nodes by lower subtrie.
|
||||
let results = lower_nodes
|
||||
// Group the nodes by lower subtrie. This must be collected into a Vec in order for
|
||||
// rayon's `zip` to be happy.
|
||||
let node_groups: Vec<_> = lower_nodes
|
||||
.chunk_by(|node_a, node_b| {
|
||||
SparseSubtrieType::from_path(&node_a.path) ==
|
||||
SparseSubtrieType::from_path(&node_b.path)
|
||||
})
|
||||
// Filter out chunks for unreachable subtries.
|
||||
.filter_map(|nodes| {
|
||||
let mut nodes = nodes
|
||||
.iter()
|
||||
.filter(|node| {
|
||||
// For boundary leaves, check reachability from upper subtrie's parent
|
||||
// branch.
|
||||
if node.path.len() == UPPER_TRIE_MAX_DEPTH &&
|
||||
!Self::is_boundary_leaf_reachable(
|
||||
upper_nodes,
|
||||
&node.path,
|
||||
&node.node,
|
||||
)
|
||||
{
|
||||
trace!(
|
||||
target: "trie::parallel_sparse",
|
||||
path = ?node.path,
|
||||
"Boundary leaf not reachable from upper subtrie, skipping",
|
||||
);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.peekable();
|
||||
.collect();
|
||||
|
||||
let node = nodes.peek()?;
|
||||
// Take the lower subtries in the same order that the nodes were grouped into, so that
|
||||
// the two can be zipped together. This also must be collected into a Vec for rayon's
|
||||
// `zip` to be happy.
|
||||
let lower_subtries: Vec<_> = node_groups
|
||||
.iter()
|
||||
.filter_map(|nodes| {
|
||||
// NOTE: chunk_by won't produce empty groups
|
||||
let node = &nodes[0];
|
||||
let idx =
|
||||
SparseSubtrieType::from_path(&node.path).lower_index().unwrap_or_else(
|
||||
|| panic!("upper subtrie node {node:?} found amongst lower nodes"),
|
||||
@@ -319,24 +303,41 @@ impl SparseTrie for ParallelSparseTrie {
|
||||
// shortest path being revealed for each subtrie. Therefore we can reveal the
|
||||
// subtrie itself using this path and retain correct behavior.
|
||||
self.lower_subtries[idx].reveal(&node.path);
|
||||
Some((
|
||||
idx,
|
||||
self.lower_subtries[idx].take_revealed().expect("just revealed"),
|
||||
nodes,
|
||||
))
|
||||
Some((idx, self.lower_subtries[idx].take_revealed().expect("just revealed")))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.collect();
|
||||
|
||||
// Zip the lower subtries and their corresponding node groups, and reveal lower subtrie
|
||||
// nodes in parallel
|
||||
let results: Vec<_> = lower_subtries
|
||||
.into_par_iter()
|
||||
.map(|(subtrie_idx, mut subtrie, nodes)| {
|
||||
.zip(node_groups.into_par_iter())
|
||||
.map(|((subtrie_idx, mut subtrie), nodes)| {
|
||||
// Enter the parent span to propagate context (e.g., hashed_address for storage
|
||||
// tries) to the worker thread
|
||||
let _guard = parent_span.enter();
|
||||
|
||||
// reserve space in the HashMap ahead of time; doing it on a node-by-node basis
|
||||
// can cause multiple re-allocations as the hashmap grows.
|
||||
subtrie.nodes.reserve(nodes.size_hint().1.unwrap_or(0));
|
||||
subtrie.nodes.reserve(nodes.len());
|
||||
|
||||
for node in nodes {
|
||||
// For boundary leaves, check reachability from upper subtrie's parent
|
||||
// branch
|
||||
if node.path.len() == UPPER_TRIE_MAX_DEPTH &&
|
||||
!Self::is_boundary_leaf_reachable(
|
||||
upper_nodes,
|
||||
&node.path,
|
||||
&node.node,
|
||||
)
|
||||
{
|
||||
trace!(
|
||||
target: "trie::parallel_sparse",
|
||||
path = ?node.path,
|
||||
"Boundary leaf not reachable from upper subtrie, skipping",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// Reveal each node in the subtrie, returning early on any errors
|
||||
let res = subtrie.reveal_node(node.path, &node.node, node.masks);
|
||||
if res.is_err() {
|
||||
@@ -345,7 +346,7 @@ impl SparseTrie for ParallelSparseTrie {
|
||||
}
|
||||
(subtrie_idx, subtrie, Ok(()))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.collect();
|
||||
|
||||
// Put subtries back which were processed in the rayon pool, collecting the last
|
||||
// seen error in the process and returning that.
|
||||
@@ -1957,7 +1958,6 @@ impl ParallelSparseTrie {
|
||||
}
|
||||
SparseTrieUpdatesAction::InsertUpdated(path, branch_node) => {
|
||||
updates.updated_nodes.insert(path, branch_node);
|
||||
updates.removed_nodes.remove(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ pub fn hash_post_state(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("Hash Post State");
|
||||
group.sample_size(20);
|
||||
|
||||
for size in [100, 1_000, 3_000, 5_000, 10_000] {
|
||||
for size in [10, 20, 32, 50, 100, 1_000, 3_000, 5_000, 10_000] {
|
||||
// Too slow.
|
||||
#[expect(unexpected_cfgs)]
|
||||
if cfg!(codspeed) && size > 1_000 {
|
||||
@@ -27,6 +27,13 @@ pub fn hash_post_state(c: &mut Criterion) {
|
||||
group.bench_function(BenchmarkId::new("parallel hashing", size), |b| {
|
||||
b.iter(|| HashedPostState::from_bundle_state::<KeccakKeyHasher>(&state))
|
||||
});
|
||||
|
||||
// adaptive
|
||||
let state_map: alloy_primitives::map::HashMap<Address, BundleAccount> =
|
||||
state.iter().map(|(k, v)| (*k, v.clone())).collect();
|
||||
group.bench_function(BenchmarkId::new("adaptive hashing", size), |b| {
|
||||
b.iter(|| HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(&state_map))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1282,16 +1282,6 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clears internal computation state. Called after errors to ensure the calculator is not
|
||||
/// left in a partially-computed state when reused.
|
||||
fn clear_computation_state(&mut self) {
|
||||
self.branch_stack.clear();
|
||||
self.branch_path = Nibbles::new();
|
||||
self.child_stack.clear();
|
||||
self.cached_branch_stack.clear();
|
||||
self.retained_proofs.clear();
|
||||
}
|
||||
|
||||
/// Internal implementation of proof calculation. Assumes both cursors have already been reset.
|
||||
/// See docs on [`Self::proof`] for expected behavior.
|
||||
fn proof_inner(
|
||||
@@ -1313,15 +1303,12 @@ where
|
||||
// Divide targets into chunks, each chunk corresponding to a different sub-trie within the
|
||||
// overall trie, and handle all proofs within that sub-trie.
|
||||
for sub_trie_targets in iter_sub_trie_targets(targets) {
|
||||
if let Err(err) = self.proof_subtrie(
|
||||
self.proof_subtrie(
|
||||
value_encoder,
|
||||
&mut trie_cursor_state,
|
||||
&mut hashed_cursor_current,
|
||||
sub_trie_targets,
|
||||
) {
|
||||
self.clear_computation_state();
|
||||
return Err(err);
|
||||
}
|
||||
)?;
|
||||
}
|
||||
|
||||
trace!(
|
||||
@@ -1391,15 +1378,12 @@ where
|
||||
let sub_trie_targets =
|
||||
SubTrieTargets { prefix: Nibbles::new(), targets: &EMPTY_TARGETS, retain_root: true };
|
||||
|
||||
if let Err(err) = self.proof_subtrie(
|
||||
self.proof_subtrie(
|
||||
value_encoder,
|
||||
&mut trie_cursor_state,
|
||||
&mut hashed_cursor_current,
|
||||
sub_trie_targets,
|
||||
) {
|
||||
self.clear_computation_state();
|
||||
return Err(err);
|
||||
}
|
||||
)?;
|
||||
|
||||
// proof_subtrie will retain the root node if retain_proof is true, regardless of if there
|
||||
// are any targets.
|
||||
@@ -1831,79 +1815,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests that `clear_computation_state` properly resets internal stacks, allowing a
|
||||
/// `ProofCalculator` to be reused after a mid-computation error left stale state.
|
||||
/// Before the fix, stale data in `branch_stack`, `child_stack`, and `branch_path`
|
||||
/// could cause a `usize` underflow panic in `pop_branch`.
|
||||
#[test]
|
||||
fn test_proof_calculator_reuse_after_error() {
|
||||
use alloy_primitives::U256;
|
||||
|
||||
reth_tracing::init_test_tracing();
|
||||
|
||||
let mut post_state = HashedPostState::default();
|
||||
let addresses = [
|
||||
B256::right_padding_from(&[0x10]),
|
||||
B256::right_padding_from(&[0x20]),
|
||||
B256::right_padding_from(&[0x30]),
|
||||
B256::right_padding_from(&[0x40]),
|
||||
];
|
||||
for addr in &addresses {
|
||||
let account =
|
||||
Account { nonce: 1, balance: U256::from(100u64), bytecode_hash: Some(B256::ZERO) };
|
||||
post_state.accounts.insert(*addr, Some(account));
|
||||
}
|
||||
|
||||
let harness = ProofTestHarness::new(post_state);
|
||||
|
||||
let trie_cursor = harness.trie_cursor_factory.account_trie_cursor().unwrap();
|
||||
let hashed_cursor = harness.hashed_cursor_factory.hashed_account_cursor().unwrap();
|
||||
let mut proof_calculator = ProofCalculator::new(trie_cursor, hashed_cursor);
|
||||
|
||||
// Simulate stale state left by a mid-computation error: push fake entries onto internal
|
||||
// stacks and set a non-empty branch_path.
|
||||
proof_calculator.branch_stack.push(ProofTrieBranch {
|
||||
ext_len: 2,
|
||||
state_mask: TrieMask::new(0b1111),
|
||||
masks: None,
|
||||
});
|
||||
proof_calculator.branch_stack.push(ProofTrieBranch {
|
||||
ext_len: 0,
|
||||
state_mask: TrieMask::new(0b11),
|
||||
masks: None,
|
||||
});
|
||||
proof_calculator
|
||||
.child_stack
|
||||
.push(ProofTrieBranchChild::RlpNode(RlpNode::word_rlp(&B256::ZERO)));
|
||||
proof_calculator.branch_path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
|
||||
|
||||
// clear_computation_state should reset everything so a subsequent proof() call works.
|
||||
proof_calculator.clear_computation_state();
|
||||
|
||||
let mut value_encoder = SyncAccountValueEncoder::new(
|
||||
harness.trie_cursor_factory.clone(),
|
||||
harness.hashed_cursor_factory.clone(),
|
||||
);
|
||||
let mut sorted_addresses = addresses.to_vec();
|
||||
sorted_addresses.sort();
|
||||
let mut targets: Vec<ProofV2Target> =
|
||||
sorted_addresses.iter().copied().map(ProofV2Target::new).collect();
|
||||
|
||||
let result = proof_calculator.proof(&mut value_encoder, &mut targets).unwrap();
|
||||
|
||||
// Compare against a fresh calculator to verify correctness.
|
||||
let trie_cursor = harness.trie_cursor_factory.account_trie_cursor().unwrap();
|
||||
let hashed_cursor = harness.hashed_cursor_factory.hashed_account_cursor().unwrap();
|
||||
let mut fresh_calculator = ProofCalculator::new(trie_cursor, hashed_cursor);
|
||||
let mut value_encoder = SyncAccountValueEncoder::new(
|
||||
harness.trie_cursor_factory.clone(),
|
||||
harness.hashed_cursor_factory,
|
||||
);
|
||||
let fresh_result = fresh_calculator.proof(&mut value_encoder, &mut targets).unwrap();
|
||||
|
||||
pretty_assertions::assert_eq!(fresh_result, result);
|
||||
}
|
||||
|
||||
mod proptest_tests {
|
||||
use super::*;
|
||||
use alloy_primitives::{map::B256Map, U256};
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
- [`reth db checksum mdbx`](./reth/db/checksum/mdbx.mdx)
|
||||
- [`reth db checksum static-file`](./reth/db/checksum/static-file.mdx)
|
||||
- [`reth db checksum rocksdb`](./reth/db/checksum/rocksdb.mdx)
|
||||
- [`reth db copy`](./reth/db/copy.mdx)
|
||||
- [`reth db diff`](./reth/db/diff.mdx)
|
||||
- [`reth db get`](./reth/db/get.mdx)
|
||||
- [`reth db get mdbx`](./reth/db/get/mdbx.mdx)
|
||||
@@ -31,7 +30,14 @@
|
||||
- [`reth db settings`](./reth/db/settings.mdx)
|
||||
- [`reth db settings get`](./reth/db/settings/get.mdx)
|
||||
- [`reth db settings set`](./reth/db/settings/set.mdx)
|
||||
- [`reth db settings set v2`](./reth/db/settings/set/v2.mdx)
|
||||
- [`reth db settings set receipts`](./reth/db/settings/set/receipts.mdx)
|
||||
- [`reth db settings set transaction_senders`](./reth/db/settings/set/transaction_senders.mdx)
|
||||
- [`reth db settings set account_changesets`](./reth/db/settings/set/account_changesets.mdx)
|
||||
- [`reth db settings set storages_history`](./reth/db/settings/set/storages_history.mdx)
|
||||
- [`reth db settings set transaction_hash_numbers`](./reth/db/settings/set/transaction_hash_numbers.mdx)
|
||||
- [`reth db settings set account_history`](./reth/db/settings/set/account_history.mdx)
|
||||
- [`reth db settings set storage_changesets`](./reth/db/settings/set/storage_changesets.mdx)
|
||||
- [`reth db settings set use_hashed_state`](./reth/db/settings/set/use_hashed_state.mdx)
|
||||
- [`reth db account-storage`](./reth/db/account-storage.mdx)
|
||||
- [`reth db state`](./reth/db/state.mdx)
|
||||
- [`reth download`](./reth/download.mdx)
|
||||
|
||||
@@ -12,7 +12,6 @@ Commands:
|
||||
stats Lists all the tables, their entry count and their size
|
||||
list Lists the contents of a table
|
||||
checksum Calculates the content checksum of a table or static file segment
|
||||
copy Copies the MDBX database to a new location (bundled mdbx_copy)
|
||||
diff Create a diff between two database tables or two entire databases
|
||||
get Gets the content of a table for the given key
|
||||
drop Deletes all database entries
|
||||
@@ -129,6 +128,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -139,6 +209,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
# reth db copy
|
||||
|
||||
Copies the MDBX database to a new location (bundled mdbx_copy)
|
||||
|
||||
```bash
|
||||
$ reth db copy --help
|
||||
```
|
||||
```txt
|
||||
Usage: reth db copy [OPTIONS] <DEST>
|
||||
|
||||
Arguments:
|
||||
<DEST>
|
||||
Destination path for the database copy
|
||||
|
||||
Options:
|
||||
-c, --compact
|
||||
Compact the database while copying (reclaims free space)
|
||||
|
||||
-d, --force-dynamic-size
|
||||
Force dynamic size for the destination database
|
||||
|
||||
-p, --throttle-mvcc
|
||||
Throttle to avoid MVCC pressure on writers
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
Datadir:
|
||||
--chain <CHAIN_OR_PATH>
|
||||
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, sepolia, holesky, hoodi, dev
|
||||
|
||||
[default: mainnet]
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
[default: terminal]
|
||||
|
||||
--log.stdout.filter <FILTER>
|
||||
The filter to use for logs written to stdout
|
||||
|
||||
[default: ]
|
||||
|
||||
--log.file.format <FORMAT>
|
||||
The format to use for logs written to the log file
|
||||
|
||||
Possible values:
|
||||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging
|
||||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications
|
||||
- terminal: Represents terminal-friendly formatting for logs
|
||||
|
||||
[default: terminal]
|
||||
|
||||
--log.file.filter <FILTER>
|
||||
The filter to use for logs written to the log file
|
||||
|
||||
[default: debug]
|
||||
|
||||
--log.file.directory <PATH>
|
||||
The path to put log files in
|
||||
|
||||
[default: <CACHE_DIR>/logs]
|
||||
|
||||
--log.file.name <NAME>
|
||||
The prefix name of the log files
|
||||
|
||||
[default: reth.log]
|
||||
|
||||
--log.file.max-size <SIZE>
|
||||
The maximum size (in MB) of one log file
|
||||
|
||||
[default: 200]
|
||||
|
||||
--log.file.max-files <COUNT>
|
||||
The maximum amount of log files that will be stored. If set to 0, background file logging is disabled
|
||||
|
||||
[default: 5]
|
||||
|
||||
--log.journald
|
||||
Write logs to journald
|
||||
|
||||
--log.journald.filter <FILTER>
|
||||
The filter to use for logs written to journald
|
||||
|
||||
[default: error]
|
||||
|
||||
--color <COLOR>
|
||||
Sets whether or not the formatter emits ANSI terminal escape codes for colors and other text formatting
|
||||
|
||||
Possible values:
|
||||
- always: Colors on
|
||||
- auto: Auto-detect
|
||||
- never: Colors off
|
||||
|
||||
[default: always]
|
||||
|
||||
--logs-otlp[=<URL>]
|
||||
Enable `Opentelemetry` logs export to an OTLP endpoint.
|
||||
|
||||
If no value provided, defaults based on protocol: - HTTP: `http://localhost:4318/v1/logs` - gRPC: `http://localhost:4317`
|
||||
|
||||
Example: --logs-otlp=http://collector:4318/v1/logs
|
||||
|
||||
[env: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=]
|
||||
|
||||
--logs-otlp.filter <FILTER>
|
||||
Set a filter directive for the OTLP logs exporter. This controls the verbosity of logs sent to the OTLP endpoint. It follows the same syntax as the `RUST_LOG` environment variable.
|
||||
|
||||
Example: --logs-otlp.filter=info,reth=debug
|
||||
|
||||
Defaults to INFO if not specified.
|
||||
|
||||
[default: info]
|
||||
|
||||
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
|
||||
|
||||
Tracing:
|
||||
--tracing-otlp[=<URL>]
|
||||
Enable `Opentelemetry` tracing export to an OTLP endpoint.
|
||||
|
||||
If no value provided, defaults based on protocol: - HTTP: `http://localhost:4318/v1/traces` - gRPC: `http://localhost:4317`
|
||||
|
||||
Example: --tracing-otlp=http://collector:4318/v1/traces
|
||||
|
||||
[env: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=]
|
||||
|
||||
--tracing-otlp-protocol <PROTOCOL>
|
||||
OTLP transport protocol to use for exporting traces and logs.
|
||||
|
||||
- `http`: expects endpoint path to end with `/v1/traces` or `/v1/logs` - `grpc`: expects endpoint without a path
|
||||
|
||||
Defaults to HTTP if not specified.
|
||||
|
||||
Possible values:
|
||||
- http: HTTP/Protobuf transport, port 4318, requires `/v1/traces` path
|
||||
- grpc: gRPC transport, port 4317
|
||||
|
||||
[env: OTEL_EXPORTER_OTLP_PROTOCOL=]
|
||||
[default: http]
|
||||
|
||||
--tracing-otlp.filter <FILTER>
|
||||
Set a filter directive for the OTLP tracer. This controls the verbosity of spans and events sent to the OTLP endpoint. It follows the same syntax as the `RUST_LOG` environment variable.
|
||||
|
||||
Example: --tracing-otlp.filter=info,reth=debug,hyper_util=off
|
||||
|
||||
Defaults to TRACE if not specified.
|
||||
|
||||
[default: debug]
|
||||
|
||||
--tracing-otlp.sample-ratio <RATIO>
|
||||
Trace sampling ratio to control the percentage of traces to export.
|
||||
|
||||
Valid range: 0.0 to 1.0 - 1.0, default: Sample all traces - 0.01: Sample 1% of traces - 0.0: Disable sampling
|
||||
|
||||
Example: --tracing-otlp.sample-ratio=0.0.
|
||||
|
||||
[env: OTEL_TRACES_SAMPLER_ARG=]
|
||||
```
|
||||
@@ -9,8 +9,15 @@ $ reth db settings set --help
|
||||
Usage: reth db settings set [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
v2 Enable or disable v2 storage layout
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
receipts Store receipts in static files instead of the database
|
||||
transaction_senders Store transaction senders in static files instead of the database
|
||||
account_changesets Store account changesets in static files instead of the database
|
||||
storages_history Store storage history in rocksdb instead of MDBX
|
||||
transaction_hash_numbers Store transaction hash to number mapping in rocksdb instead of MDBX
|
||||
account_history Store account history in rocksdb instead of MDBX
|
||||
storage_changesets Store storage changesets in static files instead of the database
|
||||
use_hashed_state Use hashed state tables (HashedAccounts/HashedStorages) as canonical state
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# reth db settings set v2
|
||||
# reth db settings set account_changesets_in_static_files
|
||||
|
||||
Enable or disable v2 storage layout
|
||||
Store account changesets in static files instead of the database
|
||||
|
||||
```bash
|
||||
$ reth db settings set v2 --help
|
||||
$ reth db settings set account_changesets_in_static_files --help
|
||||
```
|
||||
```txt
|
||||
Usage: reth db settings set v2 [OPTIONS] <VALUE>
|
||||
Usage: reth db settings set account_changesets_in_static_files [OPTIONS] <VALUE>
|
||||
|
||||
Arguments:
|
||||
<VALUE>
|
||||
@@ -95,24 +95,6 @@ Logging:
|
||||
|
||||
[default: always]
|
||||
|
||||
--logs-otlp[=<URL>]
|
||||
Enable `Opentelemetry` logs export to an OTLP endpoint.
|
||||
|
||||
If no value provided, defaults based on protocol: - HTTP: `http://localhost:4318/v1/logs` - gRPC: `http://localhost:4317`
|
||||
|
||||
Example: --logs-otlp=http://collector:4318/v1/logs
|
||||
|
||||
[env: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=]
|
||||
|
||||
--logs-otlp.filter <FILTER>
|
||||
Set a filter directive for the OTLP logs exporter. This controls the verbosity of logs sent to the OTLP endpoint. It follows the same syntax as the `RUST_LOG` environment variable.
|
||||
|
||||
Example: --logs-otlp.filter=info,reth=debug
|
||||
|
||||
Defaults to INFO if not specified.
|
||||
|
||||
[default: info]
|
||||
|
||||
Display:
|
||||
-v, --verbosity...
|
||||
Set the minimum log level.
|
||||
@@ -137,9 +119,9 @@ Tracing:
|
||||
[env: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=]
|
||||
|
||||
--tracing-otlp-protocol <PROTOCOL>
|
||||
OTLP transport protocol to use for exporting traces and logs.
|
||||
OTLP transport protocol to use for exporting traces.
|
||||
|
||||
- `http`: expects endpoint path to end with `/v1/traces` or `/v1/logs` - `grpc`: expects endpoint without a path
|
||||
- `http`: expects endpoint path to end with `/v1/traces` - `grpc`: expects endpoint without a path
|
||||
|
||||
Defaults to HTTP if not specified.
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
-u, --url <URL>
|
||||
Specify a snapshot URL or let the command propose a default one.
|
||||
|
||||
@@ -128,7 +206,7 @@ Storage:
|
||||
- https://www.merkle.io/snapshots (default, mainnet archive)
|
||||
- https://publicnode.com/snapshots (full nodes & testnets)
|
||||
|
||||
If no URL is provided, the latest archive snapshot for the selected chain
|
||||
If no URL is provided, the latest mainnet archive snapshot
|
||||
will be proposed for download from https://downloads.merkle.io.
|
||||
|
||||
Local file:// URLs are also supported for extracting snapshots from disk.
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--first-block-number <first-block-number>
|
||||
Optional first block number to export from the db.
|
||||
It is by default 0.
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--path <IMPORT_ERA_PATH>
|
||||
The path to a directory for import.
|
||||
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--no-state
|
||||
Disables stages that require state.
|
||||
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--without-evm
|
||||
Specifies whether to initialize the state without relying on EVM historical data.
|
||||
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
@@ -912,6 +912,33 @@ Pruning:
|
||||
--prune.bodies.before <BLOCK_NUMBER>
|
||||
Prune storage history before the specified block number. The specified block number is not pruned
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Engine:
|
||||
--engine.persistence-threshold <PERSISTENCE_THRESHOLD>
|
||||
Configure persistence threshold for the engine. This determines how many canonical blocks must be in-memory, ahead of the last persisted block, before flushing canonical blocks to disk again.
|
||||
@@ -1046,6 +1073,50 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -1056,6 +1127,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
Metrics:
|
||||
--metrics <PROMETHEUS>
|
||||
Enable Prometheus metrics.
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--from <FROM>
|
||||
The height to start at
|
||||
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
<STAGE>
|
||||
Possible values:
|
||||
- headers: The headers stage within the pipeline
|
||||
|
||||
@@ -118,6 +118,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -128,6 +199,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
Logging:
|
||||
--log.stdout.format <FORMAT>
|
||||
The format to use for logs written to stdout
|
||||
|
||||
@@ -111,6 +111,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -121,6 +192,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--metrics <SOCKET>
|
||||
Enable Prometheus metrics.
|
||||
|
||||
|
||||
@@ -116,6 +116,77 @@ Static Files:
|
||||
--static-files.blocks-per-file.storage-change-sets <BLOCKS_PER_FILE_STORAGE_CHANGE_SETS>
|
||||
Number of blocks per file for the storage changesets segment
|
||||
|
||||
--static-files.receipts <RECEIPTS>
|
||||
Store receipts in static files instead of the database.
|
||||
|
||||
When enabled, receipts will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.transaction-senders <TRANSACTION_SENDERS>
|
||||
Store transaction senders in static files instead of the database.
|
||||
|
||||
When enabled, transaction senders will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.account-change-sets <ACCOUNT_CHANGESETS>
|
||||
Store account changesets in static files.
|
||||
|
||||
When enabled, account changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--static-files.storage-change-sets <STORAGE_CHANGESETS>
|
||||
Store storage changesets in static files.
|
||||
|
||||
When enabled, storage changesets will be written to static files on disk instead of the database.
|
||||
|
||||
Note: This setting can only be configured at genesis initialization. Once the node has been initialized, changing this flag requires re-syncing from scratch.
|
||||
|
||||
Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
RocksDB:
|
||||
--rocksdb.all
|
||||
Route all supported tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
|
||||
|
||||
--rocksdb.tx-hash <TX_HASH>
|
||||
Route tx hash -> number table to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.storages-history <STORAGES_HISTORY>
|
||||
Route storages history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
--rocksdb.account-history <ACCOUNT_HISTORY>
|
||||
Route account history tables to `RocksDB` instead of MDBX.
|
||||
|
||||
This is a genesis-initialization-only flag: changing it after genesis requires a re-sync. Defaults to the base storage mode (v1: false, v2: true).
|
||||
|
||||
[possible values: true, false]
|
||||
|
||||
Storage:
|
||||
--storage.v2
|
||||
Enable v2 storage defaults (static files + `RocksDB` routing).
|
||||
@@ -126,6 +197,13 @@ Storage:
|
||||
|
||||
Individual settings can still be overridden with `--static-files.*` and `--rocksdb.*` flags.
|
||||
|
||||
--storage.use-hashed-state
|
||||
Use hashed state tables (`HashedAccounts`/`HashedStorages`) as canonical state representation instead of plain state tables.
|
||||
|
||||
When enabled, execution writes directly to hashed tables, eliminating the need for separate hashing stages. This should only be enabled for new databases.
|
||||
|
||||
WARNING: Changing this setting on an existing database requires a full resync.
|
||||
|
||||
--offline
|
||||
If this is enabled, then all stages except headers, bodies, and sender recovery will be unwound
|
||||
|
||||
|
||||
@@ -10,19 +10,21 @@ Reth is production ready, and suitable for usage in mission-critical environment
|
||||
|
||||

|
||||
|
||||
## What is Reth?
|
||||
## What is this about?
|
||||
|
||||
[Reth](https://github.com/paradigmxyz/reth/) is an execution layer (EL) implementation that is compatible with all Ethereum consensus layer (CL) implementations that support the [Engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine).
|
||||
[Reth](https://github.com/paradigmxyz/reth/) is an execution layer (EL) implementation that is compatible with all Ethereum consensus layer (CL) implementations that support the [Engine API](https://github.com/ethereum/execution-apis/tree/59e3a719021f48c1ef5653840e3ea5750e6af693/src/engine).
|
||||
|
||||
It is originally built and driven forward by [Paradigm](https://paradigm.xyz/), and is licensed under the Apache and MIT licenses.
|
||||
|
||||
As a full Ethereum node, Reth allows users to connect to the Ethereum network and interact with the Ethereum blockchain. This includes sending and receiving transactions, querying logs and traces, as well as accessing and interacting with smart contracts.
|
||||
As a full Ethereum node, Reth allows users to connect to the Ethereum network and interact with the Ethereum blockchain.
|
||||
|
||||
## Goals
|
||||
This includes sending and receiving transactions, querying logs and traces, as well as accessing and interacting with smart contracts.
|
||||
|
||||
Building a successful Ethereum node requires creating a high-quality implementation that is both secure and efficient, as well as being easy to use on consumer hardware. It also requires building a strong community of contributors who can help support and improve the software.
|
||||
|
||||
### Modularity
|
||||
## What are the goals of Reth?
|
||||
|
||||
**1. Modularity**
|
||||
|
||||
Every component of Reth is built to be used as a library: well-tested, heavily documented and benchmarked. We envision that developers will import the node's crates, mix and match, and innovate on top of them.
|
||||
|
||||
@@ -30,23 +32,23 @@ Examples of such usage include, but are not limited to, spinning up standalone P
|
||||
|
||||
To achieve that, we are licensing Reth under the Apache/MIT permissive license.
|
||||
|
||||
### Performance
|
||||
**2. Performance**
|
||||
|
||||
Reth aims to be fast, so we used Rust and the [Erigon staged-sync](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) node architecture.
|
||||
|
||||
We also use our Ethereum libraries (including [Alloy](https://github.com/alloy-rs/alloy/) and [revm](https://github.com/bluealloy/revm/)) which we've battle-tested and optimized via [Foundry](https://github.com/foundry-rs/foundry/).
|
||||
We also use our Ethereum libraries (including [Alloy](https://github.com/alloy-rs/alloy/) and [revm](https://github.com/bluealloy/revm/)) which we’ve battle-tested and optimized via [Foundry](https://github.com/foundry-rs/foundry/).
|
||||
|
||||
### Free for anyone to use any way they want
|
||||
**3. Free for anyone to use any way they want**
|
||||
|
||||
Reth is free open-source software, built for the community, by the community.
|
||||
|
||||
By licensing the software under the Apache/MIT license, we want developers to use it without being bound by business licenses, or having to think about the implications of GPL-like licenses.
|
||||
|
||||
### Client Diversity
|
||||
**4. Client Diversity**
|
||||
|
||||
The Ethereum protocol becomes more antifragile when no node implementation dominates. This ensures that if there's a software bug, the network does not finalize a bad block. By building a new client, we hope to contribute to Ethereum's antifragility.
|
||||
|
||||
### Used by a wide demographic
|
||||
**5. Used by a wide demographic**
|
||||
|
||||
We want to solve for node operators that care about fast historical queries, but also for hobbyists who cannot operate on large hardware.
|
||||
|
||||
@@ -58,8 +60,8 @@ We envision that Reth will be configurable enough for the tradeoffs that each te
|
||||
|
||||
Reth is a new Ethereum full node that allows users to sync and interact with the entire blockchain, including its historical state if in archive mode.
|
||||
|
||||
- **Full node**: Stores and processes the entire blockchain, validates blocks and transactions, and participates in the consensus process.
|
||||
- **Archive node**: Stores the entire history of the blockchain and is useful for applications that need access to historical data.
|
||||
- Full node: It can be used as a full node, which stores and processes the entire blockchain, validates blocks and transactions, and participates in the consensus process.
|
||||
- Archive node: It can also be used as an archive node, which stores the entire history of the blockchain and is useful for applications that need access to historical data.
|
||||
|
||||
As a data engineer/analyst, or as a data indexer, you'll want to use Archive mode. For all other use cases where historical access is not needed, you can use Full mode.
|
||||
|
||||
@@ -75,7 +77,7 @@ Reth implements the specification of Ethereum as defined in the [ethereum/execut
|
||||
|
||||
We have completed an audit of the [Reth v1.0.0-rc.2](https://github.com/paradigmxyz/reth/releases/tag/v1.0.0-rc.2) with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](https://github.com/paradigmxyz/reth/blob/main/audit/sigma_prime_audit_v2.pdf).
|
||||
|
||||
[Revm](https://github.com/bluealloy/revm) (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)).
|
||||
[Revm](https://github.com/bluealloy/revm) (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)). We will publish the results soon.
|
||||
|
||||
## Reth Metrics
|
||||
|
||||
@@ -92,18 +94,21 @@ We operate several public Reth nodes across different networks. You can monitor
|
||||
Want to set up metrics for your own Reth node? Check out our [monitoring guide](/run/monitoring) to learn how to configure Prometheus metrics and build your own dashboards.
|
||||
:::
|
||||
|
||||
## Get started
|
||||
## Sections
|
||||
|
||||
- [Install Reth](/installation/overview) and get up and running.
|
||||
- [Run a node](/run/overview) on any official network.
|
||||
- [Monitor your node](/run/monitoring) with statistics and metrics.
|
||||
- [Query the JSON-RPC](/jsonrpc/intro) using Foundry's `cast` or `curl`.
|
||||
- [Explore the SDK](/sdk) to build custom blockchain infrastructure.
|
||||
- [Set up your development environment and contribute](/introduction/contributing)!
|
||||
Here are some useful sections to jump to:
|
||||
|
||||
- Install Reth by following the [guide](/installation/overview).
|
||||
- Sync your node on any [official network](/run/overview).
|
||||
- View [statistics and metrics](/run/monitoring) about your node.
|
||||
- Query the [JSON-RPC](/jsonrpc/intro) using Foundry's `cast` or `curl`.
|
||||
- Set up your [development environment and contribute](/introduction/contributing)!
|
||||
|
||||
:::note
|
||||
The documentation is continuously rendered [here](https://reth.rs)!
|
||||
You can contribute to the docs on [GitHub][gh-docs].
|
||||
:::
|
||||
|
||||
[tg-badge]: https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fparadigm%5Freth
|
||||
[tg-url]: https://t.me/paradigm_reth
|
||||
[gh-docs]: https://github.com/paradigmxyz/reth/tree/main/docs
|
||||
|
||||
@@ -65,10 +65,6 @@ export const rethCliSidebar: SidebarItem = {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "reth db copy",
|
||||
link: "/cli/reth/db/copy"
|
||||
},
|
||||
{
|
||||
text: "reth db diff",
|
||||
link: "/cli/reth/db/diff"
|
||||
@@ -149,8 +145,36 @@ export const rethCliSidebar: SidebarItem = {
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "reth db settings set v2",
|
||||
link: "/cli/reth/db/settings/set/v2"
|
||||
text: "reth db settings set receipts",
|
||||
link: "/cli/reth/db/settings/set/receipts"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set transaction_senders",
|
||||
link: "/cli/reth/db/settings/set/transaction_senders"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set account_changesets",
|
||||
link: "/cli/reth/db/settings/set/account_changesets"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set storages_history",
|
||||
link: "/cli/reth/db/settings/set/storages_history"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set transaction_hash_numbers",
|
||||
link: "/cli/reth/db/settings/set/transaction_hash_numbers"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set account_history",
|
||||
link: "/cli/reth/db/settings/set/account_history"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set storage_changesets",
|
||||
link: "/cli/reth/db/settings/set/storage_changesets"
|
||||
},
|
||||
{
|
||||
text: "reth db settings set use_hashed_state",
|
||||
link: "/cli/reth/db/settings/set/use_hashed_state"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export default defineConfig({
|
||||
},
|
||||
{ text: 'GitHub', link: 'https://github.com/paradigmxyz/reth' },
|
||||
{
|
||||
text: 'v1.11.3',
|
||||
text: 'v1.10.2',
|
||||
items: [
|
||||
{
|
||||
text: 'Releases',
|
||||
|
||||
@@ -257,7 +257,7 @@ fn run_case(case: &BlockchainTest) -> Result<(), Error> {
|
||||
|
||||
// Compute and check the post state root
|
||||
let hashed_state =
|
||||
HashedPostState::from_bundle_state::<KeccakKeyHasher>(output.state.state());
|
||||
HashedPostState::from_bundle_state_adaptive::<KeccakKeyHasher>(output.state.state());
|
||||
let (computed_state_root, _) = StateRoot::overlay_root_with_updates(
|
||||
provider.tx_ref(),
|
||||
&hashed_state.clone_into_sorted(),
|
||||
|
||||
Reference in New Issue
Block a user