Compare commits

...

849 Commits

Author SHA1 Message Date
Matthias Seitz
9c30bf7af5 chore: bump alloy 1.0.37 (#18795) 2025-09-30 15:29:51 +01:00
Tim
8950b4eb1e chore: bump version to 1.8.2 (#18792)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-30 15:03:40 +01:00
Delweng
1de013b21f fix(rpc/engine): check osaka in getBlobsV1 (#18669)
Signed-off-by: Delweng <delweng@gmail.com>
2025-09-30 14:57:37 +01:00
Matthias Seitz
95897e21b8 fix: remove cancun check (#18787) 2025-09-30 14:50:33 +01:00
nethoxa
12794769c1 fix(rpc): fix eth_config impl (#18744)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-30 14:50:27 +01:00
Mablr
611c307213 feat: make more EVM and RPC conversions fallible (#18685) 2025-09-30 14:50:23 +01:00
YK
994d73edf6 chore: bump rust to edition 2024 (#18692) 2025-09-30 14:50:22 +01:00
Matthias Seitz
e6608be51e chore: release 1.8.1 (#18646) 2025-09-23 17:41:38 +02:00
Matthias Seitz
44aa0fbb0e fix: Revert "chore: disable fee charge in env" (#18645) 2025-09-23 17:40:40 +02:00
dependabot[bot]
6fdf6c4492 chore(deps): bump CodSpeedHQ/action from 3 to 4 (#18333)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-23 14:07:44 +00:00
Tim
e613ee9e85 chore: update voc.config.to text to v1.8.0 (#18644) 2025-09-23 14:07:29 +00:00
Tim
132f5b5204 chore: update version to 1.8.0 in Cargo.toml (#18638)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-23 13:48:38 +00:00
Matthias Seitz
faaebe7f6d fix: check request gas limit before (#18639) 2025-09-23 12:21:59 +00:00
YK
088a0d44c2 chore(observability): add tokio runtime with custom thread naming (#18635)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-09-23 12:05:35 +00:00
Tim
4c9942b920 docs: update dashboard table and rpc urls (#18637) 2025-09-23 12:01:19 +00:00
Matthias Seitz
70a8c06773 feat: add osaka+bpo timestamps (#18627)
Co-authored-by: Brian Picciano <me@mediocregopher.com>
2025-09-23 11:06:52 +00:00
Matthias Seitz
ee834fb892 chore: disable fee charge in env (#18634) 2025-09-23 13:01:20 +02:00
Matthias Seitz
f225751c12 chore: bump inspectors 0.30 (#18633) 2025-09-23 13:01:08 +02:00
YK
7dc3aea930 chore(revert): revert tokio runtime with custom thread naming (#18631) 2025-09-23 10:20:44 +00:00
Matthias Seitz
87c75b9836 chore: bump deps (#18630) 2025-09-23 10:03:07 +00:00
YK
2ec3671633 chore(observability): add tokio runtime with custom thread naming (#18623) 2025-09-23 09:04:54 +00:00
MozirDmitriy
b27a927413 chore(primitive-traits): remove redundant auto-trait bounds from FullNodePrimitives (#18626)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-23 09:03:12 +00:00
Dmitry
e3cc6e2ea5 docs: fix incorrect RPC method names in trace calls (#18619) 2025-09-23 07:56:11 +00:00
Andrea Simeoni
dfab5f9646 fix(cli): bootnode default address (#18617) 2025-09-22 20:19:40 +00:00
Galoretka
87078e9205 fix(primitives-traits): simplify Rayon bounds and fix docs (#18620) 2025-09-22 19:48:10 +00:00
josé v
9e3246e695 chore: specialize send_raw_transaction_sync for op-reth with flashblocks support (#18586)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-22 13:43:57 +00:00
VolodymyrBg
60658be734 fix(handshake): validate peer TD from their_status_message during eth handshake (#18611) 2025-09-22 13:33:55 +02:00
Matthias Seitz
0bd2097995 chore: enforce max tx gas limit on estimate and accesslit (#18612) 2025-09-22 13:04:26 +02:00
Matthias Seitz
39d5563ce8 fix: disable block gas limit (#18583) 2025-09-22 10:07:03 +00:00
Brian Picciano
79c71b8692 chore: Remove reth recover storage-tries sub-command (#18580) 2025-09-22 10:04:40 +00:00
emmmm
9806e07cf8 fix: replace tx_hash method with TxHashRef trait bound (#18357) (#18362)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-22 09:31:17 +00:00
Matthias Seitz
3ebfd7a25e test: add test case for op tx env conversion (#18581) 2025-09-22 11:39:28 +02:00
YK
36107c60ab fix(cache): Ensure execution cache remains locked until updated (#18564)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-09-22 11:38:02 +02:00
YK
95f1931c59 test(engine): add new payload handling tests for canonical insertion and invalid ancestors (#18608) 2025-09-22 08:38:53 +00:00
crStiv
4ddf3ddb45 docs: multiple small textual defects (#18598) 2025-09-21 08:36:24 +00:00
github-actions[bot]
aeb6eddba0 chore(deps): weekly cargo update (#18600)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-21 07:37:18 +00:00
Federico Gimenez
ff59089094 chore(ci): unpin teku image for kurtosis-op (#18595) 2025-09-20 13:59:01 +00:00
Federico Gimenez
aead6c17c5 chore(ci): update expected and ignored hive tests (#18594) 2025-09-20 13:58:41 +00:00
Hai | RISE
55cbefe836 perf(persistence): lookup segment operation once (#18588) 2025-09-20 07:22:31 +00:00
William Nwoke
3655dc7f09 feat(rpc): make send_raw_transaction_sync timeout configurable (#18558)
Co-authored-by: Nathaniel Bajo <nathanielbajo@Nathaniels-MacBook-Pro.local>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-20 05:50:56 +00:00
Matthias Seitz
379db45b40 fix: use timestamp derived max blob count on launch (#18590) 2025-09-20 05:41:56 +00:00
VolodymyrBg
fa531761c4 chore(payload-builder): relax Sync bounds on resolve futures (#18585) 2025-09-19 20:22:53 +00:00
Brian Picciano
ff51faaeac chore(db): Simplifications to trie-related storage-api methods (#18579) 2025-09-19 15:41:32 +00:00
YK
8f4cc90ef9 chore: clippy manual_string_new warning in version.rs (#18576) 2025-09-19 15:03:20 +00:00
Brian Picciano
ebe1a8b014 chore(trie): Use Vec<Option<...>> in InMemoryTrieCursor (#18479) 2025-09-19 13:24:46 +00:00
Dharm Singh
d6160de610 fix(rpc): return empty log set for invalid filter block ranges (#18112)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-19 11:47:38 +00:00
YK
8aeebe10ff fix(txpool): prevent double-processing of tx pool tier (#18446)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-19 11:10:01 +00:00
Alexey Shekhirin
5bc507bfaf fix(reth-bench): do not panic on empty results (#18570) 2025-09-19 10:37:50 +00:00
かとり
4e1c552d3a fix(optimism): always enable interop maintenance task if activated (#18563) 2025-09-19 09:57:49 +00:00
0xOsiris
4fcc4457c1 chore(evm): add public constructor to BlockAssemblerInput (#18559) 2025-09-19 11:59:24 +02:00
Arsenii Kulikov
c9a95d085d feat: add Future AT to LaunchNode and allow customizing local attributes builder (#18556) 2025-09-19 09:34:49 +00:00
Matthias Seitz
4e78f956fd chore: map NaN to 0.0 (#18560) 2025-09-18 22:35:48 +00:00
MozirDmitriy
df9b7a079b chore(chainspec): reuse local hardforks in DEV instead of cloning again (#18557) 2025-09-18 17:38:38 +00:00
MIHAO PARK
e2aa41733c chore(docker): add FEATURES for op dockerfile (#18489) 2025-09-18 13:15:33 +00:00
Federico Gimenez
6f385d0a01 chore(consensus): update EIP-7825 error message format (#18549) 2025-09-18 13:10:21 +00:00
MIHAO PARK
f9e5030386 docs(op): decompress the state file before init-state (#18416) 2025-09-18 15:18:21 +02:00
stevencartavia
ce6199abf6 feat: tree config setting for unwinding canonical header (#18420) 2025-09-18 12:59:08 +00:00
MIHAO PARK
70d634a3f8 feat(rpc): add admin_clearTxpool api (#18539) 2025-09-18 12:58:20 +00:00
Federico Gimenez
ea500f6af9 chore(ci): bump hive timeout (#18544) 2025-09-18 12:52:18 +00:00
Roman Hodulák
e8d32a5491 feat(rpc): Add convert_receipt_with_block method to ReceiptConverter (#18542)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-18 11:06:52 +00:00
Matthias Seitz
ece847287a chore: add cache traces (#18538) 2025-09-18 09:21:44 +00:00
Copilot
64b4ae60f5 docs: document critical cache safety assumptions in ExecutionCache (#18536)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yongkangc <46377366+yongkangc@users.noreply.github.com>
Co-authored-by: YK <chiayongkang@hotmail.com>
2025-09-18 08:52:13 +00:00
Julio
59cff107bc feat(op-reth): initial setup FlashBlockConsensusClient engine sidecar (#18443) 2025-09-18 08:13:22 +00:00
Dharm Singh
870389c5d6 refactor: EmptyBodyStorage block reader logic (#18508)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-17 23:51:27 +00:00
MIHAO PARK
d357d2acb3 feat(node): rename debug.rpc-consensus-ws to debug-rpc-consensus-url to suport HTTP (#18027)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-17 23:10:55 +00:00
Mablr
2b68d3a424 fix(rpc): use flashblock when preparing tx response on gettxreceipt (#18530) 2025-09-17 20:39:37 +00:00
Federico Gimenez
6bf405a143 chore(ci): bump hive eest tests to v5.1.0 (#18528) 2025-09-17 19:15:17 +00:00
leniram159
4a958f41b8 fix: use noopprovider for pending block state root (#18523) 2025-09-17 17:24:38 +00:00
Roman Hodulák
6e6a497ef2 refactor(evm): Replace revm_spec* functions with alloy-evm and alloy-op-evm versions (#18526) 2025-09-17 16:46:21 +00:00
Roman Hodulák
5a39e57e47 deps: Upgrade alloy and alloy-evm versions 1.0.30 => 1.0.32 and 0.21.0 => 0.21.1 respectively (#18525) 2025-09-17 15:53:24 +00:00
crazykissshout
4b4b122e75 docs(engine): improve cache naming and documentation (#18457)
Co-authored-by: YK <chiayongkang@hotmail.com>
2025-09-17 14:45:26 +00:00
Hai | RISE
98ce04d5e0 feat: relax OpEngineValidatorBuilder for more custom payload types (#18520) 2025-09-17 14:37:07 +00:00
Brian Picciano
d9c9810266 fix(trie): Don't run repair-trie if MerkleExecute is incomplete (#18497) 2025-09-17 14:32:02 +00:00
spencer
193f699057 chore(engine): remove calldata exception workaround (#18521) 2025-09-17 14:25:42 +00:00
Alexey Shekhirin
584d7164fd feat(engine): fallback for when both state root task and parallel state root failed (#18519) 2025-09-17 13:31:26 +00:00
Roman Hodulák
5c5b21e489 feat(optimism): Implement local_pending_state for RPC that uses pending_flashblock (#18518) 2025-09-17 12:59:27 +00:00
theo
fabf3e84d4 feat(op/jovian): implement min base fee in op-reth. bump alloy, alloy-evm deps. (#18407)
Co-authored-by: Emilia Hane <emiliaha95@gmail.com>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-09-17 12:47:01 +00:00
VolodymyrBg
8a3d984c11 fix(docs): correct BlockBody root docs and RecoveredBlock “safer variant” references (#18510) 2025-09-17 12:25:27 +00:00
Federico Gimenez
f113a97a78 chore(ci): run eest osaka tests on hive workflow (#18516) 2025-09-17 12:11:25 +00:00
YK
31ce037a25 chore: add myself to CODEOWNERS (#18514) 2025-09-17 10:42:32 +00:00
YK
088eb6c463 feat(metrics): add transaction error counter for prewarming (#18509) 2025-09-17 09:57:30 +00:00
Arsenii Kulikov
04c5820689 fix: don't override existing tables in create_tables_for (#18511)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-17 09:56:35 +00:00
Brian Picciano
9c892b0233 chore: add myself to CODEOWNERS for engine and stages (#18512) 2025-09-17 09:55:11 +00:00
Arsenii Kulikov
9fc89495d0 fix: don't require closure to be Debug (#18507) 2025-09-16 22:51:29 +00:00
sashass1315
c45817c1f2 chore(engine): avoid panic on mpsc send in sparse trie worker (#18502) 2025-09-16 20:39:33 +00:00
Arsenii Kulikov
7296fc68b6 feat: relax EthBlockAssembler (#18505) 2025-09-16 19:38:35 +00:00
Arsenii Kulikov
7af829ed37 feat: make EthBuiltPayload generic over NodePrimitives (#18504) 2025-09-16 19:12:11 +00:00
Arsenii Kulikov
bf58089286 feat: more flexible rpc receipts (#18501) 2025-09-16 20:49:41 +02:00
Matthias Seitz
5274f095fe chore: skip prewarm transact errors (#18498) 2025-09-16 15:13:20 +00:00
MozirDmitriy
1185514c1e fix(engine): exit MultiProofTask loop on closed internal channel (#18490) 2025-09-16 14:22:45 +00:00
Richard Janis Goldschmidt
847330cdfc fix(cli): disallow --instance 0 (#18496) 2025-09-16 14:16:39 +00:00
wizard
d1c966020b docs: fix incorrect transaction type count (#18437) 2025-09-16 12:20:03 +00:00
VolodymyrBg
18052836fe docs(engine): fix LiveSync target doc and clarify disable-parallel-sparse-trie semantics (#18478) 2025-09-16 12:05:39 +00:00
Matthias Seitz
1697826fdb chore: deconstruct non-exhaustive (#18492) 2025-09-16 12:00:37 +00:00
Matthias Seitz
976939ab6b chore: update superchain commit (#18481)
Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>
2025-09-16 10:55:57 +00:00
Nathaniel Bajo
05008e2841 feat(op-reth): specialize get_transaction_receipt to check pending flashblocks (#18374)
Co-authored-by: Nathaniel Bajo <nathanielbajo@Nathaniels-MacBook-Pro.local>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-09-16 02:07:01 +00:00
Matthias Seitz
8e65a1d1a2 fix: missing generic type hint for cursor (#18483) 2025-09-15 23:32:19 +00:00
CPerezz
b7e9f7608e feat(network): add shadowfork block hash filtering for peers (#18361)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-15 22:14:04 +00:00
Arsenii Kulikov
5f38ff7981 feat: Block::iter_recovered (#18476) 2025-09-15 20:26:19 +00:00
Alexey Shekhirin
5844ff7b17 feat(storage): bump MDBX map size to 8TB (#18360) 2025-09-15 16:42:37 +00:00
Matthias Seitz
2dabb23331 fix(rpc): disable tx gas limit in calls (#18473) 2025-09-15 15:53:23 +00:00
Federico Gimenez
7cf239ab59 feat: add CliApp wrapper for ethereum CLI configuration and execution (#18458) 2025-09-15 15:31:37 +00:00
Federico Gimenez
e578b1b933 chore(ci): update ignored hive tests (#18412) 2025-09-15 14:18:00 +00:00
MIHAO PARK
ec2a898ac6 fix(rpc): add validation for missing headers in debug execution witness (#18444) 2025-09-15 14:15:35 +00:00
Hai | RISE
ef85d93cd7 perf(db): open MDBX DBIs only once at startup (#18424) 2025-09-15 11:57:01 +00:00
MozirDmitriy
d2b9c571a2 fix(engine): remove redundant method-level where bound in InvalidBlockWitnessHook (#18459) 2025-09-15 10:39:20 +00:00
YK
d61349beb2 fix(engine): perform cache updates with guard (#18435) 2025-09-15 10:27:58 +00:00
Fredrik
7d5415a608 perf: Enforce EIP-7825 transaction gas limit for Osaka (#18439)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-15 10:25:16 +00:00
Federico Gimenez
5516ad2d4f chore(ci): unpin kurtosis op package (#18456) 2025-09-15 09:23:02 +00:00
crStiv
1b08843bc5 docs: multiple small textual defects (#18434)
Co-authored-by: YK <chiayongkang@hotmail.com>
2025-09-14 12:08:43 +00:00
Matthias Seitz
96f8454d42 chore: remove type aliases (#18433) 2025-09-14 12:23:46 +02:00
github-actions[bot]
2408586a51 chore(deps): weekly cargo update (#18431)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-09-14 11:27:26 +02:00
stevencartavia
27e4a05cf0 chore: move and rename PendingBlockAndReceipts to BlockAndReceipts (#18430) 2025-09-14 07:41:43 +00:00
lipperhey
1bd6cc21c2 chore: clean up TS warnings in search index & file finder (#18426) 2025-09-13 11:54:02 +00:00
Matthias Seitz
33c75e8e52 chore: add state and response to miner error (#18422) 2025-09-13 13:32:24 +02:00
stevencartavia
99b6dc7986 feat: add helper to PendingBlockAndReceipts (#18423) 2025-09-13 09:51:17 +00:00
stevencartavia
7694b9dee3 feat: fn recovered_tx to indexedTx (#18421) 2025-09-13 10:55:19 +02:00
Hai | RISE
f66e197171 chore(storage): remove unused primed_dbis (#18415) 2025-09-13 07:32:22 +00:00
Hai | RISE
bac0e1f83f perf: downsize mempool tx priority from U256 to u128 (#18413) 2025-09-13 07:30:46 +00:00
TMOT
e276480728 feat(observability): add phase-level observablity to newPayload processing (#18308)
Co-authored-by: YK <chiayongkang@hotmail.com>
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-13 02:01:48 +00:00
Matthias Seitz
44a48ab9fd fix: dont update canon chain to ancestor for opstack (#18410) 2025-09-12 19:36:05 +02:00
かとり
72c2d1b6a0 feat(txpool): break down queued transaction states into specific reasons (#18106)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-12 13:03:41 +00:00
Hai | RISE
51bf7e37e2 perf(db): reuse MDBX DBIs for the same tx (#18292) 2025-09-12 12:34:52 +00:00
Federico Gimenez
bd387cd495 chore: update e2e-test-utils code owners (#18397) 2025-09-12 10:41:12 +00:00
Snezhkko
82fb54763c fix(e2e): persist accepted header in CheckPayloadAccepted and align timestamp (#18275)
Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>
Co-authored-by: Federico Gimenez <fgimenez@users.noreply.github.com>
2025-09-12 10:41:04 +00:00
Cypher Pepe
87444ef8d0 chore: fixed broken link in history-expiry.mdx (#18400) 2025-09-12 10:38:39 +00:00
leniram159
6d4a1a3ccf chore: use decode_2718_exact for recover raw txs (#18381) 2025-09-12 08:40:17 +00:00
Hai | RISE
40a9954a8e fix: still use real chain id for no-op network (#18382) 2025-09-12 08:30:37 +00:00
stevencartavia
3e4c0cc402 feat: replace PendingBlockAndReceipts tuple with dedicated struct (#18395) 2025-09-11 22:32:09 +00:00
Federico Gimenez
f3aa57a10e fix: map EIP-7623 gas floor errors to expected exception type for test compatibility (#18389) 2025-09-11 20:15:53 +00:00
Yash Atreya
edc1ae8f4d fix(docs): mv search-index to dist from .vocs (#18390) 2025-09-11 14:49:19 +00:00
Yash Atreya
8c2d5cc484 fix(docs): disable jekyll which removes the search-index (#18388) 2025-09-11 12:37:07 +00:00
Matthias Seitz
9d3564ecba fix: relax nonce gap rule if configured (#18385) 2025-09-11 11:39:50 +00:00
Arsenii Kulikov
60568cca8f feat: add helper aliases for node adapters (#18366) 2025-09-11 07:55:13 +00:00
Arsenii Kulikov
a80ed916b1 refactor!: more type-safety in cli (#18375) 2025-09-11 07:54:34 +00:00
Brian Picciano
967a6fb1d5 perf(trie): Use ParallelSparseTrie (if enabled) for storage tries (#17959) 2025-09-10 22:51:52 +00:00
Matthias Seitz
f2350e509e fix: check payload id (#18370) 2025-09-10 18:46:48 +00:00
Federico Gimenez
17a41a2463 feat: bump hive eest tests (#18013) 2025-09-10 18:30:39 +00:00
Federico Gimenez
424974ca37 fix(engine): avoid block fetching inconsistencies for checks during reorgs (#18368) 2025-09-10 17:44:38 +00:00
Federico Gimenez
d6a92287ed feat(engine): check header validity after invalid transaction (#18356) 2025-09-10 12:00:28 +00:00
Yash Atreya
e94658f792 fix(docs): include .vocs to retain search-index (#18363) 2025-09-10 10:22:03 +00:00
Matthias Seitz
700f2e101a feat: add some ethapi builder fns (#18358) 2025-09-10 09:12:02 +00:00
malik
a3aaccd34a perf: optimize canonical_hashes_range with Vec::with_capacity pre-allocation + benchmark (#18072)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-10 07:36:51 +00:00
Rez
fe236cd571 fix: add is_osaka check before erroring in default_ethereum_payload (#18355) 2025-09-10 07:06:12 +00:00
Léa Narzis
3ce0a38108 fix: fix search in vocs doc (#18354) 2025-09-09 20:42:57 +00:00
Emilia Hane
4c363fe1aa feat(op-sdk): custom precompiles (#18350) 2025-09-09 20:04:41 +00:00
Brian Picciano
2fa52f32f4 fix(prune): TransactionLookup pruning issues with pre-merge expiry (#18348) 2025-09-09 16:55:17 +00:00
Arsenii Kulikov
90aa99cb3c feat: support customizable RPC namespace parsers (#18160)
Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>
2025-09-09 14:17:43 +00:00
Ignacio Hagopian
394a53d7b0 feat(stateless): Run EEST tests in stateless block validator & bug fixes (#18140)
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-09 12:48:14 +00:00
Matthias Seitz
4fdc1ceb0c refactor(revm): (#18150) use hardfork activation helpers (#18349)
Co-authored-by: Waiting-Chai <1753609696@qq.com>
2025-09-09 12:47:17 +00:00
malik
1423a30e15 perf: use debug_assert for parked pool lookup (#17712)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-09 12:45:11 +00:00
かとり
b7c2b562e1 fix(stages): implement entities checkpoint update in merkle stage unwind (#18131) 2025-09-09 12:02:52 +00:00
Federico Gimenez
6c9c96c132 fix(ci): pin teku image to fix kurtosis-op build (#18345) 2025-09-09 11:32:13 +00:00
nk_ysg
bfb37da2a9 perf(reth-engine-local): use VecDeque reduce removal operations (#18198) 2025-09-09 11:16:56 +00:00
theo
86eaa6f285 feat(op-reth/flashblocks): subscribe to the flashblock sequences produced (#18276)
Co-authored-by: julio4 <30329843+julio4@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-09 11:10:30 +00:00
Matthias Seitz
aa5e6ad417 fix: properly compute genesis hash (#18300) 2025-09-09 12:15:57 +02:00
Hai | RISE
64afc1e549 perf(merkle-stage): only fetch checkpoint in the branch that needs it (#18339) 2025-09-09 09:04:44 +00:00
Arsenii Kulikov
1e491bc85e feat: cache latest built payload (#18324) 2025-09-09 07:55:34 +00:00
dependabot[bot]
0d13d7f4ff chore(deps): bump actions/stale from 9 to 10 (#18335)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 07:50:59 +00:00
dependabot[bot]
e079ddc7a5 chore(deps): bump actions/github-script from 7 to 8 (#18334)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 07:50:45 +00:00
dependabot[bot]
4b29f5fafe chore(deps): bump actions/setup-go from 5 to 6 (#18332)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 07:50:16 +00:00
Brian Picciano
b4beab1a83 chore(trie): use read-only db handle during repair-trie dry-runs (#18328) 2025-09-09 06:56:26 +00:00
Matthias Seitz
a35b299ae5 docs: update public dashboards (#18331) 2025-09-09 00:34:29 +02:00
Matthias Seitz
23c2dcac9a chore: bump docs version 1.7.0 (#18326) 2025-09-08 23:27:08 +02:00
Matthias Seitz
9d56da53ec chore: bump version 1.7.0 (#18323) 2025-09-08 16:43:05 +02:00
Hai | RISE
6e950a1286 fix: DB benches (#18314) 2025-09-08 13:58:29 +00:00
radik878
cf19c9a10b fix(stateless): verify_execution_witness doc for pre-state mismatch (#18319) 2025-09-08 12:37:36 +00:00
Hai | RISE
1a4b5eca3c fix(bench): fix deadlock in test data generation (#18321) 2025-09-08 12:34:27 +00:00
Hai | RISE
77e13939d0 docs(reth-bench): fix markdown (#18322) 2025-09-08 14:34:45 +02:00
Alexey Shekhirin
e2368676cc ci: pin Rust to 1.88 when building for Windows in Cross (#18320) 2025-09-08 11:52:24 +00:00
Brian Picciano
366d641cc3 feat(trie): Add helper sub-command (#18301) 2025-09-08 11:05:15 +00:00
Julio
81b2e16fb6 feat(optimism): flashblock completed sequences (#18272) 2025-09-08 10:34:42 +00:00
Alexey Shekhirin
dd69dcbd01 refactor(engine): persistence logic (#18318) 2025-09-08 10:32:44 +00:00
kien-rise
bde7464e38 refactor: change PendingPool and PendingTransaction visibility to pub (#18267) 2025-09-08 10:16:45 +00:00
Roman Hodulák
4f930c25c4 refactor(optimism): Extract pending block building responsibility out of FlashBlockService (#18247)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-08 09:15:59 +00:00
Brian Picciano
a14f345c27 chore(trie): dont warn on blinded node reveals (#18317) 2025-09-08 09:09:02 +00:00
Emilia Hane
119ed881ec fix(rpc): error code eth_sendRawTransactionSync timeout (#18252)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-07 11:15:47 +00:00
github-actions[bot]
2e06bbc80f chore(deps): weekly cargo update (#18312)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-09-07 12:49:57 +02:00
Matthias Seitz
8b098755c1 chore: introduce validationtask with capacity (#18291) 2025-09-07 08:45:35 +00:00
Dan Cline
6e75f7b2e2 feat(download): support zst archives in reth download (#18237)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-06 15:33:58 +00:00
Matthias Seitz
de24793b19 chore: clippy happy (#18310) 2025-09-06 09:59:44 +02:00
Femi Bankole
ef337d46a2 feat: introduce maybe_pending method to StateProviderFactory (#18260)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-06 09:31:09 +02:00
James Niken
63a912e312 perf(e2e-test-utils): optimize block checking by fetching header instead of full block (#18254)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-06 08:36:57 +02:00
Matthias Seitz
62f03e41bc chore: fix various typos in comments and documentation (#18296) 2025-09-06 08:36:10 +02:00
Matthias Seitz
01d6f85690 perf: specialize len 1 (#18307) 2025-09-05 22:41:14 +00:00
Arsenii Kulikov
50e8409fa6 feat: expose EvmEnv to caller_gas_allowance (#18302) 2025-09-05 16:55:23 +00:00
Matthias Seitz
0bd1bb2b8c feat: introduce setting for delegated txs slots (#18298) 2025-09-05 16:52:52 +00:00
zhygis
e93e1fcecb feat(gpo): add default fee price argument (#18297)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-05 15:04:48 +00:00
Mablr
d6845357c1 feat(metrics): add TxPoolValidatorMetrics to track inflight validation jobs (#18295) 2025-09-05 12:11:41 +00:00
Matthias Seitz
9c61b46752 perf: specialize validate_transactions_with_origin for task validator (#18288) 2025-09-05 12:09:30 +00:00
Roman Hodulák
848d7fa830 test(optimism): Test that close message is responded to in WsFlashBlockStream (#18268) 2025-09-05 10:54:11 +00:00
Hai | RISE
0cdd54838b chore: delist unused deps with cargo-machete (#18259) 2025-09-05 10:23:52 +00:00
Matthias Seitz
f8b678cf17 perf: specialize single batch request (#18289) 2025-09-05 10:19:15 +00:00
Matthias Seitz
d99f37b243 perf: optimize send raw batching (#18280) 2025-09-05 10:02:51 +00:00
Matthias Seitz
30297092f6 fix: check prune checkpoints for unwind target limit (#18263) 2025-09-05 10:02:28 +00:00
YK
254860f2df chore(txpool): add sanity tests for blob fee bit handling (#18258) 2025-09-05 10:02:05 +00:00
Hai | RISE
4cc600c41e perf(db): do not heap-allocate the stage key per query (#18284) 2025-09-05 09:44:15 +00:00
Matthias Seitz
02ff408b10 perf: build local pending block without updates (#18271) 2025-09-05 10:54:49 +02:00
Matthias Seitz
7c8f5a402e perf: rm redundant collect (#18281) 2025-09-05 01:03:56 +00:00
Arsenii Kulikov
60311096e9 chore: extract validate_against_parent_gas_limit into separate fn (#18277) 2025-09-04 19:00:13 +00:00
Matthias Seitz
cf46aa017d chore: log prune settings on unwind (#18270) 2025-09-04 14:05:19 +00:00
Roman Hodulák
7f8674971f test(optimism): Test that UTF-8 encoded messages are received in WsFlashBlockStream (#18269) 2025-09-04 14:01:56 +00:00
Roman Hodulák
c57feda644 fix(optimism): Reconnect if ws stream ends in WsFlashBlockStream (#18226) 2025-09-04 12:23:32 +00:00
Roman Hodulák
ecd18987b0 feat(optimism): Respond to close messages in WsFlashBlockStream (#18256) 2025-09-04 12:03:36 +00:00
Hai | RISE
b1e19325b6 chore: remove redundant payload trait bounds (#18262) 2025-09-04 10:31:45 +00:00
Roman Hodulák
107399ff0e feat(optimism): Decode text messages in WsFlashBlockStream (#18257) 2025-09-04 09:07:43 +00:00
Roman Hodulák
36e39ebe3d fix(optimism): Compare parent hash and latest hash to invalidate cached flashblock (#18238) 2025-09-03 20:27:04 +00:00
Matthias Seitz
1d7fefecec chore: unify engine downloader targets (#18248) 2025-09-03 17:43:59 +00:00
quantix9
3d8d7ce781 chore: downgrade debug to trace for peer reputation logs (#18250) 2025-09-03 13:40:11 +00:00
Roman Hodulák
29685ce006 test(optimism): Test that WsFlashBlockStream pongs a ping (#18217) 2025-09-03 11:38:07 +00:00
Roman Hodulák
0550289c69 feat(optimism): Respond to ping messages with pong in WsFlashBlockStream (#18212) 2025-09-03 10:39:53 +00:00
Matthias Seitz
9121dba0b6 docs: update urls in docs (#18245) 2025-09-03 12:30:34 +02:00
YK
bb1dfc9e9d perf(txpool): eliminate allocations in basefee enforcement (#18218)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-03 09:49:15 +00:00
nk_ysg
a11655b515 perf(reth-optimism-flashblocks): rm redundant clone (#18196) 2025-09-03 09:21:32 +00:00
Ivan Wang
f0880f3ff0 fix: filter zero storage values when computing withdrawals root in genesis header (#18213) 2025-09-03 07:54:30 +00:00
Dan Cline
783ef65799 chore(trie): use instrument instead of manual span (#18239) 2025-09-03 07:46:18 +00:00
Dan Cline
0acebab68c chore(engine): add better logs and spans for execution (#18240) 2025-09-03 07:45:50 +00:00
Dan Cline
d5a4898384 fix(download): use updated merkle base URL (#18236) 2025-09-03 00:20:24 +02:00
Matthias Seitz
60ce536550 chore: improve flashblock logs (#18232) 2025-09-02 20:49:17 +00:00
Matthias Seitz
733e8cfce9 chore: safe None check (#18225) 2025-09-02 18:31:55 +00:00
Roman Hodulák
298a7cb5ea feat(optimism): Warn if FlashBlockService has stopped (#18227) 2025-09-02 20:27:54 +02:00
Roman Hodulák
44caf60afd test(optimism): Test that sequence stops before a gap (#18228) 2025-09-02 17:39:34 +00:00
Roman Hodulák
358b61b4ef fix(optimism): Prevent repeated executions of current flashblock sequence (#18224) 2025-09-02 14:02:18 +00:00
Matthias Seitz
6bcd5e07ac fix: incorrect blob fee comparison (#18216) 2025-09-02 12:02:47 +00:00
Matthias Seitz
dba13f4486 revert: "perf(txpool): eliminate allocations in basefee enforcement" (#18215) 2025-09-02 13:49:15 +02:00
Matthias Seitz
1788c5c6a2 fix: spawn flashblocks service as blocking (#18214) 2025-09-02 10:39:32 +00:00
Matthias Seitz
d10e5f6fb4 perf: prepare flashblock txs (#18201)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-09-01 19:41:34 +00:00
Matthias Seitz
4d94e201d7 chore: impl ExecutorTx for withtxenv (#18202) 2025-09-01 19:25:40 +00:00
Matthias Seitz
e9801a7997 chore: simplify flashblocks poll logic (#18194)
Co-authored-by: julio4 <30329843+julio4@users.noreply.github.com>
Co-authored-by: Roman Hodulák <roman.hodulak@polyglot-software.com>
2025-09-01 17:40:18 +00:00
Roman Hodulák
fe37279ab3 test(optimism): Test that streaming flashblocks from remote source is successful (#18170) 2025-09-01 13:20:09 +00:00
Brawn
b6fddd7d07 fix: struct serialization to match actual fields (#18189) 2025-09-01 13:20:06 +00:00
Roman Hodulák
945d50a7f1 test(optimism): Cover the case of repeatedly failing to connect to websocket in WsFlashBlockStream (#18169) 2025-09-01 12:40:43 +00:00
Roman Hodulák
e3772c4db9 test(optimism): Cover the case of stream returning errors in WsFlashBlockStream (#18167) 2025-09-01 11:59:50 +00:00
Roman Hodulák
e76c88c219 test(optimism): Cover the failure case of decoding a non-binary message in WsFlashBlockStream (#18166) 2025-09-01 11:26:26 +00:00
Roman Hodulák
9ec6459bda test(optimism): Cover successful decoding of websocket messages in WsFlashBlockStream (#18163) 2025-09-01 10:54:07 +00:00
Brian Picciano
651e34cec6 fix: Pass prefix set from init_from_state_dump into compute_state_root (#18185) 2025-09-01 10:16:35 +00:00
TMOT
d69fda1a2b feat(examples): added txpoolExt_clearTxpool to existing example (#18175) 2025-09-01 10:07:52 +00:00
Roman Hodulák
e9a57a72c8 refactor(optimism): Extract responsibility to connect to a flashblock websocket stream (#18158) 2025-09-01 09:22:04 +00:00
Julio
61b8015c84 perf(optimism): use cached db in FlashblockService (#18125)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-09-01 11:04:03 +02:00
YK
e30da67d35 perf(txpool): eliminate allocations in basefee enforcement (#18162) 2025-09-01 08:18:14 +00:00
Fynn
203cb6e158 feat: enhance engine tree metrics (#18000) 2025-09-01 01:29:22 +00:00
DaniPopes
3ad9743904 chore: avoid using hashmap hashers directly (#18176) 2025-08-31 13:40:13 +00:00
smileclown2024
42eb835569 perf(stages): optimize unwind operation by fetching headers instead full blocks (#18139) 2025-08-31 08:39:17 +00:00
github-actions[bot]
4cc2a4decd chore(deps): weekly cargo update (#18174)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-08-31 08:17:33 +00:00
Matthias Seitz
911ed27787 chore: simplify dev signed tx conversions (#18171) 2025-08-30 19:01:31 +00:00
David Klank
eab2ad7743 refactor: remove unnecessary PathBuf clone in CLI help generator (#18172) 2025-08-30 11:43:33 +00:00
VolodymyrBg
4a28cf4281 fix: correct logical error in delete_outside_range error message (#18031) 2025-08-30 08:07:31 +00:00
James Niken
339f18c48f ci: Fix .PHONY declaration for install-reth-bench target in Makefile (#18152) 2025-08-30 10:03:46 +02:00
pepes
9b863264d4 perf: optimize single-element collection creation (#18168) 2025-08-29 16:21:48 +00:00
dependabot[bot]
0e9cbc80b4 chore(deps): bump actions/upload-pages-artifact from 3 to 4 (#18076)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-29 14:17:38 +00:00
Julio
297304852b fix(optimism): find fb attrs in base fb (#18164) 2025-08-29 14:01:35 +00:00
quantix9
7170e14404 chore: Add 0x prefix and use macro (#18156) 2025-08-29 12:20:08 +00:00
Roman Hodulák
616e492c79 perf(optimism): Pass noop provider to skip state root calculations for flashblocks (#18161) 2025-08-29 11:27:00 +00:00
nk_ysg
64df86fe30 perf(reth-invalid-block-hooks): use Reverts::eq reduce clone (#18159) 2025-08-29 11:08:24 +00:00
Jonas Bostoen
21ba9c4e05 feat(optimism): add FlashblocksRx getter (#18155) 2025-08-29 10:40:49 +00:00
Brian Picciano
e7685789be fix(trie): Fix call to update_account in witness (#18154) 2025-08-29 10:31:02 +00:00
nk_ysg
5c0c8bb38d chore(reth-optimism-storage): small refactor code (#18104) 2025-08-29 08:58:04 +00:00
YK
ee5006c027 perf(engine): pre-allocate channel handles in prewarm task (#18147) 2025-08-29 08:23:01 +00:00
YK
f93dfec50f perf(engine): pre-allocate Vec capacity in payload processor (#18148) 2025-08-29 07:24:16 +00:00
Eric Woolsey
001fb927b5 feat: generalize impl EngineValidatorAddOn for OpAddOns (#18141) 2025-08-29 06:14:26 +00:00
Max Bytefield
0b316160a9 docs(op): op chains don't require deposit contracts, so as dev chain (#17988)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-28 18:22:26 +00:00
Arsenii Kulikov
66a0a14cf6 refactor: merge EthTransactionValidator and EthTransactionValidatorInner (#18129) 2025-08-28 18:22:01 +00:00
Matthias Seitz
354cfdf90e fix(txpool): ensure fee changes are updated (#18137) 2025-08-28 18:21:40 +00:00
Roman Hodulák
f13cf181ad fix(optimism): Fail if latest and base flashblock parent are different (#18132)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-28 17:44:54 +00:00
Matus Kysel
abf1dbd7a5 feat(net): implement support of subprotocols (#18080)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-28 17:06:16 +00:00
Louis Brown
8bc2bfdf90 feat: Forward transactions to a specified endpoint (#17444)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-08-28 16:18:03 +00:00
Haotian
94547b06a1 fix: import should count on the delta (#17819)
Signed-off-by: tmel <tmel0103@gmail.com>
Signed-off-by: tmelhao <tmel0103@gmail.com>
Co-authored-by: tmel <tmel0103@gmail.com>
2025-08-28 15:27:41 +00:00
Roman Hodulák
594a67d87f fix(optimism): Verify that flashblocks are not old according to canon state (#18123) 2025-08-28 15:23:05 +00:00
Hai | RISE
fad93e95a8 perf(engine): only clone headers instead of full blocks for tree tasks (#18116) 2025-08-28 15:14:58 +00:00
Suyash Nayan
282abc708c fix(engine): Prevent instant miner from creating empty blocks (#18108)
Signed-off-by: 7suyash7 <suyashnyn1@gmail.com>
2025-08-28 15:12:58 +00:00
Matus Kysel
63a09bace9 refactor(eth-wire): remove EthVersion::total_messages in favor of EthMessageID::max (#17999) 2025-08-28 12:46:48 +00:00
Matthias Seitz
9e9a0b1867 chore: add prewarm traces (#18117) 2025-08-28 10:24:11 +00:00
Andrea Simeoni
b2c6852c29 fix(optimism): Fix endless poll on the FlashBlockService (#18120) 2025-08-28 09:39:55 +00:00
Arsenii Kulikov
3425a31a2f chore: make caller_gas_allowance an RPC trait method (#18101) 2025-08-28 09:22:47 +00:00
Roman Hodulák
07c62aebda fix(optimism): Prevent old pending flashblock from being returned from pending_flashblock (#18103) 2025-08-28 09:01:27 +00:00
Matthias Seitz
8a4b53361c chore: include err in log (#18119) 2025-08-28 08:44:16 +00:00
leniram159
87a4949f5c feat: add EIP-7934 block size check to validateBuilderSubmissionV5 (#18111) 2025-08-28 07:57:03 +00:00
Matthias Seitz
eb4496dbf0 ci: remove expected failures (#18099) 2025-08-27 21:49:26 +02:00
nk_ysg
1d893a1ce2 chore(reth-optimism-cli): use OpTypedTransaction::eip2718_encode (#18105) 2025-08-27 16:08:10 +00:00
Matthias Seitz
e62c7d2469 feat: add module manipulation methods and RPC server arg helpers (#18084) 2025-08-27 14:35:08 +00:00
Dharm Singh
0804131015 refactor: make transaction validator functions reusable (#17929)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-08-27 14:30:56 +00:00
Roman Hodulák
f376dd8031 feat(optimism): Remove builder of next block environment from FlashBlockService (#18100) 2025-08-27 13:59:02 +00:00
Roman Hodulák
9d1ec366f8 feat(optimism): Implement conversion of ExecutionPayloadBaseV1 into OpNextBlockEnvAttributes (#18097) 2025-08-27 13:30:47 +00:00
Hai | RISE
615bd4a30f perf(engine): only fetch headers instead of full blocks for tree tasks (#18088) 2025-08-27 12:27:37 +00:00
Roman Hodulák
3a5c992394 feat(optimism): Add flashblocks_url as part of rollup args of the op-reth CLI (#18094) 2025-08-27 11:32:00 +00:00
Matthias Seitz
dc598490ac feat: add helper for provider with wallet (#18085) 2025-08-27 10:27:08 +00:00
Matthias Seitz
2e6ab54248 feat: add NoopNetwork example (#18093) 2025-08-27 10:25:43 +00:00
Roman Hodulák
97f4b00fc0 feat(optimism): Launch FlashBlockService when websocket URL is provided in OpEthApi (#18077) 2025-08-27 09:51:33 +00:00
0xKitsune
b7b70a46a5 feat: optionally disable balance check for EthTransactionValidator (#18086) 2025-08-27 09:44:59 +00:00
nk_ysg
f67e7547df fix(era): SlotIndex offset support negative value (#18047) 2025-08-27 08:28:28 +00:00
malik
28774f7ad4 fix: clarify locking behavior comment in InMemoryState (#18081) 2025-08-27 08:05:52 +00:00
Brian Picciano
34de67ab57 fix: Fix state root related metrics (#18045) 2025-08-27 08:04:52 +00:00
Hai | RISE
0889a52ec0 chore(nix): add cargo-nextest to devShell (#18087) 2025-08-27 07:59:09 +00:00
Matthias Seitz
3d8033a03c chore: add helpers for setting minimum protocol basefee (#18083) 2025-08-26 23:51:55 +00:00
Haotian
9d2194fa43 feat: support importing multi files (#17928)
Signed-off-by: tmelhao <tmel0103@gmail.com>
Co-authored-by: tmelhao <tmel0103@gmail.com>
2025-08-26 20:58:53 +00:00
Arsenii Kulikov
db04a19101 feat: fusaka changes (#18071)
Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
Co-authored-by: Bharath Vedartham <vedabharath12345@gmail.com>
2025-08-26 18:43:36 +00:00
Roman Hodulák
13e0fd55de feat(optimism): Change FlashBlockService output ExecutedBlock => PendingBlock (#18078) 2025-08-26 16:59:23 +00:00
Igor Markelov
92743a0d87 feat: FCU unwind: properly reorg in-memory canonical state and update latest block (#17938)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-26 16:54:50 +00:00
Roman Hodulák
3c7301e0bb feat(optimism): Add launch_wss_flashblocks_service function spawning a task sending last pending block (#18067) 2025-08-26 15:15:44 +00:00
Debjit Bhowal
87647b25ac fix(static_file_provider): Exception for Gnosis and Chiado (#18044)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-26 14:31:06 +00:00
Léa Narzis
8c8ffd4329 refactor(rpc): add TxEnv converter to RpcCoverter (#17792)
Co-authored-by: Roman Hodulák <roman.hodulak@polyglot-software.com>
2025-08-26 13:51:07 +00:00
ongyimeng
caa8c541ec perf: use FuturesOrdered instead of join_all to yield results (#17638)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-26 13:26:26 +00:00
Roman Hodulák
7ee085f393 feat(optimism): Add constructors to FlashBlockService and FlashBlockWsStream (#18064) 2025-08-26 13:23:01 +00:00
Hai | RISE
d14658dc5e perf(payload): do not clone full attributes for timestamp validation (#18054) 2025-08-26 15:29:07 +02:00
Roman Hodulák
b50eb7e514 feat(optimism): Wrap incoming stream item in Result for compatibility of FlashBlockService with FlashBlockWsStream (#18063) 2025-08-26 12:15:29 +00:00
Avory
089629ba64 fix: use deterministic RNG in state_root_task benchmark (#18049) 2025-08-26 11:47:53 +00:00
int88
f343b19c1b fix: add secp256k1 to dev-dependencies of dns crate (#18059) 2025-08-26 09:44:10 +00:00
bendanzhentan
138c9172bb fix(node/builder): correct left_mut() method implementation and docs (#18053) 2025-08-26 08:46:45 +00:00
YK
7703e6fb9d refactor(tree): move metered execution functions to tree module (#17912) 2025-08-26 01:14:31 +00:00
Matthias Seitz
dd4aa7cd2a chore: relax EngineValidatorAddOn impl (#18052) 2025-08-25 21:13:25 +02:00
smileclown2024
af57047654 perf: optimize canonical_hashes_range to O(n) complexity (#17975) 2025-08-25 18:42:19 +00:00
かとり
8bec55183e feat: remove the not used executor in sparse_trie (#17966) 2025-08-25 20:15:24 +02:00
Roman Hodulák
23cfd1bb7c feat(optimism): Add FlashBlockService that builds blocks from FlashBlocks (#18009) 2025-08-25 15:02:39 +00:00
Avory
c97b322c54 feat: bump jsonrpsee to v0.26.0 (#17901)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-25 16:54:30 +02:00
Matthias Seitz
d87280e793 chore: apply spelling and typo fixes (#18041) 2025-08-25 16:24:21 +02:00
DaniPopes
c3d211c6f7 chore: remove msrv from clippy.toml (#18034) 2025-08-25 15:21:23 +02:00
iPLAY888
f3c2a3dc27 Update README.md (#18021) 2025-08-25 13:55:08 +02:00
Hai | RISE
014e8dacc9 perf(pool): remove unused hash in tx insertion/validation (#18030) 2025-08-25 10:38:48 +00:00
Dharm Singh
01f667c228 feat(reth-bench): add --advance option for relative block ranges (#17996) 2025-08-25 01:51:24 +00:00
github-actions[bot]
848370b311 chore(deps): weekly cargo update (#18023)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-08-24 10:16:29 +00:00
Matthias Seitz
ce2ce23e30 feat: add accessor methods for RPC handle types (#18016) 2025-08-23 11:27:27 +00:00
Julio
13f7ae463e feat: add log.file.name cli arg (#17883)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-23 04:51:11 +00:00
Ishika Choudhury
304c9090e2 feat: added trace_transaction_storage_access (#16022)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-23 03:23:16 +00:00
Dharm Singh
28b085a352 feat: add CLI support for TransactionPropagationMode in NetworkArgs (#18012)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-23 02:59:34 +00:00
Kero
d5ade8504a fix: replace unwrap with proper error handling in ShardedKey decode (#17902) 2025-08-23 02:48:08 +00:00
Matthias Seitz
fcb74930af feat: add helper for setting tx propagation mode (#18007) 2025-08-22 15:34:10 +00:00
Federico Gimenez
530269e3a6 test(engine): add e2e tests for forkchoice update with finalized blocks (#18004) 2025-08-22 13:01:37 +00:00
Matthias Seitz
42f44a3d74 fix: rlp encoding for sealedblock (#18003) 2025-08-22 10:12:36 +00:00
Brian Picciano
8193fcff93 chore(trie): fully reveal sparse tries prior to leaf updates/removals (#17643)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-22 09:16:38 +00:00
leniram159
d8e8d67ff8 fix: remove unused base_fee_params_at_block function (#17992)
Co-authored-by: Dharm Singh <dharmhsing@gmail.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-22 08:01:45 +00:00
JP
e9d4020057 fix(revm-inspectors): update revm-inspectors to fix js tracer opcode gas calculation (#17986) 2025-08-22 09:38:59 +02:00
Roman Hodulák
a4dd305ee9 feat(optimism): Add FlashBlockWsStream for streaming flashblocks from a websocket connection (#17987) 2025-08-21 23:11:56 +02:00
Federico Gimenez
00ae7654e9 chore(cli): add log about state root computation for init-state (#17980) 2025-08-21 19:46:35 +00:00
MIHAO PARK
9209d37e72 chore: remove not used block/receipt memory limiter constants (#17989) 2025-08-21 21:52:54 +02:00
Starkey
b81bdc88f0 chore(db): remove empty TODO comment (#17981) 2025-08-21 19:33:11 +00:00
Roman Hodulák
12abfd76de feat(optimism): Add FlashBlock payload schema (#17984) 2025-08-21 17:35:54 +02:00
Ashin Gau
e0b5203cb0 refactor: Fix incorrect length parameter in StorageTrieEntry::from_compact (#17748) 2025-08-21 14:31:13 +00:00
Roman Hodulák
00dd9eccc6 feat(optimism): Add new reth-optimism-flashblocks crate (#17982) 2025-08-21 16:50:09 +02:00
Roman Hodulák
aabeb06a15 feat(rpc): Use pool-based pending block for pending state over latest (#17924) 2025-08-21 11:41:28 +00:00
MIHAO PARK
6264530a8a docs(net): add Rreceipts69 document (#17969)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-21 10:59:13 +00:00
Federico Gimenez
7ea6daf7d8 fix(optimism): add debug_traceTransaction support for pre-bedrock blocks (#17971) 2025-08-21 10:41:32 +00:00
Roman Hodulák
65907e3d86 feat(rpc): Add local_pending_state that creates a state provider out of a mem-pool built pending block (#17957) 2025-08-21 08:33:15 +00:00
Roman Hodulák
e0ca0407b2 docs(sdk): Add guide for custom transaction envelope macro usage (#17879) 2025-08-21 08:30:12 +00:00
Brian Picciano
df3bf2c00a perf(trie): default ParallelSparseTrie to enabled (accounts only still) (#17956) 2025-08-21 06:24:05 +00:00
Brian Picciano
4fe6ae411a fix: ParallelSparseTrie::update_leaf edge-case, and not correctly clearing all fields for re-use (#17955) 2025-08-21 06:23:42 +00:00
MIHAO PARK
a2751c316e fix(net): Receipts69 should respond with Receipts69 message (#17880) 2025-08-20 21:32:07 +00:00
Starkey
7884c1e063 fix: use len() instead of iter().count() for trace logging (#17968) 2025-08-20 20:30:22 +00:00
Dharm Singh
2c4d90671f docs(trie): document MDBX ordering assumptions in TrieWalker and Trie… (#17906) 2025-08-20 18:20:04 +00:00
Femi Bankole
a89646faee chore(engine): rename block validation task (#17964) 2025-08-20 18:16:19 +00:00
Femi Bankole
1ed7450d53 feat(engine): set default_memory_block_buffer_target to zero (#17963) 2025-08-20 18:01:00 +00:00
かとり
8435976563 feat(optimism): add supervisor_revalidation_duration_seconds metrics (#17897) 2025-08-20 17:32:50 +00:00
Léa Narzis
0110fbe0a9 refactor(evm): use execution payload getters (#17947) 2025-08-20 14:43:48 +00:00
Matthias Seitz
db6ee6428d chore: rm redundant runtime (#17961) 2025-08-20 14:11:24 +00:00
Roman Hodulák
441bad848b feat(rpc): Convert state_at_block_id into async function (#17954) 2025-08-20 14:09:32 +00:00
0xNarumi
4bd788e74c fix: allow at most one in-flight tx (#17960) 2025-08-20 14:04:41 +00:00
Matthias Seitz
81fe6ca05a chore: activate pool if node (#17950) 2025-08-20 13:01:03 +00:00
Matthias Seitz
e110c9b8d4 chore: add helpers to added tx state (#17951) 2025-08-20 13:00:33 +00:00
Léa Narzis
7542580170 refactor(era): add era types and file traits for shared behavior (#17873)
Co-authored-by: Roman Hodulák <hodulakr@gmail.com>
2025-08-20 11:43:20 +00:00
Roman Hodulák
0fa93840e8 feat(rpc): Add spawn_blocking_io_fut that accepts a future (#17953) 2025-08-20 09:45:43 +00:00
Starkey
93fcd82351 fix: replace todo!() with Ok(None) in NoopProvider transaction_block (#17949) 2025-08-20 10:00:18 +02:00
Solar Mithril
0f26562bb6 feat: Add transaction propagation kind 'None' (#17944) 2025-08-19 16:52:58 +00:00
crStiv
a4c57de5ec docs: multiple small textual defects (#17904) 2025-08-19 16:50:40 +00:00
bendanzhentan
d31e4ca835 fix(optimism): correct string formatting in error message (#17923) 2025-08-19 16:47:03 +00:00
dependabot[bot]
d8ade5af38 chore(deps): bump amannn/action-semantic-pull-request from 5 to 6 (#17933)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 16:45:20 +00:00
YK
a1a1b11e45 fix(trie): replace rayon with tokio for I/O operations in parallel trie (#17931) 2025-08-19 16:37:17 +00:00
Starkey
41aa3bf7ff fix: optimize empty directory check in is_database_empty (#17932) 2025-08-19 16:23:14 +00:00
Brian Picciano
97763ff7dd chore: fix clippy in nix flake (#17918) 2025-08-19 18:46:11 +02:00
crazykissshout
a3298ecfdd test: remove misleading TODO comments in MockEthProvider (#17926) 2025-08-19 12:45:39 +00:00
bigbear
b9e09d06b7 chore: replace reference (#17899)
Co-authored-by: Yash Atreya <44857776+yash-atreya@users.noreply.github.com>
2025-08-19 12:06:00 +00:00
malik
b81e133fbc perf: reduce cycles on indexing (#17916) 2025-08-19 07:33:10 +00:00
Mourad Kejji
91730cd326 docs: add paragraph about EIP-7702 transaction types (#17865) 2025-08-18 16:51:58 +00:00
Emilia Hane
1b9f9e2a2f chore(grafana): Add description to pruner panel (#17917) 2025-08-18 15:04:56 +00:00
bendanzhentan
56e641a878 chore(metrics): fix MeteredReceiver docs (#17913) 2025-08-18 14:19:14 +00:00
Kero
3f3e4fe7a7 fix: convert anchor() method from recursive to iterative (#17909) 2025-08-18 13:55:26 +00:00
robinsdan
29e4b20588 refactor: remove StateCommitment trait (#17812) 2025-08-18 13:53:53 +00:00
Forostovec
e617dd30c9 fix(ress/provider): return zero headers when request.limit == 0 (#17911) 2025-08-18 12:12:58 +00:00
github-actions[bot]
48df70eaff chore(deps): weekly cargo update (#17907)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-17 10:32:34 +00:00
malik
61662098aa chore(pool): replace saturating_sub with unchecked_sub (#17890) 2025-08-16 00:43:54 +00:00
Matthias Seitz
198ba18e86 chore: remove Beacon from type names (#17868)
Co-authored-by: petarjuki7 <petar.jukic7@gmail.com>
2025-08-15 20:54:05 +00:00
Matthias Seitz
7577ab81aa test: add tests for fetching header,body ranges (#17893) 2025-08-15 20:52:09 +00:00
0xKitsune
f180b0da9b feat: bubble up revm feature flags via revm-reth (#17896) 2025-08-15 18:39:26 +00:00
Roman Hodulák
b3479f6622 refactor(examples): Replace CustomTransactionEnvelope with Signed<TxPayment> as the variant type in the custom node example (#17894) 2025-08-15 14:37:29 +00:00
Shiyas Mohammed
de157aa3a0 feat(rpc): add configurable pending block behaviour (#17677) 2025-08-15 13:09:41 +00:00
Roman Hodulák
055331a667 fix(examples): Implement Compact using blanket implementation (#17878) 2025-08-15 13:01:53 +00:00
YK
3f86efc3bb fix: use map_pure_precompiles for precompile caching (#17886) 2025-08-15 11:48:39 +00:00
colin
87c29027b8 fix(network): off by one error in getting next header (#17889)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-15 13:47:31 +02:00
Matthias Seitz
0de24935c2 chore: clippy happy (#17892) 2025-08-15 13:18:37 +02:00
Emilia Hane
7744ee9e74 chore(tx-pool): Rm redundant async block (#17891) 2025-08-15 13:05:31 +02:00
かとり
6daf5fc777 chore: remove the deprecated ganache api (#17881) 2025-08-14 21:49:20 +00:00
Roman Hodulák
d030ef8b7a feat(rpc): Add RpcTxConverter to allow for providing custom converters with extra context (#17827) 2025-08-14 13:15:10 +00:00
viktorking7
4651b9ae7c fix: critical error handling in ExEx launcher (#17627)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-14 07:45:41 +00:00
Mablr
907448ff3b feat(rpc): Add support for custom Tokio runtime configuration in EthereumAddOns (#17693)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-14 05:40:29 +00:00
Rej Ect
84992f7508 chore(ci): migrate workflows to checkout v5 (#17813) 2025-08-14 05:19:40 +00:00
Jack Drogon
cd7a3c816f fix: replace unsafe unwrap with proper error handling (#17867)
Signed-off-by: Jack Drogon <jack.xsuperman@gmail.com>
2025-08-14 04:40:40 +00:00
Eric Woolsey
b64eed99b5 feat: custom instance label and configurable datasource for mempool dash (#16634) 2025-08-14 04:18:21 +00:00
0xKitsune
e12e6c0d04 feat(txpool): Batch insertions into the Tx Pool (#17670)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-08-13 19:36:34 +00:00
DaniPopes
4e20417a87 fix: box some more futures (#17864) 2025-08-13 18:45:02 +00:00
nk_ysg
544eed8b72 test(chain-state): opt unit test (#17770) 2025-08-13 18:12:48 +00:00
Matthias Seitz
b5aa824120 chore: fix typos and improve documentation (#17862) 2025-08-13 20:33:52 +02:00
greg
cb03cb7e17 feat: make MockEthProvider more generic (#17780)
Signed-off-by: Gregory Edison <gregory.edison1993@gmail.com>
2025-08-13 17:55:10 +00:00
Bashmunta
ad9b528c1f docs(e2s_file): clarify automatic version insertion and entries behavior (#17789)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-13 17:38:57 +00:00
かとり
0fdc1ec28d chore: update crunchy to v0.2.4 (#17856) 2025-08-13 17:38:23 +00:00
phrwlk
f3b99cbf32 fix: remove unused import from execute.rs (#17811) 2025-08-13 17:29:54 +00:00
Roman Hodulák
8065229008 feat(rpc): Add SimTxConverter to allow for providing custom converters with extra context (#17821) 2025-08-13 17:13:55 +00:00
Jack Drogon
1cdc43d79c fix: typo initialise to initialize (#17851)
Signed-off-by: Jack Drogon <jack.xsuperman@gmail.com>
2025-08-13 17:09:59 +00:00
かとり
5dda39dd8d chore: use receipt.into_logs instead of log.to_vec to reduce the unnecessary clone (#17852) 2025-08-13 16:52:31 +00:00
onbjerg
ee8c893f59 chore: remove myself from codeowners (#17855) 2025-08-13 15:14:32 +00:00
Ishika Choudhury
94c93583af feat: introduced configurable version globals (#17711)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-13 14:25:35 +00:00
georgehao
3fe6c0c3c6 fix(call): overwrite gas when exceed the RPC_DEFAULT_GAS_CAP (#17847) 2025-08-13 14:04:20 +00:00
Jack Drogon
f1da87e3e6 fix: clippy warnning manual_is_multiple_of (#17853)
Signed-off-by: Jack Drogon <jack.xsuperman@gmail.com>
2025-08-13 13:47:58 +00:00
Dan Cline
f30016019d fix(db): make db get --raw work with DupSort tables (#17842) 2025-08-13 12:06:49 +00:00
Roman Hodulák
28c7113799 feat(examples): Add custom header extensions to payload attributes in custom_node example (#17797) 2025-08-13 10:45:10 +00:00
Max Bytefield
dfc58eac7c chore: remove s3 stage (#17831) 2025-08-13 09:22:22 +00:00
Pana
02eafd75f1 chore: update db-access example used method (#17815) 2025-08-13 09:10:52 +00:00
Dan Cline
fa31b9edcc chore(deps): bump revm 28.0.1, inspectors, alloy-evm (#17840) 2025-08-12 23:10:13 +00:00
malik
79571315be perf: use unwrap and save 198 cycles (#17836) 2025-08-12 19:34:52 +00:00
Haotian
f49b3202d1 chore(cli): rename file import_op to import_core for clarity (#17826)
Signed-off-by: tmelhao <tmel0103@gmail.com>
Co-authored-by: tmelhao <tmel0103@gmail.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-12 18:56:18 +00:00
daksh
443d16f6f7 perf: iterate through nibbles (#17820)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-12 18:54:35 +00:00
Wolfgang Welz
810790c767 feat: allow external block recovery in reth-stateless (#17755) 2025-08-12 18:44:52 +00:00
Mablr
6e691c0f38 chore: Remove BlockMeta variants and unused code (#17835) 2025-08-12 18:29:04 +00:00
Léa Narzis
3cfc01d09b feat(tx-pool): add add_transactions_with_origins helper (#17802) 2025-08-12 17:41:10 +00:00
Cypher Pepe
82f1cc09ff chore: fixed dead links in repo (#17694) 2025-08-12 17:38:02 +02:00
ssolit
5733a32e27 test: modify discv5 startup test to use a random port (#17614) 2025-08-12 17:36:50 +02:00
DaniPopes
772d92056d fix: storage lock race condition (#17823) 2025-08-12 15:03:38 +00:00
malik
01c39f6738 perf: optimize condition ordering in ParkedPool for better short-circuiting (#17816) 2025-08-12 13:40:10 +00:00
Hai | RISE
1077904f55 perf: remove some clones around eth tracing (#17822) 2025-08-12 13:30:35 +00:00
dependabot[bot]
6a79d80ec5 chore(deps): bump actions/download-artifact from 4 to 5 (#17817)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 10:55:33 +00:00
dependabot[bot]
e741fac680 chore(deps): bump actions/checkout from 4 to 5 (#17814)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 08:12:55 +00:00
Max Bytefield
74dcb8afdb chore(test-vectors): remove TxDeposit compact TODO (#17800)
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
2025-08-12 02:10:22 +00:00
Max Bytefield
e208d380b7 chore: remove whitespace of the gas unit and threshold (#17808) 2025-08-12 02:04:39 +00:00
Max Bytefield
f0bd4c6843 chore: rename gas to gas_used in the node logs (#17767) 2025-08-11 21:37:48 +00:00
Solar Mithril
bcbd2d64ce chore: Expose payload builder handle and metrics (#17764) 2025-08-11 16:46:19 +00:00
viktorking7
3ba2370a57 chore: remove redundant words in comment (#17753) 2025-08-11 18:41:38 +02:00
Matthias Seitz
0b1c94a150 feat: add op db access example (#17796) 2025-08-11 15:45:53 +00:00
Femi Bankole
3e0ceda9f1 feat: persist origin on pooled tx backup for propagation setting (#17756)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-11 15:13:45 +00:00
Max Bytefield
76c4c02edb chore: replace ~/.cargo with $CARGO_HOME (#17776) 2025-08-11 14:46:13 +00:00
Max Bytefield
69a1951f54 docs: add optimism Access-list spec (#17775) 2025-08-11 11:32:32 +00:00
Max Bytefield
1ba9e680bc fix: reth dev node implement the --block-max-transactions arg (#17784)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-11 11:28:49 +00:00
colin
42ae8beee6 fix(network): push header before next header check in get_headers_response (#17766)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-11 10:16:54 +00:00
github-actions[bot]
6260c10c52 chore(deps): weekly cargo update (#17777)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-11 11:09:23 +02:00
georgehao
31dd1334e6 docs: remove deprecated difficulty check comment (#17781) 2025-08-11 08:42:50 +00:00
Matthias Seitz
5f0d33425e chore: msrv 1.88 (#17782) 2025-08-10 15:51:26 +00:00
Wolfgang Welz
d8f9f05e2c fix: add validation against parent header in reth-stateless (#17754) 2025-08-08 21:54:12 +00:00
morito
a9cd3fc83c chore: Fix typo tx_inf -> tx_info (#17763) 2025-08-08 18:12:27 +00:00
Snezhkko
c23e533779 refactor(witness): remove unnecessary curly braces in closure (#17752)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-08-08 02:55:10 +00:00
Brian Picciano
82bbed9795 feat: nix flake (#17757)
Co-authored-by: rob <mdnlss@outlook.com>
Co-authored-by: mdnlss <rob73hall@gmail.com>
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-08-07 23:34:07 +00:00
Micke
9862481f18 fix(stages): use correct block number in error message (#17751) 2025-08-07 13:52:48 +00:00
Dan Cline
59e4a5556f feat(grafana): add state root duration histogram graph (#17745) 2025-08-06 22:23:50 +00:00
Fibonacci747
b5e65926a0 fix: add missing semicolon in wallet generation loop (#17739) 2025-08-06 18:30:18 +00:00
Matthias Seitz
baa03294cf fix: enforce propagate on getpooledtx (#17720)
Co-authored-by: Bharath Vedartham <vedabharath12345@gmail.com>
2025-08-06 20:18:05 +02:00
Arsenii Kulikov
f5c2502f55 feat: delay block -> payload conversions (#17681) 2025-08-06 17:53:37 +00:00
Léa Narzis
a4e85841d8 feat(chain-state): add IndexedTx helper (#17737) 2025-08-06 17:24:32 +00:00
queryfast
49f7543aa2 chore: remove redundant word in comment (#17728)
Signed-off-by: queryfast <queryfast@outlook.com>
2025-08-06 16:38:47 +00:00
Léa Narzis
bf2700aa3e feat: add jovian to OpChainSpec (#17671)
Co-authored-by: Emilia Hane <emiliaha95@gmail.com>
2025-08-06 11:14:04 +00:00
Matthias Seitz
62425b2643 chore: feature gate async (#17734) 2025-08-05 23:37:30 +00:00
radik878
f3a42bce55 fix: typo in file deletion error message (#17729) 2025-08-05 23:33:59 +00:00
Matthias Seitz
4f6f97d422 chore: rm trie dep (#17732) 2025-08-05 21:37:57 +00:00
Danno Ferrin
f052c46b84 feat: Execute execution-apis-tests in e2e tests (#17708) 2025-08-05 20:55:05 +00:00
Skanda Bhat
4d96ea0343 test(generators): add topics_count parameter to random_receipt (#17718) 2025-08-05 20:53:32 +00:00
Dan Cline
ac83c27531 fix(db-common): compute state root when initializing from genesis (#17731) 2025-08-05 20:30:30 +00:00
Danno Ferrin
944a5fc19f fix: execution-apis eth_syncing should return false (#17730) 2025-08-05 17:47:35 +00:00
Morty
48941e6db5 fix(GPO): calculate max_tx_gas_used corner case (#17679) 2025-08-04 21:58:02 +00:00
Alexey Shekhirin
1aee213133 deps: bump libmdbx to 0.13.7 (#17727)
Co-authored-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
2025-08-04 21:49:29 +00:00
Matthias Seitz
4db6adfedd chore: fix clippy docs (#17726)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-08-04 20:25:09 +00:00
Bharath Vedartham
6c37ef5635 chore: add flag to disable txpool gossip (#17724) 2025-08-04 18:23:20 +02:00
Matthias Seitz
d5f59070bb test: add ordering test (#17703) 2025-08-04 05:57:02 +02:00
github-actions[bot]
cf3ab02b2f chore(deps): weekly cargo update (#17716)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-08-03 08:35:33 +00:00
nk_ysg
3a201c24bd test(exex): add advance backfill range test (#17714) 2025-08-02 17:52:08 +00:00
Matthias Seitz
6234f61c35 fix: forward unknown hashes pre bedrock (#17709) 2025-08-01 22:14:00 +00:00
stevencartavia
f74efdb02b chore: fix clippy warnings (#17707) 2025-08-01 20:37:25 +00:00
Matthias Seitz
8553bf9cda feat: add all_transaction_hashes (#17700) 2025-08-01 18:37:20 +00:00
Federico Gimenez
db779ed9db fix: feature-gate std-only methods in sparse trie (#17706) 2025-08-01 17:10:24 +00:00
Federico Gimenez
7d660b57b0 refactor: move BasicEngineValidator creation into EngineApiValidatorBuilder trait (#17664)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-08-01 17:08:00 +00:00
Léa Narzis
2170f1b97e test(op-chainspec): add isthmus checks (#17698) 2025-08-01 11:08:24 +00:00
Matthias Seitz
54a4a23f64 fix: skip pending tx updates with higher prio value (#17699) 2025-07-31 18:55:08 +00:00
Matthias Seitz
3a2bf263d7 fix(txpool): also emit promoted pending tx on pool drift (#17695) 2025-07-31 18:54:44 +00:00
Dan Cline
ed56417237 feat(trie): add blinded node metrics in ProofTaskManager (#17685) 2025-07-31 18:54:38 +00:00
Léa Narzis
575a99fd22 chore: bump alloy-op-hardforks and op-alloy (#17697) 2025-07-31 17:57:56 +00:00
0xMushow
0f1ff20926 fix(config): default back gas limit to 45M on mainnet (#17690) 2025-07-31 11:44:59 +00:00
Matthias Seitz
f0051e1016 fix: use primitive header type for fetching header (#17691) 2025-07-31 11:37:40 +00:00
Arsenii Kulikov
568a7e065d refactor: stream transactions while executing payload (#17661) 2025-07-31 11:37:10 +00:00
Emilia Hane
98e30d4340 chore(sdk): Add example for building offline TraceApi with node builder (#17682)
Co-authored-by: ongyimeng <ongyimeng@gmail.com>
2025-07-31 09:39:37 +00:00
Acat
6c7f7f7e54 fix(pool): optimize canonical state change benchmark (#17688) 2025-07-31 09:08:18 +00:00
Matthias Seitz
dd3479ff62 chore: rm clone for witness (#17684) 2025-07-30 23:20:27 +00:00
Dan Cline
6a587a23e9 perf(trie): reuse allocated trie input in payload processor (#17371) 2025-07-30 21:05:35 +00:00
Dan Cline
26173f99b8 feat(trie): add ParallelSparseTrieMetrics (#17405) 2025-07-30 21:05:16 +00:00
Andrea Cerone
3772535220 fix: RPC: feeHistoryEntry should return 0.0 when blob_params.max_blob_count is zero (#17669)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-30 15:15:46 +00:00
stevencartavia
7001f7a33d feat: convert BlockExecutionErrors (#17573) 2025-07-30 12:44:20 +00:00
Sergey Melnychuk
dd4b2869d3 docs(example): extract full contract state from db (#17601)
Co-authored-by: sergey-melnychuk <sergey-melnychuk@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-30 11:36:30 +00:00
Ishika Choudhury
dac5868a10 feat: tracked State for local pending block (#17600)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-30 10:35:33 +00:00
Dan Cline
938d589b52 feat(merkle): add IntermediateRootState for storage root progress (#17548) 2025-07-30 01:09:36 +00:00
Matthias Seitz
a5f2d58650 perf: remove redundant metrics update (#17660) 2025-07-30 01:07:41 +00:00
Haardik
32e27c04df fix: createtx_env after applying state overrides for estimate_gas (#17668) 2025-07-29 18:29:42 +00:00
Soubhik Singha Mahapatra
056ae2abce feat: added max-readers flag for db (#17663) 2025-07-29 14:47:59 +00:00
Shiyas Mohammed
6923e051ee refactor(cli): replace From<Header> with CliHeader trait (#17656)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-29 14:04:31 +00:00
Brian Picciano
489f262d95 docs(trie): update ParallelSparseTrie documentation (#17538)
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
2025-07-29 11:05:42 +00:00
Matthias Seitz
12fb913383 perf: add benchmark for on_canonical_state_change (#17645) 2025-07-29 13:04:30 +02:00
Matthias Seitz
e38e247b40 perf: box larger futures (#17633) 2025-07-29 12:51:19 +02:00
Federico Gimenez
60bbd66319 refactor: move invalid block hook creation from LaunchContext to AddOnsContext (#17655) 2025-07-29 10:12:39 +00:00
Federico Gimenez
6487f0b906 feat: separate EngineValidator from PayloadValidator (#17641) 2025-07-29 07:24:16 +00:00
Matthias Seitz
f517e0159f perf: only notify if we have listeners (#17651) 2025-07-29 01:29:02 +02:00
Matthias Seitz
92020d9eb6 perf: can shortcircuit here if no peers (#17650) 2025-07-29 01:28:42 +02:00
Matthias Seitz
9ebe4e5653 chore: only cast basefee once (#17648) 2025-07-28 22:19:33 +00:00
Matthias Seitz
6e148e6b54 perf(txpool): rm unused best bijection (#17649) 2025-07-28 22:02:38 +00:00
Matthias Seitz
7ff8f3fff2 perf: avoid redundant notifications (#17647) 2025-07-28 21:22:34 +00:00
Léa Narzis
6430535dd6 fix(era-test): fix integration tests for era (#17646) 2025-07-28 19:53:35 +00:00
Brian Picciano
7f2bdbbdf8 perf(trie): Process multiproof reveals for storage tries in parallel (#17440) 2025-07-28 16:35:44 +00:00
strmfos
b1f1e9d711 docs: fix doc comments: clarify downloaded bytes and builder return condition (#17566) 2025-07-28 14:25:30 +00:00
Arsenii Kulikov
9d1af5a09c refactor: introduce Enginvalidator in tree (#17598)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-28 09:09:55 +00:00
Arsenii Kulikov
d392c3fdf2 chore: relax Cli::run_with_components (#17630) 2025-07-28 09:07:25 +00:00
github-actions[bot]
7ed3ab0ec6 chore(deps): weekly cargo update (#17628)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-27 16:40:27 +00:00
MozirDmitriy
812dd04b80 fix: correct comment for is_latest_invalid method (#17621) 2025-07-27 10:28:18 +00:00
crStiv
e63dafb3b5 docs: fix typos (#17624) 2025-07-26 14:39:23 +00:00
Matthias Seitz
8796a77cfa feat: support any network type in eth api builder (#17617)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-26 11:51:42 +00:00
anim001k
5748cf92a1 fix: Benchmarking Link in database.md (#17553) 2025-07-26 11:34:15 +00:00
Léa Narzis
3f3ccc3aa8 chore: remove duplicate deps (#17618) 2025-07-26 10:11:17 +00:00
Federico Gimenez
73091305ac chore: make clippy happy (#17620) 2025-07-26 09:53:49 +00:00
Starkey
0a416d33d7 docs: correct error comments in networking optimism modules (#17602) 2025-07-25 14:46:24 +00:00
Mablr
c549188a93 feat(rpc): add method to configure custom tokio runtime for RPC server (#17611) 2025-07-25 14:35:36 +00:00
Emilia Hane
a7cbf81b65 test(sdk): Add test for using node builder with noop components (#17560) 2025-07-25 11:34:24 +00:00
Léa Narzis
de5cbfe4cc test(era1): add more Receipt tests to verify decoding (#17592) 2025-07-25 11:31:41 +00:00
Matthias Seitz
876e964cbc chore: introduce engine module (#17591) 2025-07-24 08:42:18 +00:00
sashaodessa
dc90eb2ffe fix: typo in Cargo.toml (#17588) 2025-07-24 01:00:25 +00:00
Daniel Ramirez
e29707f0ee feat: Add IPC socket permission configuration (#17497)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-23 23:10:53 +00:00
Arsenii Kulikov
6b23818c76 refactor: small simplifications for tree types (#17589) 2025-07-23 22:39:36 +00:00
Micke
eaaf1ab4d8 fix: remove extra space in PostStateRootMismatch error message (#17590) 2025-07-23 20:41:57 +00:00
Starkey
bf36f95211 docs: fix the parameters (#17586) 2025-07-23 18:40:24 +00:00
Federico Gimenez
8bd6bf5dc1 feat(engine): add validate_payload and validate_block methods to EngineValidator trait (#17429) 2025-07-23 13:46:41 +00:00
Matthias Seitz
a72fe7a2d0 chore: move validation to standalone fns (#17582) 2025-07-23 13:44:33 +00:00
Matthias Seitz
9ff444ea9e fix(txpool): enforce encoded length check (#17581) 2025-07-23 13:34:51 +00:00
Tomass
c986441d87 fix: correct prune mode assignments in HistoryIndexingStages (#17575) 2025-07-23 13:03:18 +00:00
Arsenii Kulikov
ff76f66cd7 feat: abstraction for attributes -> NextBlockEnv conversion (#17570) 2025-07-23 11:39:38 +00:00
Léa Narzis
2c5a967898 feat(era): add era types (#17477) 2025-07-23 11:28:17 +00:00
Federico Gimenez
ed8eacfc5b refactor: move EngineValidator trait to reth-engine-tree (#17559) 2025-07-23 11:25:58 +00:00
Federico Gimenez
42c1947c8a chore(hive): update expected failures (#17580) 2025-07-23 10:10:23 +00:00
Federico Gimenez
81e0cb0385 feat(ci): add ignored tests management to hive workflow (#17577) 2025-07-23 10:01:52 +00:00
Rez
752637a5d7 feat: make CompactEnvelope trait public for external crate usage (#17576) 2025-07-23 08:10:14 +00:00
Alexey Shekhirin
58235419bb feat(reth-bench): add gas throughput chart to python script (#17572)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-22 18:51:11 +00:00
Léa Narzis
a1a4f2df7a refactor: use alloy Log::collect_for_receipt instead of macro to collect logs (#17569) 2025-07-22 17:19:12 +00:00
Federico Gimenez
8ce656f834 feat: add TreePayloadValidator (#17451) 2025-07-22 16:55:36 +00:00
Hai | RISE
868c421c5d feat(pool): return state of an added tx (#17442) 2025-07-22 14:51:03 +00:00
0xOsiris
c2098faea3 feat: make basic block builder pub (#17476) 2025-07-22 14:50:18 +00:00
nk_ysg
c1bfa31444 chore: rm unused file (#17563) 2025-07-22 14:50:07 +00:00
Amidamaru
2446c2fd42 perf: process chunks in par for get logs in block range eth_getLogs (#16675) 2025-07-22 14:41:39 +00:00
nk_ysg
ca645b40ee fix(exex): update batch threadshold calculate processed blocks (#17551) 2025-07-22 13:35:16 +00:00
Matthias Seitz
d8451e54e7 chore: bump version v1.6.0 (#17556) 2025-07-22 15:32:51 +02:00
Matthias Seitz
4fb1b8a614 ci: fix era sync test (#17561) 2025-07-22 12:51:59 +00:00
Alexey Shekhirin
a0de7f875e fix: convert latency to milliseconds in reth-bench script (#17555)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-22 11:22:49 +00:00
Arsenii Kulikov
53df3b803a feat: add AddOns for custom node example (#17544) 2025-07-22 13:04:37 +02:00
Matthias Seitz
48617dc33c ci: mark system eest tests as passing (#17542) 2025-07-22 12:58:20 +02:00
Matthias Seitz
3ab5bac40c chore: bump deps (#17554) 2025-07-22 12:57:48 +02:00
adust
58e6113584 feat: implement DatabaseProviderFactory for NoopProvider (#17134)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Emilia Hane <elsaemiliaevahane@gmail.com>
2025-07-22 09:34:53 +00:00
Arsenii Kulikov
7b76a1e00f chore: relax EthereumEthApiBuilder bound (#17546) 2025-07-22 08:47:27 +00:00
Alexey Shekhirin
39f1ee8795 feat(reth-bench): auto-create output directory (#17541)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-21 20:18:45 +00:00
Matthias Seitz
f532e49d2d chore(deps): bump inspectors 027 (#17543) 2025-07-21 20:17:46 +00:00
David Klank
1eff10d871 docs: fix typo in OpReceiptBuilder comment (#17540) 2025-07-21 18:11:34 +00:00
Brian Picciano
566ff51d04 perf(trie): Re-use storage tries across payloads (#17488)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-21 16:32:31 +00:00
PixelPilot
8c50d84187 docs: Fix broken fuzzing module link in database.md (#17523) 2025-07-21 15:17:54 +00:00
Arsenii Kulikov
0a8cb95eb9 feat: EthApiCtx::eth_api_builder (#17532) 2025-07-21 14:51:46 +00:00
Arsenii Kulikov
94c1c3f078 feat: ComponentsFor type alias (#17533) 2025-07-21 14:51:40 +00:00
cakevm
4bd2fd2dac refactor: rename AlloyRethProvider to RpcBlockchainProvider and move to storage (#17524) 2025-07-21 13:59:03 +00:00
Arsenii Kulikov
818e01773a feat: HeaderConverter (#17490)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-21 13:46:48 +00:00
Matthias Seitz
8f26b95643 chore: bump alloy-evm 015 (#17528) 2025-07-21 13:30:13 +00:00
Matthias Seitz
42f791924a fix: ensure required revm features are activated (#17526) 2025-07-21 12:34:33 +00:00
Matthias Seitz
5bc8589162 chore: extend exex ethapi example (#17481) 2025-07-21 14:50:04 +02:00
Matthias Seitz
84387f7c97 chore: sanity secp256k1+rayon activations (#17527) 2025-07-21 14:48:27 +02:00
Rez
ac2974867f feat: make payload validation functions generic over block header type (#17520) 2025-07-21 10:55:47 +00:00
Arsenii Kulikov
0b1f25e56e fix: logIndex in getBlockReceipts (#17519) 2025-07-21 12:40:45 +02:00
Avory
4639f94535 docs(trace): document trace format and response structure (#17517) 2025-07-21 09:44:27 +00:00
AJStonewee
5b01ca7738 docs: normalize dynamic CLI defaults in help generation (#17509) 2025-07-21 09:38:26 +00:00
Fallengirl
52a627bf4d docs: fix error in RawCapabilityMessage comment (#17411) 2025-07-21 09:36:32 +00:00
anim001k
a49fef80c1 fix: temporary file leak in atomic_write_file (#17505) 2025-07-21 09:30:24 +00:00
maradini77
c1ff79c074 fix: Refine Transaction Abstraction Link (#17502) 2025-07-21 09:28:32 +00:00
cakevm
c78f7e4501 feat(alloy-provider): compatibility for non-reth nodes (#17511) 2025-07-21 09:19:04 +00:00
Micke
54855e1798 docs: fix Sepolia URL description (#17495) 2025-07-21 09:17:38 +00:00
Matthias Seitz
bec451026d chore: migrate from codespell to typos (#17501) 2025-07-21 11:18:01 +02:00
Matthias Seitz
2c62cd8b46 ci: dont expect callenv to fail (#17516) 2025-07-21 11:14:46 +02:00
cakevm
8f38b42e3f feat(alloy-provider): implement receipts_by_block and other methods (#17507) 2025-07-20 11:04:48 +00:00
github-actions[bot]
1175f6c178 chore(deps): weekly cargo update (#17506)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-07-20 09:14:55 +00:00
anim001k
03ceac7e79 fix: refactor trace log key and comment formatting (#17459) 2025-07-19 11:08:34 +00:00
viktorking7
627658bda0 fix: correct documentation for block_mut method in SealedBlock (#17489) 2025-07-19 06:58:50 +00:00
NeoByteX
c1a33a2e6e docs: fix outdated file paths in database.md links (#17486) 2025-07-19 06:52:59 +00:00
Dan Cline
f0572fc9d3 perf(tree): add metric for payload conversion + validation latency (#17499) 2025-07-19 06:44:39 +00:00
Matthias Seitz
b0aed0dded fix: force set basefee to 0 if gasprice is 0 (#17496) 2025-07-18 18:12:43 +00:00
Matthias Seitz
81b93ac58b chore: downgrade threadpool init error (#17483) 2025-07-18 18:02:51 +00:00
cakevm
2ced409141 feat(alloy-provider): implement methods for BlockReaderIdExt (#17491) 2025-07-18 16:37:10 +00:00
ongyimeng
623920c63d fix: set correct timestamp when calculating basefee (#17493)
Co-authored-by: rose2221 <rose.jethani@nethermind.io>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-18 16:06:37 +00:00
ongyimeng
537ffeacac feat: continue opchainspec support (#17422)
Co-authored-by: rose2221 <rose.jethani@nethermind.io>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-18 14:44:28 +00:00
Brian Picciano
8fb0fbba73 chore: fix reth-engine-tree dev-dependencies import (#17487) 2025-07-18 14:27:18 +00:00
cakevm
0aef0c35c8 feat(alloy-provider): implement receipt_by_hash method (#17456) 2025-07-18 12:20:25 +00:00
Femi Bankole
0f449f2b39 feat: add Middleware generic to AuthServerConfig (#17373)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-18 11:54:36 +00:00
Rez
1b6f72321a feat: enable CLI support for custom block headers (#17441) 2025-07-18 10:21:51 +00:00
Matthias Seitz
ca116aa7b7 docs: add code example to extend_rpc_modules method (#17446)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jennifer <jenpaff0@gmail.com>
2025-07-18 09:57:07 +00:00
luory ✞
3c9ff6e157 fix: change hyperlink to reth_codec (#17437) 2025-07-18 09:56:59 +00:00
o-az
e089d902ca fix: edit link and config (#17453)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-18 09:30:52 +00:00
cakevm
3add4b1e3d feat(alloy-provider): implement transaction_by_hash method (#17479) 2025-07-18 09:14:12 +00:00
Matthias Seitz
87000e3359 chore: expose chainspec getter (#17461) 2025-07-18 11:14:36 +02:00
Yash Atreya
6927afac16 fix(docs): rustdocs module and nested links (#17478) 2025-07-18 07:49:38 +00:00
Matthias Seitz
65a63e129e feat: add envelope conversion for op (#17469) 2025-07-17 18:48:50 +00:00
Yash Atreya
0fff798cb6 fix(docs): change sdk overview path to /sdk (#17467) 2025-07-17 17:41:22 +00:00
bigbear
d4d3e22f79 fix: correct documentation for block_mut method in RecoveredBlock (#17472) 2025-07-17 15:47:55 +00:00
cakevm
1912ac7547 feat(alloy-provider): implement bytecode_by_hash method (#17471) 2025-07-17 15:39:47 +00:00
Matthias Seitz
425541d5a6 fix: use primitives headers for pruner (#17458) 2025-07-17 14:03:15 +00:00
Arsenii Kulikov
05fed6f991 feat: add helper for building pending block env (#17464) 2025-07-17 14:00:13 +00:00
cakevm
61a19c1bcb feat(alloy-provider): implement sealed_header method (#17455) 2025-07-17 13:56:21 +00:00
Léa Narzis
0b1d950f67 feat(tx-pool): add submit methods to TransactionPool (#17431) 2025-07-17 13:46:10 +00:00
strmfos
237e97ab83 docs: fix typo from optstack to opstack (#17454) 2025-07-17 13:41:33 +00:00
Arsenii Kulikov
7ccb37ebe3 refactor: move receipt conversions to RpcConverter (#17450) 2025-07-17 13:19:30 +00:00
cakevm
2afd109816 chore: correct spelling errors (#17462) 2025-07-17 13:19:19 +00:00
Rez
824e099055 feat: make engine API metered methods and utilities public (#17460) 2025-07-17 11:48:46 +00:00
Tomass
1e20871043 docs: fix typo in NetworkManager diagram (#17448) 2025-07-16 15:40:52 +00:00
Brian Picciano
802be64ef8 perf(trie): parallelize ParallelSparseTrie::reveal_nodes (#17372) 2025-07-16 15:22:32 +00:00
maradini77
825222f3b0 fix: Update JWT Secret Flag in Benchmark Documentation (#17447) 2025-07-16 14:46:18 +00:00
Matthias Seitz
f86959f4c1 docs: enhance direct database access documentation (#17445)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-16 14:38:10 +00:00
anim001k
2d1f8cdea1 fix: rename highest_static_fileted_block to highest_static_file_block (#17427) 2025-07-16 14:26:39 +00:00
viktorking7
fdefed3d79 fix: Update Docker Compose Docs Link in etc/README.md (#17414) 2025-07-16 13:44:06 +00:00
maradini77
8cbd119940 fix: Rename WitnessBlindedProvider to WitnessTrieNodeProvider (#17426) 2025-07-16 13:13:04 +00:00
Alexey Shekhirin
c01f230ffb chore(bin): missing --jwt-secret message in reth-bench (#17443) 2025-07-16 13:11:17 +00:00
cakevm
1179da2222 chore: simplify blob count extraction using new blob_count() method (#17439) 2025-07-16 10:56:13 +00:00
Rez
8e5efb36c3 feat: make revm_spec generic over header type (#17436) 2025-07-16 10:53:13 +00:00
Matthias Seitz
2643324668 chore: bump revm 273 (#17412) 2025-07-16 12:53:48 +02:00
adust
b0d05b69e2 refactor: remove unused sparse trie methods (#17433)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-16 08:00:16 +00:00
Dan Cline
76b19f37ab chore(consensus): refactor fork and ommers check into standalone fn (#17406) 2025-07-15 19:17:23 +00:00
Matthias Seitz
5d72088ecd chore: add txpool submit examples (#17420) 2025-07-15 17:34:06 +02:00
Alexey Shekhirin
cd737052c3 test(engine): enable parallel sparse trie in e2e tests (#17423) 2025-07-15 15:15:06 +00:00
maradini77
4364cd09bc refactor: use DefaultTrieNodeProviderFactory in state root calculation (#17425) 2025-07-15 14:57:33 +00:00
Matthias Seitz
55fa57bb11 chore: box import future (#17424) 2025-07-15 14:43:51 +00:00
Aliaksei Misiukevich
fe1d2d2425 refactor: BlindedPovider rename (#17208)
Signed-off-by: Aliaksei Misiukevich <taberlick@gmail.com>
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-07-15 12:40:52 +00:00
fantasyup
fb9f3cce92 feat: Add support for ethstats (#16396)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-15 10:56:43 +00:00
Dan Cline
c667bc972e chore(txpool): use alloy-primitives HashMap for SenderIdentifiers (#17408) 2025-07-15 10:10:24 +00:00
Federico Gimenez
00d259dbea feat(sdk): make engine API (auth server) optional for custom consensus integrations (#17376) 2025-07-15 09:28:21 +00:00
cakevm
13c59dc1c4 feat(alloy-provider): implement header methods (#17402) 2025-07-15 09:20:58 +00:00
Yash Atreya
13d3d9b577 fix(docs): rustdoc search functionality (#17410)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-15 09:16:27 +00:00
Rez
253721d226 feat: add generic database support for Receipt<T> (#17409) 2025-07-15 09:13:14 +00:00
Roman Hodulák
73f2edb90c feat(rpc): Use generic transaction request as input (#17092)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-14 17:46:52 +00:00
Léa Narzis
52bd07b8fd refactor(rpc): change receipt to Cow<R> for build_receipt (#17382) 2025-07-14 17:15:55 +00:00
Léa Narzis
f83e29cdd3 docs(guides): add export era in history section (#17391) 2025-07-14 16:45:42 +00:00
Matthias Seitz
61bbe5ee29 perf: release listner lock early (#17400) 2025-07-14 15:23:10 +00:00
Acat
44cc67be00 perf: optimize txpool_status RPC by avoiding full transaction collection (#17392)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-14 14:07:32 +00:00
Acat
b9c63f6a10 fix(txpool): Propagate promoted transactions on account updates (#17396)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-14 11:55:08 +00:00
Matthias Seitz
4edd55aacd chore: make clippy happy (#17399) 2025-07-14 11:05:20 +00:00
github-actions[bot]
b19b1b0790 chore(deps): weekly cargo update (#17386)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-07-14 12:19:39 +02:00
nekomoto911
332c656617 perf(blob): optimize blob store gets (#17388) 2025-07-13 09:44:18 +00:00
maradini77
e5e42e79f9 fix: broken link to system requirements in troubleshooting guide (#17384) 2025-07-13 09:03:41 +00:00
Matthias Seitz
b08586946c chore: consolidate typo fixes from multiple PRs (#17387) 2025-07-13 08:57:45 +00:00
crStiv
e010ec290a docs: typos (#17283) 2025-07-13 08:35:00 +00:00
Léa Narzis
ac5d335796 feat: add into_logs() to TxReceipt for Receipt/OpReceipt (#17383) 2025-07-13 08:24:00 +00:00
crStiv
4767e1c251 docs: typos (#17335)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-12 15:55:12 +00:00
otc group
e9389dc640 docs: fix link to installation (#17375)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-12 13:44:56 +02:00
Léa Narzis
1d6a830803 feat: make Receipt generic over TxType (#17237)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-12 06:49:36 +00:00
Alexey Shekhirin
80767f1f30 perf(engine): clear accounts trie in background to not block state root (#17369) 2025-07-11 17:17:51 +00:00
Yash Atreya
f6839ac352 fix(docs): rustdocs search functionality (#17367) 2025-07-11 15:28:29 +00:00
Federico Gimenez
99baeeb413 chore(ci): unpin hive (#17370) 2025-07-11 13:27:07 +00:00
Dan Cline
96f8faf8f0 feat(trie): wire parallel trie config to PayloadProcessor (#17355) 2025-07-11 13:26:22 +00:00
Tomass
2060813af5 docs:fix spelling error in flowchart (#17346) 2025-07-11 12:41:34 +00:00
Dan Cline
bcc9ed461e chore(trie): impl HashedPostState::drain_into_sorted (#17362) 2025-07-11 12:05:15 +00:00
Dan Cline
00d117dd3e chore(trie): impl TrieUpdates::drain_into_sorted (#17361) 2025-07-11 12:05:03 +00:00
Yash Atreya
88ce599f65 fix(docs): update-book-cli job (#17365) 2025-07-11 11:05:51 +00:00
Dan Cline
cbf2ceb344 chore(consensus): remove outdated comment from validate_block_pre_execution (#17360) 2025-07-11 10:27:58 +00:00
Arsenii Kulikov
ea35ebfda2 feat: make ethereum Cli generic over node and remove debug commands (#17363) 2025-07-11 10:07:38 +00:00
Brian Picciano
98c68c1f8a perf(trie): reuse update action buffers in parallel sparse trie processing (#17352) 2025-07-11 09:28:45 +00:00
Federico Gimenez
f148cb3199 feat(rpc): specialise contiguous receipt queries for logs (#16441)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-11 09:21:08 +00:00
Dan Cline
06a7d05649 feat(cli): add enable-parallel-sparse-trie flag (#17357)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-07-10 23:47:25 +00:00
Arsenii Kulikov
4560ac4fe7 feat: support isthmus in reth-bench (#17351) 2025-07-10 23:43:32 +00:00
Dan Cline
a1dd69ee0e feat(trie): add TrieUpdates::clear (#17359) 2025-07-10 22:57:06 +00:00
Dan Cline
2b142fb198 feat(trie): add HashedPostState::clear (#17358) 2025-07-10 22:57:00 +00:00
Matthias Seitz
e263daebce chore: broadcast raw tx for opethapi (#17342) 2025-07-10 22:04:24 +00:00
Matthias Seitz
5479e115f9 chore: add helper to access invalid tx error (#17353) 2025-07-10 21:43:21 +00:00
Matthias Seitz
ee11b424fc chore: add helper convert into error object (#17354) 2025-07-10 21:05:03 +00:00
Dan Cline
2bf4646e2d chore(trie): add Either type for SparseTrieInterface (#17267) 2025-07-10 20:31:43 +00:00
fuder.eth
4668614f41 fix: Typographical Errors in Comments (#17333) 2025-07-10 20:24:38 +00:00
Amidamaru
ccc1493848 chore: make OpAddonsBuilder generic over middleware (#17347) 2025-07-10 20:00:01 +00:00
Matthias Seitz
2813776d4e chore: add helpers for disabling read-tx timeout (#17339)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-10 15:48:19 +00:00
Brian Picciano
6561e8ff46 chore(trie): Implement ParallelSparseTrie::find_leaf (#17326) 2025-07-10 15:04:29 +00:00
Brian Picciano
d7aa751379 feat: add graph selection option to newpayload latency comparison script (#17097) 2025-07-10 13:42:27 +00:00
Dan Cline
c274422bba feat(trie): add generics to SparseTrieTask (#17269)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-07-10 12:45:14 +00:00
Léa Narzis
60c86aeca2 feat(era1): add subcommand export-era (#17132)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-10 12:37:17 +00:00
Alexey Shekhirin
da2ab711d3 refactor: rename RevealedSparseTrie to SerialSparseTrie (#17345) 2025-07-10 12:06:29 +00:00
Federico Gimenez
26b7258d57 feat(ci): reorganize e2e tests with dedicated nextest filter and CI workflow (#17290) 2025-07-10 10:41:48 +00:00
Arsenii Kulikov
1a7c335a60 feat: re-execute command (#17330) 2025-07-10 10:21:51 +00:00
Yash Atreya
ea944fa75a fix(docs): broken rustdocs link (#17341) 2025-07-10 09:33:25 +00:00
Alexey Shekhirin
0f49e35fbb fix(trie): reset hashes of nodes along the path of removed leaf (#17331)
Co-authored-by: Brian Picciano <me@mediocregopher.com>
2025-07-10 09:27:23 +00:00
Matthias Seitz
0326dab81c chore: replace CacheDb with trait bounds (#17315) 2025-07-10 11:34:18 +02:00
Matthias Seitz
b3d722f1fd chore: simplify receipt envelope conversion (#17337) 2025-07-09 22:46:57 +00:00
Matthias Seitz
e3d2632be2 chore: remove type hints (#17336) 2025-07-09 22:46:46 +00:00
Matthias Seitz
b317431b77 chore: make tracer match non-exhaustive (#17338) 2025-07-09 22:29:23 +00:00
Matthias Seitz
4cd0c0d613 test: allow empty response (#17332) 2025-07-09 23:19:42 +02:00
Roman Krasiuk
959323fa6f feat(sync): track time spent in stages (#17321) 2025-07-09 22:44:49 +02:00
Léa Narzis
73f820af40 feat(sdk): add local_payload_attributes_builder to DebugNodeLauncher (#17297)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-09 19:19:25 +02:00
Alexey Shekhirin
9ec522d914 fix(trie): move masks to ParallelSparseTrie level (#17322)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-09 15:06:55 +00:00
Brian Picciano
7195eca1cb fix(trie): ParallelSparseTrie::update_leaf: add moved leaves to the prefix set (#17317) 2025-07-09 14:58:04 +00:00
nekomoto911
0cbb4823c9 perf(txpool): reduce one BTree lookup operation in add_transaction (#17313) 2025-07-09 14:52:44 +00:00
Alexey Shekhirin
b0cf23af44 fix(trie): duplicate hash mask check in sparse trie implementations (#17316)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-09 13:52:10 +00:00
Matthias Seitz
7e3eb03939 docs: add section for enabling pre-merge history expiry (#17320) 2025-07-09 15:44:15 +02:00
catconcat
700b1fd312 feat: make build_receipt infallable (#17287)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-09 13:29:46 +00:00
Matthias Seitz
e15be6584c chore: bump vdocs version (#17318) 2025-07-09 13:23:00 +00:00
Matthias Seitz
162568b297 chore: relax era export bounds (#17312) 2025-07-09 12:26:08 +02:00
Fallengirl
9d8248528b fix: correct typos (#17296) 2025-07-09 10:05:03 +00:00
Bilog WEB3
9a2c66a508 fix(docs): correct duplicated function reference in documentation (#17301) 2025-07-09 09:44:35 +00:00
stevencartavia
e238fc4823 feat: add --prune.receipts.premerge setting (#17295) 2025-07-09 09:14:39 +00:00
Starkey
818712124b docs: myrpc_ext.rs: fix namespace inconsistency in myrpcExt comments (#17300) 2025-07-09 09:10:22 +00:00
Roman Hodulák
cb42ac94b5 refactor(examples): Use TransactionEnvelope macro from alloy for CustomPooledTransaction in the custom-node example (#17302) 2025-07-09 09:09:10 +00:00
Dan Cline
15c6562636 chore(trie): remove Default bound from SparseTrieInterface (#17268) 2025-07-08 18:44:27 +00:00
Federico Gimenez
3ba16128af feat(test): add rpc e2e tests (#17284) 2025-07-08 17:23:14 +00:00
Roman Krasiuk
038ddd6614 perf: remove block cloning from is_descendant check (#17286) 2025-07-08 16:58:40 +00:00
Dan Cline
34f1a606b7 chore(trie): move from_root out of SparseTrieInterface (#17266) 2025-07-08 16:23:57 +00:00
Alexey Shekhirin
34b1d3d5cf ci: add https:// to image URLs in release.yml (#17280) 2025-07-08 13:51:31 +00:00
Alexey Shekhirin
eaf2e50f0f test(trie): add sparse trie tests to parallel sparse trie (#17258)
Co-authored-by: Brian Picciano <me@mediocregopher.com>
2025-07-08 13:28:54 +00:00
Brian Picciano
bb1e44e8ab fix(trie): ParallelSparseTrie: remove leaves from upper subtrie when update in a lower (#17278) 2025-07-08 11:57:40 +00:00
Matthias Seitz
dbe7ee9c21 chore: bump 1.5.1 (#17277) 2025-07-08 13:31:56 +02:00
Merkel Tranjes
9fe0f25e7b docs: fix correction in storage reverts iterator test comment (#17276) 2025-07-08 11:15:59 +00:00
Roman Hodulák
62c5a57302 docs(guides): Add history expiry (#17274) 2025-07-08 10:31:19 +00:00
Dan Cline
7017627a9f chore(trie): add Send and Sync to SparseTrieInterface (#17270) 2025-07-08 10:15:40 +00:00
Dan Cline
11db28e9b7 feat(trie): add parallel sparse trie to TreeConfig (#17265) 2025-07-08 10:15:04 +00:00
Noisy
68309cac28 docs: update snapshot URL from downloads.merkle.io to snapshots.merkle.io (#17248)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-08 12:14:33 +02:00
Femi Bankole
38f02bb46e feat: include chain-id query param for etherscan v2 API (#17167)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-08 09:56:41 +00:00
Brian Picciano
e9a4222c8a fix(trie): correctly handle path field on cleared ParallelSparseTrie lower subtries (#17259) 2025-07-08 09:45:23 +00:00
Federico Gimenez
557836b93d feat(test): add apply_with_import method to e2e Setup (#17263) 2025-07-08 09:26:27 +00:00
Matthias Seitz
5645659d59 chore: bump alloy (#17275) 2025-07-08 09:24:56 +00:00
GarmashAlex
7c69ab1c8d docs: fix typo basfee → basefee in txpool.mmd (#17252) 2025-07-08 09:23:22 +00:00
VolodymyrBg
af004c0c0d chore: fix typos (#17251) 2025-07-08 09:22:52 +00:00
Galoretka
36d568a404 chore: Fix typo in block number reader comment (#17250) 2025-07-07 23:09:14 +00:00
Brian
1eccb5b7f6 fix: dead link (#17200) 2025-07-07 23:08:48 +00:00
Arsenii Kulikov
78bad34091 chore: check blob fee (#17272) 2025-07-07 23:02:09 +00:00
Matthias Seitz
e4574326ea chore: update size metrics once (#17242) 2025-07-07 21:50:37 +00:00
Alexey Shekhirin
09b4c5e987 fix(trie): add lower subtrie root paths to upper subtrie prefix set (#17262) 2025-07-07 19:56:32 +00:00
Federico Gimenez
e66caca5e9 feat(test): spin up e2e test nodes with imported data (#17261) 2025-07-07 19:13:32 +00:00
Federico Gimenez
dddde9eff9 feat(test): allow to create testing nodes with specific datadir (#17260) 2025-07-07 14:34:38 +00:00
Brian Picciano
468e925077 fix(trie): track branch node updates only in ParallelSparseTrie, not subtries (#17223) 2025-07-07 14:29:19 +00:00
crStiv
927e9c4661 docs: typos (#17246) 2025-07-07 13:38:42 +00:00
James Niken
1f557b399a docs: fix typo fileted to filtered (#17257) 2025-07-07 13:38:13 +00:00
Federico Gimenez
e70f6871b8 refactor: extract import functionality to separate module (#17253) 2025-07-07 13:26:20 +00:00
Alexey Shekhirin
a64dafdb54 fix(trie): ParallelSparseTrie::default should have an empty root node (#17256) 2025-07-07 11:46:23 +00:00
Max Bytefield
44b361a4e2 fix: correct comment in static file writer (#17254) 2025-07-07 09:26:45 +00:00
github-actions[bot]
651f1b97e5 chore(deps): weekly cargo update (#17247)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-07-06 09:42:47 +00:00
Fallengirl
8e800d6f73 docs: deleted extra duplicate environment.rs (#17249) 2025-07-06 09:19:27 +00:00
emmmm
3277333df6 docs: correction comments (#17244) 2025-07-05 10:50:18 +00:00
Udoagwa Franklin
1e9866c858 refactor(rpc): Arc PendingBlock internals (#17240)
Co-authored-by: frankudoags <frankudoags.com>
2025-07-05 08:26:29 +00:00
leopardracer
0592bd06a8 docs: Consistent Spelling for "Reuse" in Documentation (#17232) 2025-07-05 07:38:25 +00:00
bigbear
30a9690a4d fix: correct typo in ValidationApi comment (#17241) 2025-07-05 04:50:14 +00:00
Varun Doshi
beb8fac91b feat: add v5 flashbots relay block validation api for Fusaka (#17179)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-05 04:28:10 +00:00
Udoagwa Franklin
593477c673 refactor(txpool): Remove txhash from PoolUpdate (#17239)
Co-authored-by: frankudoags <frankudoags.com>
2025-07-05 04:24:56 +00:00
Micke
29c1a35e8d docs: fix typo mod.rs (#17233) 2025-07-04 19:12:05 +00:00
Galoretka
e948ab12fc fix: logical error in pruning test for storage_history PruneMode::Full (#17235) 2025-07-04 18:40:15 +00:00
fantasyup
ca36316f3b chore: add capabilities to NetworkStatus (#17236) 2025-07-04 18:13:52 +00:00
fantasyup
dcf3469d56 chore(doc): update exclude list for doc/cli (#17234)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-04 16:44:50 +00:00
Ritesh Das
89d0e6a919 feat(p2p): separate args for (header, body) (#17184)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-04 15:28:12 +00:00
leopardracer
47d2ed55d1 docs: fix typo in documentation comments (#17207) 2025-07-04 14:53:29 +00:00
Matthias Seitz
a46d0c0273 chore: use alloy traits for build receipt (#17211) 2025-07-04 16:52:59 +02:00
Fallengirl
19d4d4f4f3 docs: fix typos across documentation (#17212) 2025-07-04 14:34:25 +00:00
Galoretka
6bf87384ca Fix typo in EVM component documentation (#17227) 2025-07-04 12:53:42 +00:00
GarmashAlex
d101fb7b90 Update metrics documentation link to new official Reth docs (#17220) 2025-07-04 15:01:55 +02:00
Udoagwa Franklin
250f2104ca fix: Returns Arc<RecoveredBlock> in BlockAndReceiptsResult (#17213)
Co-authored-by: frankudoags <frankudoags.com>
2025-07-04 12:43:17 +00:00
Matthias Seitz
9a58ef18a7 chore: load kzg settings in background (#17224) 2025-07-04 12:41:45 +00:00
Arsenii Kulikov
cc46a27ebf chore: make receipt root mismatch log more useful (#17225) 2025-07-04 12:35:49 +00:00
Matthias Seitz
62b1d574e1 docs: improve NodeAddOns trait documentation (#17178)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-04 14:40:18 +02:00
MozirDmitriy
2962f2ea35 chore: fix typo in documentation comment in environment.rs (#17218) 2025-07-04 12:00:17 +00:00
Roman Hodulák
342bab5e82 deps: Upgrade alloy version 1.0.16 => 1.0.17 and all other deps minor versions (#17217)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-04 11:31:28 +00:00
Francis Li
5c47be25c4 feat(txpool): add minimal priority fee configuration for transaction pool (#17183) 2025-07-04 11:22:48 +00:00
Brian Picciano
3b92a23599 chore(trie): make SparseStateTrie generic with respect to trie implementation (#17205)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>
2025-07-04 10:53:28 +00:00
Federico Gimenez
3457358880 chore: make clippy happy (#17219) 2025-07-04 10:35:23 +00:00
Matthias Seitz
e49bbe416e chore: bump evm 0.14 (#17206) 2025-07-03 20:39:13 +00:00
Matthias Seitz
3b1b2a0229 fix: dont double serialize resp (#17204) 2025-07-03 16:11:36 +00:00
Arsenii Kulikov
037be8d7ac chore(test): don't use EvmInternals::new (#17188) 2025-07-03 16:01:00 +00:00
Alexey Shekhirin
d026630746 perf(trie): implement SparseTrieInterface for ParallelSparseTrie (#17192)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-03 15:06:08 +00:00
Alexey Shekhirin
7a8a0da1a5 perf(trie): implement SparseTrieInterface for RevealedSparseTrie (#17191)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-03 15:01:18 +00:00
leopardracer
a550025a8f docs: fix typo in trie test comment (#17199) 2025-07-03 14:24:03 +00:00
Alexey Shekhirin
8c38c8b33a perf(trie): sparse trie trait (#17181)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-03 14:19:57 +00:00
Matthias Seitz
d949061fc0 chore: bump inspectors (#17198) 2025-07-03 15:09:29 +02:00
Brian Picciano
c2a2d7d449 feat(trie): ParallelSparseTrie: Compute lower subtrie hashes in parallel (#17173)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-03 10:03:34 +00:00
crStiv
c6e6a54d5b docs: typos (#17168) 2025-07-03 09:46:32 +00:00
PixelPilot
c2737957d7 docs: update snapshot URL from downloads.merkle.io to snapshots.merkle.io (#17190)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-03 09:30:26 +00:00
Dan Cline
f86445e094 feat(trie): add ParallelSparseTrie::update_leaf (#16956)
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
Co-authored-by: Brian Picciano <me@mediocregopher.com>
2025-07-03 06:00:41 +00:00
Ferran Borreguero
60940dd243 Add bootnode cmd to cli runner (#17180)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-02 16:46:56 +00:00
Matthias Seitz
b286a61db8 chore: relax rpc middleware generic (#17174) 2025-07-02 14:52:16 +00:00
CrazyFrog
f54cef5e28 docs: update Grafana repository URL in monitoring documentation (#17175) 2025-07-02 13:58:42 +00:00
Rez
40fd91a068 feat: expose chain_spec field in LocalPayloadAttributesBuilder (#17151) 2025-07-02 13:55:04 +00:00
Aliaksei Misiukevich
3a3bc5f795 feat: trait impl for dbmock (#17124)
Signed-off-by: Aliaksei Misiukevich <taberlick@gmail.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-07-02 13:00:33 +00:00
Guro
9c045810ad docs: update metrics link in ethereum.mdx (#17170) 2025-07-02 11:38:23 +00:00
Brian Picciano
b1f9f716a8 chore(trie): factor out SparseTrieState (#17166)
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
Co-authored-by: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
2025-07-02 11:36:16 +00:00
Rebustron
a37917dd7a chore: removed link for book repo/layout.md (#17164) 2025-07-02 00:42:28 +00:00
Aliaksei Misiukevich
4199dd4676 feat: eth addons' middleware setter (#17159)
Signed-off-by: Aliaksei Misiukevich <taberlick@gmail.com>
2025-07-01 16:18:24 +00:00
Matthias Seitz
1c169257b6 chore: add debug for forkid mismatch (#17157) 2025-07-01 13:31:46 +00:00
Brian Picciano
7350c0151e fix(trie): correct ParallelSparseTrie lower subtrie path management (#17143) 2025-07-01 11:00:50 +00:00
Matthias Seitz
1bd5761b32 chore: bump revm (#17153)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
2025-07-01 10:51:16 +00:00
Matthias Seitz
06b542c556 docs: fix broken links and typos (#17149) 2025-07-01 10:30:57 +00:00
Matthias Seitz
fcf58cb5ac fix: use safe math for withdrawals check (#17150) 2025-06-30 22:14:17 +00:00
Niran Babalola
7276dae4ee feat: introduce max_tx_gas_limit feature to enforce per-transaction gas limits (#17028)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-30 20:44:28 +00:00
youyyytrok
22d271a714 chore: fixed dead link in docs/.../sync-op-mainnet.mdx (#17146) 2025-06-30 20:14:58 +00:00
Brian Picciano
c9f20728f2 chore: pass provider into SparseTrie and SparseStateTrie via impl argument in update/remove_leaf (#17099) 2025-06-30 16:11:51 +00:00
Matthias Seitz
2819ab2c0e chore: promote trace to debug (#17144) 2025-06-30 15:05:45 +00:00
Arsenii Kulikov
bdb3debdf1 feat: remove redundant generic from EthereumEngineValidatorBuilder (#17108) 2025-06-30 14:07:39 +00:00
Roman Hodulák
c63459884e refactor: Replace reth recover_singer_with_buf with alloy (#17107)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-30 13:41:35 +00:00
Matthias Seitz
678b5cd1fc chore: rm unused either type (#17126) 2025-06-30 11:53:04 +00:00
Matthias Seitz
42eb672473 feat(optimism): add debug namespace endpoints to historical RPC forwarding (#17133) 2025-06-30 11:38:32 +00:00
Cypher Pepe
5409d3146b chore: fixed broken links in opstack.mdx (#17135) 2025-06-30 11:27:07 +00:00
Alex Pikme
515e2077b4 docs: fix spelling errors (#17139) 2025-06-30 11:25:09 +00:00
PixelPilot
bf260bfcb8 docs: update Engine API link in ethereum.mdx (#17137) 2025-06-30 11:10:46 +00:00
Matthias Seitz
772c65eab8 docs: add comprehensive documentation for LaunchContext type system (#17120) 2025-06-30 13:12:34 +02:00
Noisy
f67629fe91 docs: fix installation source URL in ARM devices guide (#17128)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-29 11:39:20 +00:00
adust
c08d41a2f7 docs: remove reference to ContextStatefulPrecompile in precompile cache example (#17130)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-29 11:35:24 +00:00
github-actions[bot]
63f6845152 chore(deps): weekly cargo update (#17131)
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
2025-06-29 11:22:08 +00:00
Hopium
a072de32d1 docs: fix broken tutorial link (#17127) 2025-06-29 11:13:01 +00:00
PixelPilot
a8fa75148c Replace Book with Docs references (#17125) 2025-06-28 18:27:03 +00:00
cakevm
6f1497cc18 feat(alloy-provider): implement fetch block (#16934) 2025-06-28 09:49:07 +00:00
kilavvy
0a8a4ac2ca docs: fix typo in section of node-components.mdx (#17105) 2025-06-28 09:43:22 +00:00
Matthias Seitz
31d0bb1d58 refactor: move consensus layer events to launch context (#17117) 2025-06-27 23:19:05 +00:00
Matthias Seitz
bfd745117b refactor: move ERA import source creation to LaunchContext (#17115) 2025-06-27 22:46:13 +00:00
Matthias Seitz
8fa928ec5f refactor: make get_healthy_node_client async (#17119) 2025-06-27 22:22:29 +00:00
Matthias Seitz
2c52fc3f93 chore: tell claude to run fmt before opening a pr (#17118) 2025-06-27 22:04:05 +00:00
Matthias Seitz
5c82812072 refactor: move ExEx launching to LaunchContext method (#17114) 2025-06-27 22:02:21 +00:00
strmfos
8980944997 docs: fix error in config.rs (#17113) 2025-06-27 21:58:13 +00:00
Arsenii Kulikov
fae433319c refactor: simplify handling of NetworkPrimitives in CLI (#17112) 2025-06-27 19:39:07 +00:00
Matthias Seitz
34d95414db fix: track earliest available block correctly (#17095) 2025-06-27 16:33:45 +00:00
Matthias Seitz
40e8fb6d4d docs: fix typos across documentation (#17102)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-27 15:33:52 +00:00
Arsenii Kulikov
e89ea409e4 feat: relax EthereumNode ChainSpec bounds (#17106) 2025-06-27 15:26:16 +00:00
Arsenii Kulikov
b2000155de feat: use Header AT in EthChainSpec::next_block_base_fee (#17101) 2025-06-27 14:37:23 +00:00
Roman Hodulák
5f8aa53c6c deps: Upgrade alloy and op-alloy versions 1.0.13 => 0.18.7 and 0.18.9 (#17103)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-27 14:26:15 +00:00
Matthias Seitz
43b091b0e6 docs: debug clarify healtyh node rpc url setting (#17100) 2025-06-27 14:18:03 +00:00
Matthias Seitz
1d9a255f18 chore: rm redundant bounds (#17104) 2025-06-27 14:17:24 +00:00
kevaundray
384e64ed00 feat: Add StatelessTrie trait for reth-stateless (#17098)
Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
2025-06-27 13:05:00 +00:00
Alexey Shekhirin
0ae4238789 feat: add per-address metrics for precompile cache (#17058)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-27 12:53:47 +00:00
Yash Atreya
a33be2e02e chore(docs): move to docs from book (#17096)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-27 12:48:45 +00:00
Matthias Seitz
8066771473 fix: use safe conversions for number and timestamps (#17093) 2025-06-26 23:38:26 +00:00
Brian Picciano
cfdd173afc perf(trie): implement remove_leaf for ParallelSparseTrie (#17035) 2025-06-26 16:33:42 +00:00
Femi Bankole
0e832c2c30 chore: replace revm_utils with alloy_evm helpers (#17046)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-26 15:28:16 +00:00
Bilog WEB3
8aeaa4ef35 docs: error fixes for clarity (#17091) 2025-06-26 15:10:32 +00:00
Rez
07b19553a1 feat: centralize EIP-1559 base fee calculation in EthChainSpec (#16927)
Co-authored-by: rose2221 <rose.jethani@nethermind.io>
Co-authored-by: Rose Jethani <101273941+rose2221@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-06-26 14:38:31 +00:00
Varun Doshi
d635035be7 feat: punish malicious peers (#16818)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
2025-06-26 12:16:34 +00:00
Matthias Seitz
3c2ef0e28f chore: bump version in docs (#17085) 2025-06-26 14:30:21 +02:00
Yash Atreya
a7e19963fb feat(docs): serve rustdocs (#17084)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-26 12:06:01 +00:00
Matthias Seitz
61e38f9af1 chore: bump version 1.5.0 (#17083) 2025-06-26 11:50:41 +00:00
Matthias Seitz
9b3f2576d1 feat: add blanket impl for Receipt trait (#17082) 2025-06-26 11:43:52 +00:00
Yash Atreya
777ee2de29 fix(docs/sdk): heading hierarchy (#17079) 2025-06-26 11:15:59 +00:00
Alexey Shekhirin
2e799062f1 feat: convert reth-bench scripts to use uv script format (#17078)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-26 10:53:23 +00:00
Skylar Ray
55840bb32b docs: error fixes for clarity (#17062) 2025-06-26 10:49:28 +00:00
Yash Atreya
471f6a375e fix(docs): redo system reqs, fix links, rebrand to docs (#17071) 2025-06-26 10:07:49 +00:00
Matthias Seitz
f9e6b10730 chore: bump alloy 1.0.13 (#17072) 2025-06-26 10:58:39 +02:00
Matthias Seitz
4e4937ffd1 feat: include eth_sendRawTransactionSync in eth namesapce (#17070) 2025-06-26 08:30:31 +00:00
Maxim Evtush
988c0f0c53 docs: typo in comment for get_pending_transactions_by_origin (#17065) 2025-06-26 08:17:22 +00:00
Matthias Seitz
142c6342e3 fix(cli): propagate max-tx-input-bytes setting (#17066) 2025-06-25 21:49:41 +00:00
Alexey Shekhirin
bde35a329c docs: add libmdbx restriction to CLAUDE.md (#17060)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-25 21:20:29 +00:00
Roman Hodulák
7349abd126 refactor(examples): Use TransactionEnvelope macro from alloy for CustomTransaction in the custom-node example (#17057) 2025-06-25 21:16:09 +00:00
Matthias Seitz
79d737e6c8 chore: bump alloy patches (#17067) 2025-06-25 21:11:24 +00:00
0xsensei
f6278a1989 feat(trie): add assert_eq_parallel_sparse_trie_proof_nodes (#17052)
Co-authored-by: Aditya Pandey <adityapandey@Adityas-MacBook-Air.local>
2025-06-25 21:05:54 +00:00
Maximilian Hubert
30110bca04 docs: fix typo "takes effect" (#17053) 2025-06-25 15:21:49 +00:00
Eric Woolsey
7267734d5c chore: delete reth-performance dashboard (#16635) 2025-06-25 14:20:24 +00:00
Brian Picciano
eef134521c chore: Add precompile cache hit rate graph to grafana overview (#17055) 2025-06-25 13:54:37 +00:00
Alexey Shekhirin
56f6da5ed1 feat: make jwt-secret argument consistent across reth-bench commands (#17050)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-25 13:13:22 +00:00
1028 changed files with 55693 additions and 25204 deletions

View File

@@ -1,3 +0,0 @@
[codespell]
skip = .git,target,./crates/storage/libmdbx-rs/mdbx-sys/libmdbx,Cargo.toml,Cargo.lock
ignore-words-list = crate,ser,ratatui

View File

@@ -5,3 +5,13 @@ slow-timeout = { period = "30s", terminate-after = 4 }
[[profile.default.overrides]]
filter = "test(general_state_tests)"
slow-timeout = { period = "1m", terminate-after = 10 }
[[profile.default.overrides]]
filter = "test(eest_fixtures)"
slow-timeout = { period = "2m", terminate-after = 10 }
# E2E tests using the testsuite framework from crates/e2e-test-utils
# These tests are located in tests/e2e-testsuite/ directories across various crates
[[profile.default.overrides]]
filter = "binary(e2e_testsuite)"
slow-timeout = { period = "2m", terminate-after = 3 }

2
.gitattributes vendored
View File

@@ -2,3 +2,5 @@ book/cli/**/*.md linguist-vendored
book/cli/cli.md -linguist-vendored
crates/storage/libmdbx-rs/mdbx-sys/libmdbx/** linguist-vendored
bun.lock linguist-language=JSON-with-Comments

30
.github/CODEOWNERS vendored
View File

@@ -1,27 +1,22 @@
* @gakonst
bin/ @onbjerg
crates/blockchain-tree-api/ @rakita @rkrasiuk @mattsse @Rjected
crates/blockchain-tree/ @rakita @rkrasiuk @mattsse @Rjected
crates/chain-state/ @fgimenez @mattsse @rkrasiuk
crates/chainspec/ @Rjected @joshieDo @mattsse
crates/cli/ @onbjerg @mattsse
crates/config/ @onbjerg
crates/cli/ @mattsse
crates/consensus/ @rkrasiuk @mattsse @Rjected
crates/e2e-test-utils/ @mattsse @Rjected
crates/engine @rkrasiuk @mattsse @Rjected
crates/engine/ @rkrasiuk @mattsse @Rjected @fgimenez
crates/e2e-test-utils/ @mattsse @Rjected @klkvr @fgimenez
crates/engine/ @rkrasiuk @mattsse @Rjected @fgimenez @mediocregopher @yongkangc
crates/era/ @mattsse @RomanHodulak
crates/errors/ @mattsse
crates/ethereum-forks/ @mattsse @Rjected
crates/ethereum/ @mattsse @Rjected
crates/etl/ @joshieDo @shekhirin
crates/evm/ @rakita @mattsse @Rjected
crates/exex/ @onbjerg @shekhirin
crates/fs-util/ @onbjerg
crates/metrics/ @onbjerg
crates/exex/ @shekhirin
crates/net/ @mattsse @Rjected
crates/net/downloaders/ @onbjerg @rkrasiuk
crates/node/ @mattsse @Rjected @onbjerg @klkvr
crates/net/downloaders/ @rkrasiuk
crates/node/ @mattsse @Rjected @klkvr
crates/optimism/ @mattsse @Rjected @fgimenez
crates/payload/ @mattsse @Rjected
crates/primitives-traits/ @Rjected @RomanHodulak @mattsse @klkvr
@@ -30,21 +25,20 @@ crates/prune/ @shekhirin @joshieDo
crates/ress @rkrasiuk
crates/revm/ @mattsse @rakita
crates/rpc/ @mattsse @Rjected @RomanHodulak
crates/stages/ @onbjerg @rkrasiuk @shekhirin
crates/stages/ @rkrasiuk @shekhirin @mediocregopher
crates/static-file/ @joshieDo @shekhirin
crates/storage/codecs/ @joshieDo
crates/storage/db-api/ @joshieDo @rakita
crates/storage/db-common/ @Rjected @onbjerg
crates/storage/db-common/ @Rjected
crates/storage/db/ @joshieDo @rakita
crates/storage/errors/ @rakita @onbjerg
crates/storage/errors/ @rakita
crates/storage/libmdbx-rs/ @rakita @shekhirin
crates/storage/nippy-jar/ @joshieDo @shekhirin
crates/storage/provider/ @rakita @joshieDo @shekhirin
crates/storage/storage-api/ @joshieDo @rkrasiuk
crates/tasks/ @mattsse
crates/tokio-util/ @fgimenez
crates/tracing/ @onbjerg
crates/transaction-pool/ @mattsse
crates/transaction-pool/ @mattsse @yongkangc
crates/trie/ @rkrasiuk @Rjected @shekhirin @mediocregopher
etc/ @Rjected @onbjerg @shekhirin
.github/ @onbjerg @gakonst @DaniPopes
etc/ @Rjected @shekhirin
.github/ @gakonst @DaniPopes

View File

@@ -40,6 +40,7 @@ exclude_crates=(
reth-node-events
reth-node-metrics
reth-optimism-cli
reth-optimism-flashblocks
reth-optimism-node
reth-optimism-payload-builder
reth-optimism-rpc
@@ -48,6 +49,8 @@ exclude_crates=(
reth-rpc-api
reth-rpc-api-testing-util
reth-rpc-builder
reth-rpc-convert
reth-rpc-e2e-tests
reth-rpc-engine-api
reth-rpc-eth-api
reth-rpc-eth-types
@@ -58,7 +61,7 @@ exclude_crates=(
reth-ress-provider
# The following are not supposed to be working
reth # all of the crates below
reth-alloy-provider
reth-storage-rpc-provider
reth-invalid-block-hooks # reth-provider
reth-libmdbx # mdbx
reth-mdbx-sys # mdbx
@@ -76,6 +79,7 @@ exclude_crates=(
reth-era-downloader # tokio
reth-era-utils # tokio
reth-tracing-otlp
reth-node-ethstats
)
# Array to hold the results

View File

@@ -11,7 +11,7 @@ go build .
# Run each hive command in the background for each simulator and wait
echo "Building images"
./hive -client reth --sim "ethereum/eest" --sim.buildarg fixtures=https://github.com/ethereum/execution-spec-tests/releases/download/v4.4.0/fixtures_develop.tar.gz --sim.buildarg branch=v4.4.0 -sim.timelimit 1s || true &
./hive -client reth --sim "ethereum/eest" --sim.buildarg fixtures=https://github.com/ethereum/execution-spec-tests/releases/download/v5.1.0/fixtures_develop.tar.gz --sim.buildarg branch=v5.1.0 -sim.timelimit 1s || true &
./hive -client reth --sim "ethereum/engine" -sim.timelimit 1s || true &
./hive -client reth --sim "devp2p" -sim.timelimit 1s || true &
./hive -client reth --sim "ethereum/rpc-compat" -sim.timelimit 1s || true &

View File

@@ -6,12 +6,8 @@ rpc-compat:
- debug_getRawReceipts/get-block-n (reth)
- debug_getRawTransaction/get-invalid-hash (reth)
- eth_call/call-callenv (reth)
- eth_getStorageAt/get-storage-invalid-key-too-large (reth)
- eth_getStorageAt/get-storage-invalid-key (reth)
- eth_getTransactionReceipt/get-access-list (reth)
- eth_getTransactionReceipt/get-blob-tx (reth)
- eth_getTransactionReceipt/get-dynamic-fee (reth)
- eth_getTransactionReceipt/get-legacy-contract (reth)
- eth_getTransactionReceipt/get-legacy-input (reth)
- eth_getTransactionReceipt/get-legacy-receipt (reth)
@@ -57,10 +53,10 @@ engine-auth:
# 7002 related tests - post-fork test, should fix for spec compliance but not
# realistic on mainnet
# 7251 related tests - modified contract, not necessarily practical on mainnet,
# 7594: https://github.com/paradigmxyz/reth/issues/18471
# worth re-visiting when more of these related tests are passing
eest/consume-engine:
- tests/prague/eip7702_set_code_tx/test_set_code_txs.py::test_set_code_to_non_empty_storage[fork_Prague-blockchain_test_engine-zero_nonce]-reth
- tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py::test_system_contract_errors[fork_Prague-blockchain_test_engine-system_contract_reaches_gas_limit-system_contract_0x0000bbddc7ce488642fb579f8b00f3a590007251]-reth
- tests/prague/eip7251_consolidations/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test_engine-deploy_after_fork-nonzero_balance]-reth
- tests/prague/eip7251_consolidations/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test_engine-deploy_after_fork-zero_balance]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_amount_offset-value_zero]-reth
@@ -68,7 +64,6 @@ eest/consume-engine:
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_index_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_index_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_pubkey_offset-value_zero]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py::test_system_contract_errors[fork_Prague-blockchain_test_engine-system_contract_reaches_gas_limit-system_contract_0x00000961ef480eb55e80d19ad83579a64c007002]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_pubkey_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_signature_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_signature_size-value_zero]-reth
@@ -78,10 +73,18 @@ eest/consume-engine:
- tests/prague/eip7002_el_triggerable_withdrawals/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test_engine-deploy_after_fork-zero_balance]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Prague-blockchain_test_engine-slice_bytes_False]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Prague-blockchain_test_engine-slice_bytes_True]-reth
# the next test expects a concrete new format in the error message, there is no spec for this message, so it is ok to ignore
- tests/cancun/eip4844_blobs/test_blob_txs.py::test_blob_type_tx_pre_fork[fork_ShanghaiToCancunAtTime15k-blockchain_test_engine_from_state_test-one_blob_tx]-reth
# 7702 test - no fix: its too expensive to check whether the storage is empty on each creation
# rest of tests - see above
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_amount_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_amount_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_index_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_index_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_pubkey_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_pubkey_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_signature_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_signature_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_withdrawal_credentials_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_withdrawal_credentials_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Osaka-blockchain_test_engine-slice_bytes_False]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Osaka-blockchain_test_engine-slice_bytes_True]-reth
eest/consume-rlp:
- tests/prague/eip7702_set_code_tx/test_set_code_txs.py::test_set_code_to_non_empty_storage[fork_Prague-blockchain_test-zero_nonce]-reth
- tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py::test_system_contract_errors[fork_Prague-blockchain_test_engine-system_contract_reaches_gas_limit-system_contract_0x0000bbddc7ce488642fb579f8b00f3a590007251]-reth
@@ -98,13 +101,24 @@ eest/consume-rlp:
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_signature_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_withdrawal_credentials_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Prague-blockchain_test_engine-log_argument_withdrawal_credentials_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_amount_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_amount_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_index_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_index_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_pubkey_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_pubkey_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_signature_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_signature_size-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_withdrawal_credentials_offset-value_zero]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_layout[fork_Osaka-blockchain_test_engine-log_argument_withdrawal_credentials_size-value_zero]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test_engine-deploy_after_fork-nonzero_balance]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test_engine-deploy_after_fork-zero_balance]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Prague-blockchain_test_engine-slice_bytes_False]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Prague-blockchain_test_engine-slice_bytes_True]-reth
- tests/prague/eip7251_consolidations/test_modified_consolidation_contract.py::test_system_contract_errors[fork_Prague-blockchain_test-system_contract_reaches_gas_limit-system_contract_0x0000bbddc7ce488642fb579f8b00f3a590007251]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Osaka-blockchain_test_engine-slice_bytes_False]-reth
- tests/prague/eip6110_deposits/test_modified_contract.py::test_invalid_log_length[fork_Osaka-blockchain_test_engine-slice_bytes_True]-reth
- tests/osaka/eip7594_peerdas/test_max_blob_per_tx.py::test_max_blobs_per_tx_fork_transition[fork_PragueToOsakaAtTime15k-blob_count_7-blockchain_test]-reth
- tests/prague/eip7251_consolidations/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test-deploy_after_fork-nonzero_balance]-reth
- tests/prague/eip7251_consolidations/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test-deploy_after_fork-zero_balance]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_modified_withdrawal_contract.py::test_system_contract_errors[fork_Prague-blockchain_test-system_contract_reaches_gas_limit-system_contract_0x00000961ef480eb55e80d19ad83579a64c007002]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test-deploy_after_fork-nonzero_balance]-reth
- tests/prague/eip7002_el_triggerable_withdrawals/test_contract_deployment.py::test_system_contract_deployment[fork_CancunToPragueAtTime15k-blockchain_test-deploy_after_fork-zero_balance]-reth

34
.github/assets/hive/ignored_tests.yaml vendored Normal file
View File

@@ -0,0 +1,34 @@
# Ignored Tests Configuration
#
# This file contains tests that should be ignored for various reasons (flaky, known issues, etc).
# These tests will be IGNORED in the CI results - they won't cause the build to fail
# regardless of whether they pass or fail.
#
# Format
# test_suite:
# - "test name 1"
# - "test name 2"
#
# When a test should no longer be ignored, remove it from this list.
# flaky
engine-withdrawals:
- Withdrawals Fork on Block 1 - 8 Block Re-Org NewPayload (Paris) (reth)
- Withdrawals Fork on Block 8 - 10 Block Re-Org NewPayload (Paris) (reth)
- Withdrawals Fork on Canonical Block 8 / Side Block 7 - 10 Block Re-Org (Paris) (reth)
- Sync after 128 blocks - Withdrawals on Block 2 - Multiple Withdrawal Accounts (Paris) (reth)
engine-cancun:
- Transaction Re-Org, New Payload on Revert Back (Cancun) (reth)
- Transaction Re-Org, Re-Org to Different Block (Cancun) (reth)
- Transaction Re-Org, Re-Org Out (Cancun) (reth)
- Multiple New Payloads Extending Canonical Chain, Wait for Canonical Payload (Cancun) (reth)
engine-api:
- Transaction Re-Org, Re-Org Out (Paris) (reth)
- Transaction Re-Org, Re-Org to Different Block (Paris) (reth)
- Transaction Re-Org, New Payload on Revert Back (Paris) (reth)
- Transaction Re-Org, Re-Org to Different Block (Paris) (reth)
- Invalid Missing Ancestor Syncing ReOrg, Transaction Nonce, EmptyTxs=False, CanonicalReOrg=False, Invalid P9 (Paris) (reth)
- Invalid Missing Ancestor Syncing ReOrg, Transaction Signature, EmptyTxs=False, CanonicalReOrg=True, Invalid P9 (Paris) (reth)
- Invalid Missing Ancestor Syncing ReOrg, Transaction Signature, EmptyTxs=False, CanonicalReOrg=False, Invalid P9 (Paris) (reth)
- Multiple New Payloads Extending Canonical Chain, Wait for Canonical Payload (Paris) (reth)
- Multiple New Payloads Extending Canonical Chain, Set Head to First Payload Received (Paris) (reth)

View File

@@ -7,6 +7,7 @@ import argparse
parser = argparse.ArgumentParser(description="Check for unexpected test results based on an exclusion list.")
parser.add_argument("report_json", help="Path to the hive report JSON file.")
parser.add_argument("--exclusion", required=True, help="Path to the exclusion YAML file.")
parser.add_argument("--ignored", required=True, help="Path to the ignored tests YAML file.")
args = parser.parse_args()
# Load hive JSON
@@ -18,13 +19,30 @@ with open(args.exclusion, 'r') as file:
exclusion_data = yaml.safe_load(file)
exclusions = exclusion_data.get(report['name'], [])
# Load ignored tests YAML
with open(args.ignored, 'r') as file:
ignored_data = yaml.safe_load(file)
ignored_tests = ignored_data.get(report['name'], [])
# Collect unexpected failures and passes
unexpected_failures = []
unexpected_passes = []
ignored_results = {'passed': [], 'failed': []}
for test in report['testCases'].values():
test_name = test['name']
test_pass = test['summaryResult']['pass']
# Check if this is an ignored test
if test_name in ignored_tests:
# Track ignored test results for informational purposes
if test_pass:
ignored_results['passed'].append(test_name)
else:
ignored_results['failed'].append(test_name)
continue # Skip this test - don't count it as unexpected
# Check against expected failures
if test_name in exclusions:
if test_pass:
unexpected_passes.append(test_name)
@@ -32,6 +50,19 @@ for test in report['testCases'].values():
if not test_pass:
unexpected_failures.append(test_name)
# Print summary of ignored tests if any were ignored
if ignored_results['passed'] or ignored_results['failed']:
print("Ignored Tests:")
if ignored_results['passed']:
print(f" Passed ({len(ignored_results['passed'])} tests):")
for test in ignored_results['passed']:
print(f" {test}")
if ignored_results['failed']:
print(f" Failed ({len(ignored_results['failed'])} tests):")
for test in ignored_results['failed']:
print(f" {test}")
print()
# Check if there are any unexpected failures or passes and exit with error
if unexpected_failures or unexpected_passes:
if unexpected_failures:

View File

@@ -18,12 +18,19 @@ ethereum_package:
}'
optimism_package:
chains:
- participants:
- el_type: op-geth
cl_type: op-node
- el_type: op-reth
cl_type: op-node
el_image: "ghcr.io/paradigmxyz/op-reth:kurtosis-ci"
chain0:
participants:
node0:
el:
type: op-geth
cl:
type: op-node
node1:
el:
type: op-reth
image: "ghcr.io/paradigmxyz/op-reth:kurtosis-ci"
cl:
type: op-node
network_params:
holocene_time_offset: 0
isthmus_time_offset: 0

View File

@@ -18,7 +18,7 @@ jobs:
runs-on:
group: Reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true
- uses: rui314/setup-mold@v1
@@ -33,7 +33,8 @@ jobs:
- name: Build the benchmark target(s)
run: ./.github/scripts/codspeed-build.sh
- name: Run the benchmarks
uses: CodSpeedHQ/action@v3
uses: CodSpeedHQ/action@v4
with:
run: cargo codspeed run --workspace
mode: instrumentation
token: ${{ secrets.CODSPEED_TOKEN }}

View File

@@ -16,7 +16,7 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install bun
uses: oven-sh/setup-bun@v2
@@ -24,22 +24,28 @@ jobs:
- name: Install Playwright browsers
# Required for rehype-mermaid to render Mermaid diagrams during build
run: |
cd book/vocs/
cd docs/vocs/
bun i
npx playwright install --with-deps chromium
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
- name: Build docs
run: cd docs/vocs && bash scripts/build-cargo-docs.sh
- name: Build Vocs
run: |
cd book/vocs/ && bun run build
cd docs/vocs/ && bun run build
echo "Vocs Build Complete"
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v4
with:
path: "./book/vocs/docs/dist"
path: "./docs/vocs/docs/dist"
deploy:
# Only deploy if a push to main

View File

@@ -31,7 +31,7 @@ jobs:
with:
cache-on-failure: true
- name: Checkout base
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ github.base_ref || 'main' }}
# On `main` branch, generates test vectors and serializes them to disk using `Compact`.
@@ -39,7 +39,7 @@ jobs:
run: |
${{ matrix.bin }} -- test-vectors compact --write
- name: Checkout PR
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
clean: false
# On incoming merge try to read and decode previously generated vectors with `Compact`

View File

@@ -33,7 +33,7 @@ jobs:
- name: 'Build and push the git-sha-tagged op-reth image'
command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME GIT_SHA=$GIT_SHA PROFILE=maxperf op-docker-build-push-git-sha'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

View File

@@ -35,7 +35,7 @@ jobs:
- name: 'Build and push the nightly profiling op-reth image'
command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=profiling op-docker-build-push-nightly-profiling'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Remove bloatware
uses: laverdet/remove-bloatware@v1.0.0
with:

View File

@@ -32,7 +32,7 @@ jobs:
- name: "Build and push op-reth image"
command: "make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=maxperf op-docker-build-push"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
@@ -68,7 +68,7 @@ jobs:
- name: "Build and push op-reth image"
command: "make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=maxperf op-docker-build-push-latest"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

46
.github/workflows/e2e.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
# Runs e2e tests using the testsuite framework
name: e2e
on:
pull_request:
merge_group:
push:
branches: [main]
env:
CARGO_TERM_COLOR: always
SEED: rustethereumethereumrust
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
test:
name: e2e-testsuite
runs-on:
group: Reth
env:
RUST_BACKTRACE: 1
timeout-minutes: 90
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@nextest
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Run e2e tests
run: |
cargo nextest run \
--locked --features "asm-keccak" \
--workspace \
--exclude 'example-*' \
--exclude 'exex-subscription' \
--exclude 'reth-bench' \
--exclude 'ef-tests' \
--exclude 'op-reth' \
--exclude 'reth' \
-E 'binary(e2e_testsuite)'

View File

@@ -27,16 +27,14 @@ jobs:
runs-on:
group: Reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Checkout hive tests
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: ethereum/hive
# TODO: unpin when https://github.com/ethereum/hive/issues/1306 is fixed
ref: edd9969338dd1798ba2e61f049c7e3a15cef53e6
path: hivetests
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version: "^1.13.1"
- run: go version
@@ -50,7 +48,7 @@ jobs:
name: hive_assets
path: ./hive_assets
test:
timeout-minutes: 60
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
@@ -114,6 +112,8 @@ jobs:
- debug_
# consume-engine
- sim: ethereum/eest/consume-engine
limit: .*tests/osaka.*
- sim: ethereum/eest/consume-engine
limit: .*tests/prague.*
- sim: ethereum/eest/consume-engine
@@ -130,6 +130,8 @@ jobs:
limit: .*tests/frontier.*
# consume-rlp
- sim: ethereum/eest/consume-rlp
limit: .*tests/osaka.*
- sim: ethereum/eest/consume-rlp
limit: .*tests/prague.*
- sim: ethereum/eest/consume-rlp
@@ -153,18 +155,18 @@ jobs:
permissions:
issues: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Download hive assets
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: hive_assets
path: /tmp
- name: Download reth image
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: artifacts
path: /tmp
@@ -178,7 +180,7 @@ jobs:
chmod +x /usr/local/bin/hive
- name: Checkout hive tests
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: ethereum/hive
ref: master
@@ -202,7 +204,7 @@ jobs:
- name: Parse hive output
run: |
find hivetests/workspace/logs -type f -name "*.json" ! -name "hive.json" | xargs -I {} python .github/assets/hive/parse.py {} --exclusion .github/assets/hive/expected_failures.yaml
find hivetests/workspace/logs -type f -name "*.json" ! -name "hive.json" | xargs -I {} python .github/assets/hive/parse.py {} --exclusion .github/assets/hive/expected_failures.yaml --ignored .github/assets/hive/ignored_tests.yaml
- name: Print simulator output
if: ${{ failure() }}

View File

@@ -32,7 +32,7 @@ jobs:
network: ["ethereum", "optimism"]
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- name: Install Geth
@@ -47,7 +47,7 @@ jobs:
cargo nextest run \
--locked --features "asm-keccak ${{ matrix.network }}" \
--workspace --exclude ef-tests \
-E "kind(test)"
-E "kind(test) and not binary(e2e_testsuite)"
- if: matrix.network == 'optimism'
name: Run tests
run: |
@@ -71,7 +71,7 @@ jobs:
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@nextest

View File

@@ -37,12 +37,12 @@ jobs:
needs:
- prepare-reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Download reth image
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: artifacts
path: /tmp
@@ -62,12 +62,10 @@ jobs:
sudo apt update
sudo apt install kurtosis-cli
kurtosis engine start
# TODO: unpin optimism-package when https://github.com/ethpandaops/optimism-package/issues/340 is fixed
# kurtosis run --enclave op-devnet github.com/ethpandaops/optimism-package --args-file .github/assets/kurtosis_op_network_params.yaml
kurtosis run --enclave op-devnet github.com/ethpandaops/optimism-package@452133367b693e3ba22214a6615c86c60a1efd5e --args-file .github/assets/kurtosis_op_network_params.yaml
kurtosis run --enclave op-devnet github.com/ethpandaops/optimism-package --args-file .github/assets/kurtosis_op_network_params.yaml
ENCLAVE_ID=$(curl http://127.0.0.1:9779/api/enclaves | jq --raw-output 'keys[0]')
GETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-2151908-1-op-geth-op-node-op-kurtosis".public_ports.rpc.number')
RETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-2151908-2-op-reth-op-node-op-kurtosis".public_ports.rpc.number')
GETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-2151908-node0-op-geth".public_ports.rpc.number')
RETH_PORT=$(curl "http://127.0.0.1:9779/api/enclaves/$ENCLAVE_ID/services" | jq '."op-el-2151908-node1-op-reth".public_ports.rpc.number')
echo "GETH_RPC=http://127.0.0.1:$GETH_PORT" >> $GITHUB_ENV
echo "RETH_RPC=http://127.0.0.1:$RETH_PORT" >> $GITHUB_ENV

View File

@@ -35,12 +35,12 @@ jobs:
needs:
- prepare-reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Download reth image
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: artifacts
path: /tmp

View File

@@ -11,12 +11,12 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Label PRs
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const label_pr = require('./.github/assets/label_pr.js')

View File

@@ -12,7 +12,7 @@ jobs:
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Download actionlint
id: get_actionlint
run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)

View File

@@ -21,7 +21,7 @@ jobs:
args: --workspace --lib --examples --tests --benches --locked
features: "ethereum asm-keccak jemalloc jemalloc-prof min-error-logs min-warn-logs min-info-logs min-debug-logs min-trace-logs"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@clippy
with:
@@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@nightly
with:
@@ -59,7 +59,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:
@@ -78,7 +78,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:
@@ -95,7 +95,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@cargo-hack
@@ -114,11 +114,11 @@ jobs:
- binary: reth
- binary: op-reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.86" # MSRV
toolchain: "1.88" # MSRV
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
@@ -131,7 +131,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
@@ -148,7 +148,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@nightly
with:
@@ -161,7 +161,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
@@ -175,7 +175,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@nightly
- uses: Swatinem/rust-cache@v2
@@ -184,25 +184,23 @@ jobs:
- run: cargo build --bin reth --workspace --features ethereum
env:
RUSTFLAGS: -D warnings
- run: ./book/cli/update.sh target/debug/reth
- name: Check book changes
- run: ./docs/cli/update.sh target/debug/reth
- name: Check docs changes
run: git diff --exit-code
codespell:
typos:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: codespell-project/actions-codespell@v2
with:
skip: "*.json"
- uses: actions/checkout@v5
- uses: crate-ci/typos@v1
check-toml:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run dprint
uses: dprint/check@v2.3
with:
@@ -212,7 +210,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Check dashboard JSON with jq
uses: sergeysova/jq-action@v2
with:
@@ -222,7 +220,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- name: Ensure no arbitrary or proptest dependency on default build
@@ -234,7 +232,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@clippy
- uses: Swatinem/rust-cache@v2
@@ -251,7 +249,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: fetch deps
run: |
# Eagerly pull dependencies
@@ -278,7 +276,7 @@ jobs:
- fmt
- udeps
- book
- codespell
- typos
- grafana
- no-test-deps
- features

View File

@@ -21,7 +21,7 @@ jobs:
steps:
- name: Check title
id: lint_pr_title
uses: amannn/action-semantic-pull-request@v5
uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@@ -29,7 +29,7 @@ jobs:
runs-on:
group: Reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- run: mkdir artifacts
- name: Set up Docker Buildx

View File

@@ -29,7 +29,7 @@ jobs:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

View File

@@ -20,8 +20,8 @@ env:
OP_IMAGE_NAME: ${{ github.repository_owner }}/op-reth
REPRODUCIBLE_IMAGE_NAME: ${{ github.repository_owner }}/reth-reproducible
CARGO_TERM_COLOR: always
DOCKER_IMAGE_NAME_URL: ghcr.io/${{ github.repository_owner }}/reth
DOCKER_OP_IMAGE_NAME_URL: ghcr.io/${{ github.repository_owner }}/op-reth
DOCKER_IMAGE_NAME_URL: https://ghcr.io/${{ github.repository_owner }}/reth
DOCKER_OP_IMAGE_NAME_URL: https://ghcr.io/${{ github.repository_owner }}/op-reth
jobs:
dry-run:
@@ -49,7 +49,7 @@ jobs:
needs: extract-version
if: ${{ github.event.inputs.dry_run != 'true' }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- name: Verify crate version matches tag
# Check that the Cargo version starts with the tag,
@@ -99,7 +99,7 @@ jobs:
- command: op-build
binary: op-reth
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:
@@ -166,11 +166,11 @@ jobs:
steps:
# This is necessary for generating the changelog.
# It has to come before "Download Artifacts" or else it deletes the artifacts.
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
- name: Generate full changelog
id: changelog
run: |
@@ -223,7 +223,7 @@ jobs:
| Payload Builders | <TODO> |
| Non-Payload Builders | <TODO> |
*See [Update Priorities](https://paradigmxyz.github.io/reth/installation/priorities.html) for more information about this table.*
*See [Update Priorities](https://reth.rs/installation/priorities) for more information about this table.*
## All Changes
@@ -231,7 +231,7 @@ jobs:
## Binaries
[See pre-built binaries documentation.](https://paradigmxyz.github.io/reth/installation/binaries.html)
[See pre-built binaries documentation.](https://reth.rs/installation/binaries)
The binaries are signed with the PGP key: `50FB 7CC5 5B2E 8AFA 59FE 03B7 AA5E D56A 7FBF 253E`

View File

@@ -10,7 +10,7 @@ jobs:
name: build reproducible binaries
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:

View File

@@ -29,7 +29,7 @@ jobs:
RUST_BACKTRACE: 1
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

View File

@@ -14,7 +14,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
days-before-stale: 21
days-before-close: 7

View File

@@ -39,7 +39,7 @@ jobs:
block: 10000
unwind-target: "0x118a6e922a8c6cab221fc5adfe5056d2b72d58c6580e9c5629de55299e2cf8de"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
@@ -53,7 +53,7 @@ jobs:
--chain ${{ matrix.chain.chain }} \
--debug.tip ${{ matrix.chain.tip }} \
--debug.max-block ${{ matrix.chain.block }} \
--debug.terminate
--debug.terminate \
--era.enable
- name: Verify the target block hash
run: |

View File

@@ -39,7 +39,7 @@ jobs:
block: 10000
unwind-target: "0x118a6e922a8c6cab221fc5adfe5056d2b72d58c6580e9c5629de55299e2cf8de"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

View File

@@ -44,7 +44,7 @@ jobs:
total_partitions: 2
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
@@ -61,7 +61,7 @@ jobs:
${{ matrix.args }} --workspace \
--exclude ef-tests --no-tests=warn \
--partition hash:${{ matrix.partition }}/2 \
-E "!kind(test)"
-E "!kind(test) and not binary(e2e_testsuite)"
state:
name: Ethereum state tests
@@ -72,15 +72,24 @@ jobs:
RUST_BACKTRACE: 1
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Checkout ethereum/tests
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
repository: ethereum/tests
ref: 81862e4848585a438d64f911a19b3825f0f4cd95
path: testing/ef-tests/ethereum-tests
submodules: recursive
fetch-depth: 1
- name: Download & extract EEST fixtures (public)
shell: bash
env:
EEST_TESTS_TAG: v4.5.0
run: |
set -euo pipefail
mkdir -p testing/ef-tests/execution-spec-tests
URL="https://github.com/ethereum/execution-spec-tests/releases/download/${EEST_TESTS_TAG}/fixtures_stable.tar.gz"
curl -L "$URL" | tar -xz --strip-components=1 -C testing/ef-tests/execution-spec-tests
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@nextest
@@ -97,7 +106,7 @@ jobs:
RUST_BACKTRACE: 1
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install required tools
run: |

View File

@@ -15,7 +15,7 @@ jobs:
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:
@@ -34,7 +34,7 @@ jobs:
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: rui314/setup-mold@v1
- uses: dtolnay/rust-toolchain@stable
with:

15
.gitignore vendored
View File

@@ -55,7 +55,20 @@ rustc-ice-*
book/sources/Cargo.lock
# vocs node_modules
book/vocs/node_modules
docs/vocs/node_modules
# Cargo chef recipe file
recipe.json
_
# broken links report
links-report.json
# Python cache
__pycache__/
*.py[cod]
*$py.class
# direnv
.envrc
.direnv/

View File

@@ -162,6 +162,7 @@ Based on PR patterns, avoid:
2. **Mixing unrelated changes**: One logical change per PR
3. **Ignoring CI failures**: All checks must pass
4. **Incomplete implementations**: Finish features before submitting
5. **Modifying libmdbx sources**: Never modify files in `crates/storage/libmdbx-rs/mdbx-sys/libmdbx/` - this is vendored third-party code
### CI Requirements
@@ -181,6 +182,7 @@ Label PRs appropriately, first check the available labels and then apply the rel
* when changes are docs related, add C-docs label
* when changes are optimism related (e.g. new feature or exclusive changes to crates/optimism), add A-op-reth label
* ... and so on, check the available labels for more options.
* if being tasked to open a pr, ensure that all changes are properly formatted: `cargo +nightly fmt --all`
If changes in reth include changes to dependencies, run commands `zepter` and `make lint-toml` before finalizing the pr. Assume `zepter` binary is installed.

View File

@@ -3,7 +3,7 @@
Thanks for your interest in improving Reth!
There are multiple opportunities to contribute at any level. It doesn't matter if you are just getting started with Rust
or are the most weathered expert, we can use your help.
or if you are already the most weathered expert, we can use your help.
**No contribution is too small and all contributions are valued.**
@@ -55,7 +55,7 @@ If you have reviewed existing documentation and still have questions, or you are
*opening a discussion**. This repository comes with a discussions board where you can also ask for help. Click the "
Discussions" tab at the top.
As Reth is still in heavy development, the documentation can be a bit scattered. The [Reth Book][reth-book] is our
As Reth is still in heavy development, the documentation can be a bit scattered. The [Reth Docs][reth-docs] is our
current best-effort attempt at keeping up-to-date information.
### Submitting a bug report
@@ -235,7 +235,7 @@ _Adapted from the [Foundry contributing guide][foundry-contributing]_.
[dev-tg]: https://t.me/paradigm_reth
[reth-book]: https://github.com/paradigmxyz/reth/tree/main/book
[reth-docs]: https://github.com/paradigmxyz/reth/tree/main/docs
[mcve]: https://stackoverflow.com/help/mcve

2597
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
[workspace.package]
version = "1.4.8"
edition = "2021"
rust-version = "1.86"
version = "1.8.2"
edition = "2024"
rust-version = "1.88"
license = "MIT OR Apache-2.0"
homepage = "https://paradigmxyz.github.io/reth"
repository = "https://github.com/paradigmxyz/reth"
@@ -11,7 +11,7 @@ exclude = [".github/"]
members = [
"bin/reth-bench/",
"bin/reth/",
"crates/alloy-provider/",
"crates/storage/rpc-provider/",
"crates/chain-state/",
"crates/chainspec/",
"crates/cli/cli/",
@@ -67,6 +67,7 @@ members = [
"crates/node/api/",
"crates/node/builder/",
"crates/node/core/",
"crates/node/ethstats",
"crates/node/events/",
"crates/node/metrics",
"crates/node/types",
@@ -75,6 +76,7 @@ members = [
"crates/optimism/cli",
"crates/optimism/consensus",
"crates/optimism/evm/",
"crates/optimism/flashblocks/",
"crates/optimism/hardforks/",
"crates/optimism/node/",
"crates/optimism/payload/",
@@ -105,6 +107,7 @@ members = [
"crates/rpc/rpc-layer",
"crates/rpc/rpc-server-types/",
"crates/rpc/rpc-testing-util/",
"crates/rpc/rpc-e2e-tests/",
"crates/rpc/rpc-convert/",
"crates/rpc/rpc/",
"crates/stages/api/",
@@ -153,12 +156,15 @@ members = [
"examples/exex-hello-world",
"examples/exex-subscription",
"examples/exex-test",
"examples/full-contract-state",
"examples/manual-p2p/",
"examples/network-txpool/",
"examples/network/",
"examples/network-proxy/",
"examples/node-builder-api/",
"examples/node-custom-rpc/",
"examples/node-event-hooks/",
"examples/op-db-access/",
"examples/polygon-p2p/",
"examples/rpc-db/",
"examples/precompile-cache/",
@@ -166,10 +172,11 @@ members = [
"examples/custom-beacon-withdrawals",
"testing/ef-tests/",
"testing/testing-utils",
"testing/runner",
"crates/tracing-otlp",
]
default-members = ["bin/reth"]
exclude = ["book/sources", "book/cli"]
exclude = ["docs/cli"]
# Explicitly set the resolver to version 2, which is the default for packages with edition >= 2021
# https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html
@@ -181,6 +188,7 @@ rust.missing_docs = "warn"
rust.rust_2018_idioms = { level = "deny", priority = -1 }
rust.unreachable_pub = "warn"
rust.unused_must_use = "deny"
rust.rust_2024_incompatible_pat = "warn"
rustdoc.all = "warn"
# rust.unnameable-types = "warn"
@@ -321,7 +329,7 @@ codegen-units = 1
# reth
op-reth = { path = "crates/optimism/bin" }
reth = { path = "bin/reth" }
reth-alloy-provider = { path = "crates/alloy-provider" }
reth-storage-rpc-provider = { path = "crates/storage/rpc-provider" }
reth-basic-payload-builder = { path = "crates/payload/basic" }
reth-bench = { path = "bin/reth-bench" }
reth-chain-state = { path = "crates/chain-state" }
@@ -391,6 +399,7 @@ reth-node-api = { path = "crates/node/api" }
reth-node-builder = { path = "crates/node/builder" }
reth-node-core = { path = "crates/node/core" }
reth-node-ethereum = { path = "crates/ethereum/node" }
reth-node-ethstats = { path = "crates/node/ethstats" }
reth-node-events = { path = "crates/node/events" }
reth-node-metrics = { path = "crates/node/metrics" }
reth-optimism-node = { path = "crates/optimism/node" }
@@ -420,10 +429,12 @@ reth-rpc = { path = "crates/rpc/rpc" }
reth-rpc-api = { path = "crates/rpc/rpc-api" }
reth-rpc-api-testing-util = { path = "crates/rpc/rpc-testing-util" }
reth-rpc-builder = { path = "crates/rpc/rpc-builder" }
reth-rpc-e2e-tests = { path = "crates/rpc/rpc-e2e-tests" }
reth-rpc-engine-api = { path = "crates/rpc/rpc-engine-api" }
reth-rpc-eth-api = { path = "crates/rpc/rpc-eth-api" }
reth-rpc-eth-types = { path = "crates/rpc/rpc-eth-types", default-features = false }
reth-rpc-layer = { path = "crates/rpc/rpc-layer" }
reth-optimism-flashblocks = { path = "crates/optimism/flashblocks" }
reth-rpc-server-types = { path = "crates/rpc/rpc-server-types" }
reth-rpc-convert = { path = "crates/rpc/rpc-convert" }
reth-stages = { path = "crates/stages/stages" }
@@ -450,79 +461,80 @@ reth-ress-protocol = { path = "crates/ress/protocol" }
reth-ress-provider = { path = "crates/ress/provider" }
# revm
revm = { version = "26.0.1", default-features = false }
revm-bytecode = { version = "5.0.0", default-features = false }
revm-database = { version = "6.0.0", default-features = false }
revm-state = { version = "6.0.0", default-features = false }
revm-primitives = { version = "20.0.0", default-features = false }
revm-interpreter = { version = "22.0.1", default-features = false }
revm-inspector = { version = "7.0.1", default-features = false }
revm-context = { version = "7.0.1", default-features = false }
revm-context-interface = { version = "7.0.0", default-features = false }
revm-database-interface = { version = "6.0.0", default-features = false }
op-revm = { version = "7.0.1", default-features = false }
revm-inspectors = "0.25.0"
revm = { version = "29.0.1", default-features = false }
revm-bytecode = { version = "6.2.2", default-features = false }
revm-database = { version = "7.0.5", default-features = false }
revm-state = { version = "7.0.5", default-features = false }
revm-primitives = { version = "20.2.1", default-features = false }
revm-interpreter = { version = "25.0.3", default-features = false }
revm-inspector = { version = "10.0.1", default-features = false }
revm-context = { version = "9.1.0", default-features = false }
revm-context-interface = { version = "10.2.0", default-features = false }
revm-database-interface = { version = "7.0.5", default-features = false }
op-revm = { version = "10.1.0", default-features = false }
revm-inspectors = "0.30.0"
# eth
alloy-chains = { version = "0.2.0", default-features = false }
alloy-dyn-abi = "1.2.0"
alloy-chains = { version = "0.2.5", default-features = false }
alloy-dyn-abi = "1.3.1"
alloy-eip2124 = { version = "0.2.0", default-features = false }
alloy-evm = { version = "0.12", default-features = false }
alloy-primitives = { version = "1.2.0", default-features = false, features = ["map-foldhash"] }
alloy-evm = { version = "0.21.0", default-features = false }
alloy-primitives = { version = "1.3.1", default-features = false, features = ["map-foldhash"] }
alloy-rlp = { version = "0.3.10", default-features = false, features = ["core-net"] }
alloy-sol-macro = "1.2.0"
alloy-sol-types = { version = "1.2.0", default-features = false }
alloy-trie = { version = "0.9.0", default-features = false }
alloy-sol-macro = "1.3.1"
alloy-sol-types = { version = "1.3.1", default-features = false }
alloy-trie = { version = "0.9.1", default-features = false }
alloy-hardforks = "0.2.7"
alloy-hardforks = "0.3.5"
alloy-consensus = { version = "1.0.12", default-features = false }
alloy-contract = { version = "1.0.12", default-features = false }
alloy-eips = { version = "1.0.12", default-features = false }
alloy-genesis = { version = "1.0.12", default-features = false }
alloy-json-rpc = { version = "1.0.12", default-features = false }
alloy-network = { version = "1.0.12", default-features = false }
alloy-network-primitives = { version = "1.0.12", default-features = false }
alloy-provider = { version = "1.0.12", features = ["reqwest"], default-features = false }
alloy-pubsub = { version = "1.0.12", default-features = false }
alloy-rpc-client = { version = "1.0.12", default-features = false }
alloy-rpc-types = { version = "1.0.12", features = ["eth"], default-features = false }
alloy-rpc-types-admin = { version = "1.0.12", default-features = false }
alloy-rpc-types-anvil = { version = "1.0.12", default-features = false }
alloy-rpc-types-beacon = { version = "1.0.12", default-features = false }
alloy-rpc-types-debug = { version = "1.0.12", default-features = false }
alloy-rpc-types-engine = { version = "1.0.12", default-features = false }
alloy-rpc-types-eth = { version = "1.0.12", default-features = false }
alloy-rpc-types-mev = { version = "1.0.12", default-features = false }
alloy-rpc-types-trace = { version = "1.0.12", default-features = false }
alloy-rpc-types-txpool = { version = "1.0.12", default-features = false }
alloy-serde = { version = "1.0.12", default-features = false }
alloy-signer = { version = "1.0.12", default-features = false }
alloy-signer-local = { version = "1.0.12", default-features = false }
alloy-transport = { version = "1.0.12" }
alloy-transport-http = { version = "1.0.12", features = ["reqwest-rustls-tls"], default-features = false }
alloy-transport-ipc = { version = "1.0.12", default-features = false }
alloy-transport-ws = { version = "1.0.12", default-features = false }
alloy-consensus = { version = "1.0.37", default-features = false }
alloy-contract = { version = "1.0.37", default-features = false }
alloy-eips = { version = "1.0.37", default-features = false }
alloy-genesis = { version = "1.0.37", default-features = false }
alloy-json-rpc = { version = "1.0.37", default-features = false }
alloy-network = { version = "1.0.37", default-features = false }
alloy-network-primitives = { version = "1.0.37", default-features = false }
alloy-provider = { version = "1.0.37", features = ["reqwest"], default-features = false }
alloy-pubsub = { version = "1.0.37", default-features = false }
alloy-rpc-client = { version = "1.0.37", default-features = false }
alloy-rpc-types = { version = "1.0.37", features = ["eth"], default-features = false }
alloy-rpc-types-admin = { version = "1.0.37", default-features = false }
alloy-rpc-types-anvil = { version = "1.0.37", default-features = false }
alloy-rpc-types-beacon = { version = "1.0.37", default-features = false }
alloy-rpc-types-debug = { version = "1.0.37", default-features = false }
alloy-rpc-types-engine = { version = "1.0.37", default-features = false }
alloy-rpc-types-eth = { version = "1.0.37", default-features = false }
alloy-rpc-types-mev = { version = "1.0.37", default-features = false }
alloy-rpc-types-trace = { version = "1.0.37", default-features = false }
alloy-rpc-types-txpool = { version = "1.0.37", default-features = false }
alloy-serde = { version = "1.0.37", default-features = false }
alloy-signer = { version = "1.0.37", default-features = false }
alloy-signer-local = { version = "1.0.37", default-features = false }
alloy-transport = { version = "1.0.37" }
alloy-transport-http = { version = "1.0.37", features = ["reqwest-rustls-tls"], default-features = false }
alloy-transport-ipc = { version = "1.0.37", default-features = false }
alloy-transport-ws = { version = "1.0.37", default-features = false }
# op
alloy-op-evm = { version = "0.12", default-features = false }
alloy-op-hardforks = "0.2.2"
op-alloy-rpc-types = { version = "0.18.6", default-features = false }
op-alloy-rpc-types-engine = { version = "0.18.6", default-features = false }
op-alloy-network = { version = "0.18.6", default-features = false }
op-alloy-consensus = { version = "0.18.6", default-features = false }
op-alloy-rpc-jsonrpsee = { version = "0.18.6", default-features = false }
alloy-op-evm = { version = "0.21.0", default-features = false }
alloy-op-hardforks = "0.3.5"
op-alloy-rpc-types = { version = "0.20.0", default-features = false }
op-alloy-rpc-types-engine = { version = "0.20.0", default-features = false }
op-alloy-network = { version = "0.20.0", default-features = false }
op-alloy-consensus = { version = "0.20.0", default-features = false }
op-alloy-rpc-jsonrpsee = { version = "0.20.0", default-features = false }
op-alloy-flz = { version = "0.13.1", default-features = false }
# misc
either = { version = "1.15.0", default-features = false }
aquamarine = "0.6"
auto_impl = "1"
backon = { version = "1.2", default-features = false, features = ["std-blocking-sleep", "tokio-sleep"] }
bincode = "1.3"
bitflags = "2.4"
blake3 = "1.5.5"
boyer-moore-magiclen = "0.2.16"
bytes = { version = "1.5", default-features = false }
brotli = "8"
cfg-if = "1.0"
clap = "4"
dashmap = "6.0"
@@ -539,7 +551,7 @@ linked_hash_set = "0.1"
lz4 = "1.28.1"
modular-bitfield = "0.11.2"
notify = { version = "8.0.0", default-features = false, features = ["macos_fsevent"] }
nybbles = { version = "0.4.0", default-features = false }
nybbles = { version = "0.4.2", default-features = false }
once_cell = { version = "1.19", default-features = false, features = ["critical-section"] }
parking_lot = "0.12"
paste = "1.0"
@@ -566,6 +578,7 @@ byteorder = "1"
mini-moka = "0.10"
tar-no-std = { version = "0.3.2", default-features = false }
miniz_oxide = { version = "0.8.4", default-features = false }
chrono = "0.4.41"
# metrics
metrics = "0.24.0"
@@ -581,6 +594,7 @@ quote = "1.0"
# tokio
tokio = { version = "1.44.2", default-features = false }
tokio-stream = "0.1.11"
tokio-tungstenite = "0.26.2"
tokio-util = { version = "0.7.4", features = ["codec"] }
# async
@@ -602,11 +616,11 @@ discv5 = "0.9"
if-addrs = "0.13"
# rpc
jsonrpsee = "0.25.1"
jsonrpsee-core = "0.25.1"
jsonrpsee-server = "0.25.1"
jsonrpsee-http-client = "0.25.1"
jsonrpsee-types = "0.25.1"
jsonrpsee = "0.26.0"
jsonrpsee-core = "0.26.0"
jsonrpsee-server = "0.26.0"
jsonrpsee-http-client = "0.26.0"
jsonrpsee-types = "0.26.0"
# http
http = "1.0"
@@ -623,7 +637,7 @@ secp256k1 = { version = "0.30", default-features = false, features = ["global-co
rand_08 = { package = "rand", version = "0.8" }
# for eip-4844
c-kzg = "2.1.1"
c-kzg = "2.1.4"
# config
toml = "0.8"
@@ -650,15 +664,10 @@ tikv-jemallocator = "0.6"
tracy-client = "0.18.0"
snmalloc-rs = { version = "0.3.7", features = ["build_cc"] }
# TODO: When we build for a windows target on an ubuntu runner, crunchy tries to
# get the wrong path, update this when the workflow has been updated
#
# See: https://github.com/eira-fransham/crunchy/issues/13
crunchy = "=0.2.2"
aes = "0.8.1"
ahash = "0.8"
anyhow = "1.0"
bindgen = { version = "0.70", default-features = false }
bindgen = { version = "0.71", default-features = false }
block-padding = "0.3.2"
cc = "=1.2.15"
cipher = "0.4.3"
@@ -705,34 +714,34 @@ visibility = "0.1.1"
walkdir = "2.3.3"
vergen-git2 = "1.0.5"
[patch.crates-io]
alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-admin = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-debug = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-mev = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-rpc-types-txpool = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-signer-local = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "08fa016ed950b6e65f810fc9cdef7cf38fbc63f6" }
# [patch.crates-io]
# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-admin = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-debug = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-mev = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-rpc-types-txpool = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-signer-local = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" }
# op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" }
# op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" }

View File

@@ -1,5 +1,5 @@
# Use the Rust 1.86 image based on Debian Bookworm
FROM rust:1.86-bookworm AS builder
# Use the Rust 1.88 image based on Debian Bookworm
FROM rust:1.88-bookworm AS builder
# Install specific version of libclang-dev
RUN apt-get update && apt-get install -y libclang-dev=1:14.0-55.7~deb12u1

View File

@@ -17,7 +17,13 @@ RUN apt-get update && apt-get install --assume-yes --no-install-recommends git
RUN git clone https://github.com/cross-rs/cross /cross
WORKDIR /cross/docker
RUN git checkout 9e2298e17170655342d3248a9c8ac37ef92ba38f
RUN git checkout baf457efc2555225af47963475bd70e8d2f5993f
# xargo doesn't work with Rust 1.89 and higher: https://github.com/cross-rs/cross/issues/1701.
#
# When this PR https://github.com/cross-rs/cross/pull/1580 is merged,
# we can update the checkout above and remove this replacement.
RUN sed -i 's|sh rustup-init.sh -y --no-modify-path --profile minimal|sh rustup-init.sh -y --no-modify-path --profile minimal --default-toolchain=1.88.0|' xargo.sh
RUN cp common.sh lib.sh / && /common.sh
RUN cp cmake.sh / && /cmake.sh

View File

@@ -6,13 +6,13 @@ LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"
RUN apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config
# Builds a cargo-chef plan
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
COPY . .
ARG BUILD_PROFILE=release
ENV BUILD_PROFILE=$BUILD_PROFILE
@@ -20,10 +20,13 @@ ENV BUILD_PROFILE=$BUILD_PROFILE
ARG RUSTFLAGS=""
ENV RUSTFLAGS="$RUSTFLAGS"
RUN cargo chef cook --profile $BUILD_PROFILE --recipe-path recipe.json --manifest-path /app/crates/optimism/bin/Cargo.toml
ARG FEATURES=""
ENV FEATURES=$FEATURES
RUN cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --recipe-path recipe.json --manifest-path /app/crates/optimism/bin/Cargo.toml
COPY . .
RUN cargo build --profile $BUILD_PROFILE --bin op-reth --manifest-path /app/crates/optimism/bin/Cargo.toml
RUN cargo build --profile $BUILD_PROFILE --features "$FEATURES" --bin op-reth --manifest-path /app/crates/optimism/bin/Cargo.toml
RUN ls -la /app/target/$BUILD_PROFILE/op-reth
RUN cp /app/target/$BUILD_PROFILE/op-reth /app/op-reth

View File

@@ -30,7 +30,7 @@
Opstack tries to be as close to the L1 engine API as much as possible. Isthmus (Prague equivalent) introduced the first
deviation from the L1 engine API with an additional field in the `ExecutionPayload`. For this reason the op engine API
has it's own server traits `OpEngineApi`.
has its own server traits `OpEngineApi`.
Adding a new versioned endpoint requires the same changes as for L1 just for the dedicated OP types.
### Hardforks

View File

@@ -30,6 +30,11 @@ EF_TESTS_TAG := v17.0
EF_TESTS_URL := https://github.com/ethereum/tests/archive/refs/tags/$(EF_TESTS_TAG).tar.gz
EF_TESTS_DIR := ./testing/ef-tests/ethereum-tests
# The release tag of https://github.com/ethereum/execution-spec-tests to use for EEST tests
EEST_TESTS_TAG := v4.5.0
EEST_TESTS_URL := https://github.com/ethereum/execution-spec-tests/releases/download/$(EEST_TESTS_TAG)/fixtures_stable.tar.gz
EEST_TESTS_DIR := ./testing/ef-tests/execution-spec-tests
# The docker image name
DOCKER_IMAGE_NAME ?= ghcr.io/paradigmxyz/reth
@@ -42,14 +47,14 @@ help: ## Display this help.
##@ Build
.PHONY: install
install: ## Build and install the reth binary under `~/.cargo/bin`.
install: ## Build and install the reth binary under `$(CARGO_HOME)/bin`.
cargo install --path bin/reth --bin reth --force --locked \
--features "$(FEATURES)" \
--profile "$(PROFILE)" \
$(CARGO_INSTALL_EXTRA_FLAGS)
.PHONY: install-op
install-op: ## Build and install the op-reth binary under `~/.cargo/bin`.
install-op: ## Build and install the op-reth binary under `$(CARGO_HOME)/bin`.
cargo install --path crates/optimism/bin --bin op-reth --force --locked \
--features "$(FEATURES)" \
--profile "$(PROFILE)" \
@@ -202,9 +207,18 @@ $(EF_TESTS_DIR):
tar -xzf ethereum-tests.tar.gz --strip-components=1 -C $(EF_TESTS_DIR)
rm ethereum-tests.tar.gz
# Downloads and unpacks EEST tests in the `$(EEST_TESTS_DIR)` directory.
#
# Requires `wget` and `tar`
$(EEST_TESTS_DIR):
mkdir $(EEST_TESTS_DIR)
wget $(EEST_TESTS_URL) -O execution-spec-tests.tar.gz
tar -xzf execution-spec-tests.tar.gz --strip-components=1 -C $(EEST_TESTS_DIR)
rm execution-spec-tests.tar.gz
.PHONY: ef-tests
ef-tests: $(EF_TESTS_DIR) ## Runs Ethereum Foundation tests.
cargo nextest run -p ef-tests --features ef-tests
ef-tests: $(EF_TESTS_DIR) $(EEST_TESTS_DIR) ## Runs Legacy and EEST tests.
cargo nextest run -p ef-tests --release --features ef-tests
##@ reth-bench
@@ -212,8 +226,8 @@ ef-tests: $(EF_TESTS_DIR) ## Runs Ethereum Foundation tests.
reth-bench: ## Build the reth-bench binary into the `target` directory.
cargo build --manifest-path bin/reth-bench/Cargo.toml --features "$(FEATURES)" --profile "$(PROFILE)"
.PHONY: install-reth-bech
install-reth-bench: ## Build and install the reth binary under `~/.cargo/bin`.
.PHONY: install-reth-bench
install-reth-bench: ## Build and install the reth binary under `$(CARGO_HOME)/bin`.
cargo install --path bin/reth-bench --bin reth-bench --force --locked \
--features "$(FEATURES)" \
--profile "$(PROFILE)"
@@ -368,7 +382,7 @@ db-tools: ## Compile MDBX debugging tools.
.PHONY: update-book-cli
update-book-cli: build-debug ## Update book cli documentation.
@echo "Updating book cli doc..."
@./book/cli/update.sh $(CARGO_TARGET_DIR)/debug/reth
@./docs/cli/update.sh $(CARGO_TARGET_DIR)/debug/reth
.PHONY: profiling
profiling: ## Builds `reth` with optimisations, but also symbols.
@@ -415,12 +429,12 @@ clippy-op-dev:
--locked \
--all-features
lint-codespell: ensure-codespell
codespell --skip "*.json" --skip "./testing/ef-tests/ethereum-tests"
lint-typos: ensure-typos
typos
ensure-codespell:
@if ! command -v codespell &> /dev/null; then \
echo "codespell not found. Please install it by running the command `pip install codespell` or refer to the following link for more information: https://github.com/codespell-project/codespell" \
ensure-typos:
@if ! command -v typos &> /dev/null; then \
echo "typos not found. Please install it by running the command 'cargo install typos-cli' or refer to the following link for more information: https://github.com/crate-ci/typos"; \
exit 1; \
fi
@@ -439,14 +453,14 @@ lint-toml: ensure-dprint
ensure-dprint:
@if ! command -v dprint &> /dev/null; then \
echo "dprint not found. Please install it by running the command `cargo install --locked dprint` or refer to the following link for more information: https://github.com/dprint/dprint" \
echo "dprint not found. Please install it by running the command 'cargo install --locked dprint' or refer to the following link for more information: https://github.com/dprint/dprint"; \
exit 1; \
fi
lint:
make fmt && \
make clippy && \
make lint-codespell && \
make lint-typos && \
make lint-toml
clippy-fix:

View File

@@ -10,7 +10,7 @@
![](./assets/reth-prod.png)
**[Install](https://paradigmxyz.github.io/reth/installation/installation.html)**
| [User Book](https://reth.rs)
| [User Docs](https://reth.rs)
| [Developer Docs](./docs)
| [Crate Docs](https://reth.rs/docs)
@@ -29,7 +29,7 @@ As a full Ethereum node, Reth allows users to connect to the Ethereum network an
More concretely, our goals are:
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. Examples of such usage include but are not limited to spinning up standalone P2P networks, talking directly to a node's database, or "unbundling" the node into the components you need. To achieve that, we are licensing Reth under the Apache/MIT permissive license. You can learn more about the project's components [here](./docs/repo/layout.md).
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 weve battle-tested and optimized via [Foundry](https://github.com/foundry-rs/foundry/).
2. **Performance**: Reth aims to be fast, so we use 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/).
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.
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.
5. **Support as many EVM chains as possible**: We aspire that Reth can full-sync not only Ethereum, but also other chains like Optimism, Polygon, BNB Smart Chain, and more. If you're working on any of these projects, please reach out.
@@ -40,17 +40,18 @@ More concretely, our goals are:
Reth is production ready, and suitable for usage in mission-critical environments such as staking or high-uptime services. We also actively recommend professional node operators to switch to Reth in production for performance and cost reasons in use cases where high performance with great margins is required such as RPC, MEV, Indexing, Simulations, and P2P activities.
More historical context below:
* We released 1.0 "production-ready" stable Reth in June 2024.
* Reth completed an audit with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](./audit/sigma_prime_audit_v2.pdf).
* Revm (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)). We will publish the results soon.
* We released multiple iterative beta versions, up to [beta.9](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.9) on Monday June 3rd 2024 the last beta release.
* We released [beta](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) on Monday March 4th 2024, our first breaking change to the database model, providing faster query speed, smaller database footprint, and allowing "history" to be mounted on separate drives.
* We shipped iterative improvements until the last alpha release on February 28th 2024, [0.1.0-alpha.21](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.21).
* We [initially announced](https://www.paradigm.xyz/2023/06/reth-alpha) [0.1.0-alpha.1](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.1) in June 20th 2023.
- We released 1.0 "production-ready" stable Reth in June 2024.
- Reth completed an audit with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](./audit/sigma_prime_audit_v2.pdf).
- Revm (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)). We will publish the results soon.
- We released multiple iterative beta versions, up to [beta.9](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.9) on Monday June 3, 2024,the last beta release.
- We released [beta](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) on Monday March 4, 2024, our first breaking change to the database model, providing faster query speed, smaller database footprint, and allowing "history" to be mounted on separate drives.
- We shipped iterative improvements until the last alpha release on February 28, 2024, [0.1.0-alpha.21](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.21).
- We [initially announced](https://www.paradigm.xyz/2023/06/reth-alpha) [0.1.0-alpha.1](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.1) on June 20, 2023.
### Database compatibility
We do not have any breaking database changes since beta.1, and do not plan any in the near future.
We do not have any breaking database changes since beta.1, and we do not plan any in the near future.
Reth [v0.2.0-beta.1](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) includes
a [set of breaking database changes](https://github.com/paradigmxyz/reth/pull/5191) that makes it impossible to use database files produced by earlier versions.
@@ -60,7 +61,7 @@ If you had a database produced by alpha versions of Reth, you need to drop it wi
## For Users
See the [Reth Book](https://paradigmxyz.github.io/reth) for instructions on how to install and run Reth.
See the [Reth documentation](https://paradigmxyz.github.io/reth) for instructions on how to install and run Reth.
## For Developers
@@ -76,21 +77,20 @@ For a general overview of the crates, see [Project Layout](./docs/repo/layout.md
If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/paradigm_reth) to chat with us about the development of Reth!
- Our contributor guidelines can be found in [`CONTRIBUTING.md`](./CONTRIBUTING.md).
- See our [contributor docs](./docs) for more information on the project. A good starting point is [Project Layout](./docs/repo/layout.md).
- Our contributor guidelines can be found in [`CONTRIBUTING.md`](./CONTRIBUTING.md).
- See our [contributor docs](./docs) for more information on the project. A good starting point is [Project Layout](./docs/repo/layout.md).
### Building and testing
<!--
When updating this, also update:
- clippy.toml
- Cargo.toml
- .github/workflows/lint.yml
-->
The Minimum Supported Rust Version (MSRV) of this project is [1.86.0](https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/).
The Minimum Supported Rust Version (MSRV) of this project is [1.88.0](https://blog.rust-lang.org/2025/06/26/Rust-1.88.0/).
See the book for detailed instructions on how to [build from source](https://paradigmxyz.github.io/reth/installation/source.html).
See the docs for detailed instructions on how to [build from source](https://paradigmxyz.github.io/reth/installation/source).
To fully test Reth, you will need to have [Geth installed](https://geth.ethereum.org/docs/getting-started/installing-geth), but it is possible to run a subset of tests without Geth.
@@ -119,13 +119,13 @@ Using `cargo test` to run tests may work fine, but this is not tested and does n
## Getting Help
If you have any questions, first see if the answer to your question can be found in the [book][book].
If you have any questions, first see if the answer to your question can be found in the [docs][book].
If the answer is not there:
- Join the [Telegram][tg-url] to get help, or
- Open a [discussion](https://github.com/paradigmxyz/reth/discussions/new) with your question, or
- Open an issue with [the bug](https://github.com/paradigmxyz/reth/issues/new?assignees=&labels=C-bug%2CS-needs-triage&projects=&template=bug.yml)
- Join the [Telegram][tg-url] to get help, or
- Open a [discussion](https://github.com/paradigmxyz/reth/discussions/new) with your question, or
- Open an issue with [the bug](https://github.com/paradigmxyz/reth/issues/new?assignees=&labels=C-bug%2CS-needs-triage&projects=&template=bug.yml)
## Security
@@ -137,9 +137,9 @@ Reth is a new implementation of the Ethereum protocol. In the process of develop
None of this would have been possible without them, so big shoutout to the teams below:
- [Geth](https://github.com/ethereum/go-ethereum/): We would like to express our heartfelt gratitude to the go-ethereum team for their outstanding contributions to Ethereum over the years. Their tireless efforts and dedication have helped to shape the Ethereum ecosystem and make it the vibrant and innovative community it is today. Thank you for your hard work and commitment to the project.
- [Erigon](https://github.com/ledgerwatch/erigon) (fka Turbo-Geth): Erigon pioneered the ["Staged Sync" architecture](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) that Reth is using, as well as [introduced MDBX](https://github.com/ledgerwatch/erigon/wiki/Choice-of-storage-engine) as the database of choice. We thank Erigon for pushing the state of the art research on the performance limits of Ethereum nodes.
- [Akula](https://github.com/akula-bft/akula/): Reth uses forks of the Apache versions of Akula's [MDBX Bindings](https://github.com/paradigmxyz/reth/pull/132), [FastRLP](https://github.com/paradigmxyz/reth/pull/63) and [ECIES](https://github.com/paradigmxyz/reth/pull/80) . Given that these packages were already released under the Apache License, and they implement standardized solutions, we decided not to reimplement them to iterate faster. We thank the Akula team for their contributions to the Rust Ethereum ecosystem and for publishing these packages.
- [Geth](https://github.com/ethereum/go-ethereum/): We would like to express our heartfelt gratitude to the go-ethereum team for their outstanding contributions to Ethereum over the years. Their tireless efforts and dedication have helped to shape the Ethereum ecosystem and make it the vibrant and innovative community it is today. Thank you for your hard work and commitment to the project.
- [Erigon](https://github.com/ledgerwatch/erigon) (fka Turbo-Geth): Erigon pioneered the ["Staged Sync" architecture](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) that Reth is using, as well as [introduced MDBX](https://github.com/ledgerwatch/erigon/wiki/Choice-of-storage-engine) as the database of choice. We thank Erigon for pushing the state of the art research on the performance limits of Ethereum nodes.
- [Akula](https://github.com/akula-bft/akula/): Reth uses forks of the Apache versions of Akula's [MDBX Bindings](https://github.com/paradigmxyz/reth/pull/132), [FastRLP](https://github.com/paradigmxyz/reth/pull/63) and [ECIES](https://github.com/paradigmxyz/reth/pull/80). Given that these packages were already released under the Apache License, and they implement standardized solutions, we decided not to reimplement them to iterate faster. We thank the Akula team for their contributions to the Rust Ethereum ecosystem and for publishing these packages.
## Warning

View File

@@ -35,6 +35,7 @@ alloy-transport-ipc.workspace = true
alloy-transport-ws.workspace = true
alloy-transport.workspace = true
op-alloy-consensus = { workspace = true, features = ["alloy-compat"] }
op-alloy-rpc-types-engine = { workspace = true, features = ["serde"] }
# reqwest
reqwest = { workspace = true, default-features = false, features = ["rustls-tls-native-roots"] }
@@ -64,7 +65,6 @@ humantime.workspace = true
csv.workspace = true
[dev-dependencies]
reth-tracing.workspace = true
[features]
default = ["jemalloc"]

View File

@@ -49,7 +49,7 @@ reth stage unwind to-block 21000000
The following `reth-bench` command would then start the benchmark at block 21,000,000:
```bash
reth-bench new-payload-fcu --rpc-url <rpc-url> --from 21000000 --to <end_block> --jwtsecret <jwt_file_path>
reth-bench new-payload-fcu --rpc-url <rpc-url> --from 21000000 --to <end_block> --jwt-secret <jwt_file_path>
```
Finally, make sure that reth is built using a build profile suitable for what you are trying to measure.
@@ -80,11 +80,11 @@ RUSTFLAGS="-C target-cpu=native" cargo build --profile profiling --no-default-fe
### Run the Benchmark:
First, start the reth node. Here is an example that runs `reth` compiled with the `profiling` profile, runs `samply`, and configures `reth` to run with metrics enabled:
```bash
samply record -p 3001 target/profiling/reth node --metrics localhost:9001 --authrpc.jwtsecret <jwt_file_path>
samply record -p 3001 target/profiling/reth node --metrics localhost:9001 --authrpc.jwt-secret <jwt_file_path>
```
```bash
reth-bench new-payload-fcu --rpc-url <rpc-url> --from <start_block> --to <end_block> --jwtsecret <jwt_file_path>
reth-bench new-payload-fcu --rpc-url <rpc-url> --from <start_block> --to <end_block> --jwt-secret <jwt_file_path>
```
Replace `<start_block>`, `<end_block>`, and `<jwt_file_path>` with the appropriate values for your testing environment. `<rpc-url>` should be the URL of an RPC endpoint that can provide the blocks that will be used during the execution.
@@ -92,6 +92,18 @@ This should NOT be the node that is being used for the benchmark. The node behin
the benchmark. The node being benchmarked will not have these blocks.
Note that this assumes that the benchmark node's engine API is running on `http://127.0.0.1:8551`, which is set as a default value in `reth-bench`. To configure this value, use the `--engine-rpc-url` flag.
#### Using the `--advance` argument
The `--advance` argument allows you to benchmark a relative number of blocks from the current head, without manually specifying `--from` and `--to`.
```bash
# Benchmark the next 10 blocks from the current head
reth-bench new-payload-fcu --advance 10 --jwt-secret <jwt_file_path> --rpc-url <rpc-url>
# Benchmark the next 50 blocks with a different subcommand
reth-bench new-payload-only --advance 50 --jwt-secret <jwt_file_path> --rpc-url <rpc-url>
```
### Observe Outputs
After running the command, `reth-bench` will output benchmark results, showing processing speeds and gas usage, which are useful metrics for analyzing the node's performance.

View File

@@ -1,4 +1,12 @@
#!/usr/bin/env python3
#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.8"
# dependencies = [
# "pandas",
# "matplotlib",
# "numpy",
# ]
# ///
# A simple script which plots graphs comparing two combined_latency.csv files
# output by reth-bench. The graphs which are plotted are:
@@ -8,6 +16,8 @@
#
# - A simple line graph plotting the latencies of the two files against each
# other.
#
# - A gas per second (gas/s) chart showing throughput over time.
import argparse
@@ -15,15 +25,82 @@ import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import sys
import os
from matplotlib.ticker import FuncFormatter
def get_output_filename(base_path, suffix=None):
"""Generate output filename with optional suffix."""
if suffix is None:
return base_path
# Split the base path into directory, name, and extension
dir_name = os.path.dirname(base_path)
base_name = os.path.basename(base_path)
name, ext = os.path.splitext(base_name)
# Create new filename with suffix
new_name = f"{name}_{suffix}{ext}"
return os.path.join(dir_name, new_name) if dir_name else new_name
def format_gas_units(value, pos):
"""Format gas values with appropriate units (gas, Kgas, Mgas, Ggas, Tgas)."""
if value == 0:
return '0'
# Define unit thresholds and labels
units = [
(1e12, 'Tgas'), # Teragas
(1e9, 'Ggas'), # Gigagas
(1e6, 'Mgas'), # Megagas
(1e3, 'Kgas'), # Kilogas
(1, 'gas') # gas
]
abs_value = abs(value)
for threshold, unit in units:
if abs_value >= threshold:
scaled_value = value / threshold
# Format with appropriate precision
if scaled_value >= 100:
return f'{scaled_value:.0f}{unit}/s'
elif scaled_value >= 10:
return f'{scaled_value:.1f}{unit}/s'
else:
return f'{scaled_value:.2f}{unit}/s'
return f'{value:.0f}gas/s'
def moving_average(data, window_size):
"""Calculate moving average with given window size."""
if window_size <= 1:
return data
# Use pandas for efficient rolling mean calculation
series = pd.Series(data)
return series.rolling(window=window_size, center=True, min_periods=1).mean().values
def main():
parser = argparse.ArgumentParser(description='Generate histogram of total_latency percent differences between two CSV files')
parser.add_argument('baseline_csv', help='First CSV file, used as the baseline/control')
parser.add_argument('comparison_csv', help='Second CSV file, which is being compared to the baseline')
parser.add_argument('-o', '--output', default='latency.png', help='Output image file (default: latency.png)')
parser.add_argument('--graphs', default='all', help='Comma-separated list of graphs to plot: histogram, line, gas, all (default: all)')
parser.add_argument('--average', type=int, metavar='N', help='Apply moving average over N blocks to smooth line and gas charts')
parser.add_argument('--separate', action='store_true', help='Output each chart as a separate file')
args = parser.parse_args()
# Parse graph selection
if args.graphs.lower() == 'all':
selected_graphs = {'histogram', 'line', 'gas'}
else:
selected_graphs = set(graph.strip().lower() for graph in args.graphs.split(','))
valid_graphs = {'histogram', 'line', 'gas'}
invalid_graphs = selected_graphs - valid_graphs
if invalid_graphs:
print(f"Error: Invalid graph types: {', '.join(invalid_graphs)}. Valid options are: histogram, line, gas, all", file=sys.stderr)
sys.exit(1)
try:
df1 = pd.read_csv(args.baseline_csv)
df2 = pd.read_csv(args.comparison_csv)
@@ -42,14 +119,24 @@ def main():
print(f"Error: 'total_latency' column not found in {args.comparison_csv}", file=sys.stderr)
sys.exit(1)
# Check for gas_used column if gas graph is selected
if 'gas' in selected_graphs:
if 'gas_used' not in df1.columns:
print(f"Error: 'gas_used' column not found in {args.baseline_csv} (required for gas graph)", file=sys.stderr)
sys.exit(1)
if 'gas_used' not in df2.columns:
print(f"Error: 'gas_used' column not found in {args.comparison_csv} (required for gas graph)", file=sys.stderr)
sys.exit(1)
if len(df1) != len(df2):
print("Warning: CSV files have different number of rows. Using minimum length.", file=sys.stderr)
min_len = min(len(df1), len(df2))
df1 = df1.head(min_len)
df2 = df2.head(min_len)
latency1 = df1['total_latency'].values
latency2 = df2['total_latency'].values
# Convert from microseconds to milliseconds for better readability
latency1 = df1['total_latency'].values / 1000.0
latency2 = df2['total_latency'].values / 1000.0
# Handle division by zero
with np.errstate(divide='ignore', invalid='ignore'):
@@ -62,54 +149,220 @@ def main():
print("Error: No valid percent differences could be calculated", file=sys.stderr)
sys.exit(1)
# Create histogram with 1% buckets
min_diff = np.floor(percent_diff.min())
max_diff = np.ceil(percent_diff.max())
bins = np.arange(min_diff, max_diff + 1, 1)
# Create figure with two subplots
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))
# Top subplot: Histogram
ax1.hist(percent_diff, bins=bins, edgecolor='black', alpha=0.7)
ax1.set_xlabel('Percent Difference (%)')
ax1.set_ylabel('Number of Blocks')
ax1.set_title(f'Total Latency Percent Difference Histogram\n({args.baseline_csv} vs {args.comparison_csv})')
ax1.grid(True, alpha=0.3)
# Add statistics to the histogram
# Calculate statistics once for use in graphs and output
mean_diff = np.mean(percent_diff)
median_diff = np.median(percent_diff)
ax1.axvline(mean_diff, color='red', linestyle='--', label=f'Mean: {mean_diff:.2f}%')
ax1.axvline(median_diff, color='orange', linestyle='--', label=f'Median: {median_diff:.2f}%')
ax1.legend()
# Bottom subplot: Latency vs Block Number
if 'block_number' in df1.columns and 'block_number' in df2.columns:
block_numbers = df1['block_number'].values[:len(percent_diff)]
ax2.plot(block_numbers, latency1[:len(percent_diff)], 'b-', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax2.plot(block_numbers, latency2[:len(percent_diff)], 'r-', alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax2.set_xlabel('Block Number')
ax2.set_ylabel('Total Latency (ms)')
ax2.set_title('Total Latency vs Block Number')
ax2.grid(True, alpha=0.3)
ax2.legend()
# Determine number of subplots and create figure
num_plots = len(selected_graphs)
if num_plots == 0:
print("Error: No valid graphs selected", file=sys.stderr)
sys.exit(1)
# Store output filenames
output_files = []
if args.separate:
# We'll create individual figures for each graph
pass
else:
# If no block_number column, use index
indices = np.arange(len(percent_diff))
ax2.plot(indices, latency1[:len(percent_diff)], 'b-', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax2.plot(indices, latency2[:len(percent_diff)], 'r-', alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax2.set_xlabel('Block Index')
ax2.set_ylabel('Total Latency (ms)')
ax2.set_title('Total Latency vs Block Index')
ax2.grid(True, alpha=0.3)
ax2.legend()
# Create combined figure
if num_plots == 1:
fig, ax = plt.subplots(1, 1, figsize=(12, 6))
axes = [ax]
else:
fig, axes = plt.subplots(num_plots, 1, figsize=(12, 6 * num_plots))
plt.tight_layout()
plt.savefig(args.output, dpi=300, bbox_inches='tight')
print(f"Histogram and latency graph saved to {args.output}")
plot_idx = 0
# Plot histogram if selected
if 'histogram' in selected_graphs:
if args.separate:
fig, ax = plt.subplots(1, 1, figsize=(12, 6))
else:
ax = axes[plot_idx]
min_diff = np.floor(percent_diff.min())
max_diff = np.ceil(percent_diff.max())
# Create histogram with 1% buckets
bins = np.arange(min_diff, max_diff + 1, 1)
ax.hist(percent_diff, bins=bins, edgecolor='black', alpha=0.7)
ax.set_xlabel('Percent Difference (%)')
ax.set_ylabel('Number of Blocks')
ax.set_title(f'Total Latency Percent Difference Histogram\n({args.baseline_csv} vs {args.comparison_csv})')
ax.grid(True, alpha=0.3)
# Add statistics to the histogram
ax.axvline(mean_diff, color='red', linestyle='--', label=f'Mean: {mean_diff:.2f}%')
ax.axvline(median_diff, color='orange', linestyle='--', label=f'Median: {median_diff:.2f}%')
ax.legend()
if args.separate:
plt.tight_layout()
output_file = get_output_filename(args.output, 'histogram')
plt.savefig(output_file, dpi=300, bbox_inches='tight')
output_files.append(output_file)
plt.close(fig)
else:
plot_idx += 1
# Plot line graph if selected
if 'line' in selected_graphs:
if args.separate:
fig, ax = plt.subplots(1, 1, figsize=(12, 6))
else:
ax = axes[plot_idx]
# Determine comparison color based on median change. The median being
# negative means processing time got faster, so that becomes green.
comparison_color = 'green' if median_diff < 0 else 'red'
# Apply moving average if requested
plot_latency1 = latency1[:len(percent_diff)]
plot_latency2 = latency2[:len(percent_diff)]
if args.average:
plot_latency1 = moving_average(plot_latency1, args.average)
plot_latency2 = moving_average(plot_latency2, args.average)
if 'block_number' in df1.columns and 'block_number' in df2.columns:
block_numbers = df1['block_number'].values[:len(percent_diff)]
ax.plot(block_numbers, plot_latency1, 'orange', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax.plot(block_numbers, plot_latency2, comparison_color, alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax.set_xlabel('Block Number')
ax.set_ylabel('Total Latency (ms)')
title = 'Total Latency vs Block Number'
if args.average:
title += f' ({args.average}-block moving average)'
ax.set_title(title)
ax.grid(True, alpha=0.3)
ax.legend()
else:
# If no block_number column, use index
indices = np.arange(len(percent_diff))
ax.plot(indices, plot_latency1, 'orange', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax.plot(indices, plot_latency2, comparison_color, alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax.set_xlabel('Block Index')
ax.set_ylabel('Total Latency (ms)')
title = 'Total Latency vs Block Index'
if args.average:
title += f' ({args.average}-block moving average)'
ax.set_title(title)
ax.grid(True, alpha=0.3)
ax.legend()
if args.separate:
plt.tight_layout()
output_file = get_output_filename(args.output, 'line')
plt.savefig(output_file, dpi=300, bbox_inches='tight')
output_files.append(output_file)
plt.close(fig)
else:
plot_idx += 1
# Plot gas/s graph if selected
if 'gas' in selected_graphs:
if args.separate:
fig, ax = plt.subplots(1, 1, figsize=(12, 6))
else:
ax = axes[plot_idx]
# Calculate gas per second (gas/s)
# latency is in microseconds, so convert to seconds for gas/s calculation
gas1 = df1['gas_used'].values[:len(percent_diff)]
gas2 = df2['gas_used'].values[:len(percent_diff)]
# Convert latency from microseconds to seconds
latency1_sec = df1['total_latency'].values[:len(percent_diff)] / 1_000_000.0
latency2_sec = df2['total_latency'].values[:len(percent_diff)] / 1_000_000.0
# Calculate gas per second
gas_per_sec1 = gas1 / latency1_sec
gas_per_sec2 = gas2 / latency2_sec
# Store original values for statistics before averaging
original_gas_per_sec1 = gas_per_sec1.copy()
original_gas_per_sec2 = gas_per_sec2.copy()
# Apply moving average if requested
if args.average:
gas_per_sec1 = moving_average(gas_per_sec1, args.average)
gas_per_sec2 = moving_average(gas_per_sec2, args.average)
# Calculate median gas/s for color determination (use original values)
median_gas_per_sec1 = np.median(original_gas_per_sec1)
median_gas_per_sec2 = np.median(original_gas_per_sec2)
comparison_color = 'green' if median_gas_per_sec2 > median_gas_per_sec1 else 'red'
if 'block_number' in df1.columns and 'block_number' in df2.columns:
block_numbers = df1['block_number'].values[:len(percent_diff)]
ax.plot(block_numbers, gas_per_sec1, 'orange', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax.plot(block_numbers, gas_per_sec2, comparison_color, alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax.set_xlabel('Block Number')
ax.set_ylabel('Gas Throughput')
title = 'Gas Throughput vs Block Number'
if args.average:
title += f' ({args.average}-block moving average)'
ax.set_title(title)
ax.grid(True, alpha=0.3)
ax.legend()
# Format Y-axis with gas units
formatter = FuncFormatter(format_gas_units)
ax.yaxis.set_major_formatter(formatter)
else:
# If no block_number column, use index
indices = np.arange(len(percent_diff))
ax.plot(indices, gas_per_sec1, 'orange', alpha=0.7, label=f'Baseline ({args.baseline_csv})')
ax.plot(indices, gas_per_sec2, comparison_color, alpha=0.7, label=f'Comparison ({args.comparison_csv})')
ax.set_xlabel('Block Index')
ax.set_ylabel('Gas Throughput')
title = 'Gas Throughput vs Block Index'
if args.average:
title += f' ({args.average}-block moving average)'
ax.set_title(title)
ax.grid(True, alpha=0.3)
ax.legend()
# Format Y-axis with gas units
formatter = FuncFormatter(format_gas_units)
ax.yaxis.set_major_formatter(formatter)
if args.separate:
plt.tight_layout()
output_file = get_output_filename(args.output, 'gas')
plt.savefig(output_file, dpi=300, bbox_inches='tight')
output_files.append(output_file)
plt.close(fig)
else:
plot_idx += 1
# Save combined figure if not using separate files
if not args.separate:
plt.tight_layout()
plt.savefig(args.output, dpi=300, bbox_inches='tight')
output_files.append(args.output)
# Create graph type description for output message
graph_types = []
if 'histogram' in selected_graphs:
graph_types.append('histogram')
if 'line' in selected_graphs:
graph_types.append('latency graph')
if 'gas' in selected_graphs:
graph_types.append('gas/s graph')
graph_desc = ' and '.join(graph_types)
# Print output file(s) information
if args.separate:
print(f"Saved {len(output_files)} separate files:")
for output_file in output_files:
print(f" - {output_file}")
else:
print(f"{graph_desc.capitalize()} saved to {args.output}")
# Always print statistics
print(f"\nStatistics:")
print(f"Mean percent difference: {mean_diff:.2f}%")
print(f"Median percent difference: {median_diff:.2f}%")
@@ -117,6 +370,15 @@ def main():
print(f"Min: {percent_diff.min():.2f}%")
print(f"Max: {percent_diff.max():.2f}%")
print(f"Total blocks analyzed: {len(percent_diff)}")
# Print gas/s statistics if gas data is available
if 'gas' in selected_graphs:
# Use original values for statistics (not averaged)
print(f"\nGas/s Statistics:")
print(f"Baseline median gas/s: {median_gas_per_sec1:,.0f}")
print(f"Comparison median gas/s: {median_gas_per_sec2:,.0f}")
gas_diff_percent = ((median_gas_per_sec2 - median_gas_per_sec1) / median_gas_per_sec1) * 100
print(f"Gas/s percent change: {gas_diff_percent:+.2f}%")
if __name__ == '__main__':
main()

View File

@@ -3,6 +3,7 @@
use crate::{authenticated_transport::AuthenticatedTransportConnect, bench_mode::BenchMode};
use alloy_eips::BlockNumberOrTag;
use alloy_primitives::address;
use alloy_provider::{network::AnyNetwork, Provider, RootProvider};
use alloy_rpc_client::ClientBuilder;
use alloy_rpc_types_engine::JwtSecret;
@@ -25,6 +26,8 @@ pub(crate) struct BenchContext {
pub(crate) benchmark_mode: BenchMode,
/// The next block to fetch.
pub(crate) next_block: u64,
/// Whether the chain is an OP rollup.
pub(crate) is_optimism: bool,
}
impl BenchContext {
@@ -33,26 +36,33 @@ impl BenchContext {
pub(crate) async fn new(bench_args: &BenchmarkArgs, rpc_url: String) -> eyre::Result<Self> {
info!("Running benchmark using data from RPC URL: {}", rpc_url);
// Ensure that output directory is a directory
// Ensure that output directory exists and is a directory
if let Some(output) = &bench_args.output {
if output.is_file() {
return Err(eyre::eyre!("Output path must be a directory"));
}
// Create the directory if it doesn't exist
if !output.exists() {
std::fs::create_dir_all(output)?;
info!("Created output directory: {:?}", output);
}
}
// set up alloy client for blocks
let client = ClientBuilder::default().http(rpc_url.parse()?);
let block_provider = RootProvider::<AnyNetwork>::new(client);
// If neither `--from` nor `--to` are provided, we will run the benchmark continuously,
// starting at the latest block.
let mut benchmark_mode = BenchMode::new(bench_args.from, bench_args.to)?;
// Check if this is an OP chain by checking code at a predeploy address.
let is_optimism = !block_provider
.get_code_at(address!("0x420000000000000000000000000000000000000F"))
.await?
.is_empty();
// construct the authenticated provider
let auth_jwt = bench_args
.auth_jwtsecret
.clone()
.ok_or_else(|| eyre::eyre!("--jwtsecret must be provided for authenticated RPC"))?;
.ok_or_else(|| eyre::eyre!("--jwt-secret must be provided for authenticated RPC"))?;
// fetch jwt from file
//
@@ -69,6 +79,31 @@ impl BenchContext {
let client = ClientBuilder::default().connect_with(auth_transport).await?;
let auth_provider = RootProvider::<AnyNetwork>::new(client);
// Computes the block range for the benchmark.
//
// - If `--advance` is provided, fetches the latest block and sets:
// - `from = head + 1`
// - `to = head + advance`
// - Otherwise, uses the values from `--from` and `--to`.
let (from, to) = if let Some(advance) = bench_args.advance {
if advance == 0 {
return Err(eyre::eyre!("--advance must be greater than 0"));
}
let head_block = auth_provider
.get_block_by_number(BlockNumberOrTag::Latest)
.await?
.ok_or_else(|| eyre::eyre!("Failed to fetch latest block for --advance"))?;
let head_number = head_block.header.number;
(Some(head_number), Some(head_number + advance))
} else {
(bench_args.from, bench_args.to)
};
// If neither `--from` nor `--to` are provided, we will run the benchmark continuously,
// starting at the latest block.
let mut benchmark_mode = BenchMode::new(from, to)?;
let first_block = match benchmark_mode {
BenchMode::Continuous => {
// fetch Latest block
@@ -94,6 +129,6 @@ impl BenchContext {
};
let next_block = first_block.header.number + 1;
Ok(Self { auth_provider, block_provider, benchmark_mode, next_block })
Ok(Self { auth_provider, block_provider, benchmark_mode, next_block, is_optimism })
}
}

View File

@@ -38,7 +38,7 @@ pub enum Subcommands {
///
/// One powerful use case is pairing this command with the `cast block` command, for example:
///
/// `cast block latest--full --json | reth-bench send-payload --rpc-url localhost:5000
/// `cast block latest --full --json | reth-bench send-payload --rpc-url localhost:5000
/// --jwt-secret $(cat ~/.local/share/reth/mainnet/jwt.hex)`
SendPayload(send_payload::Command),
}

View File

@@ -9,12 +9,13 @@ use crate::{
GAS_OUTPUT_SUFFIX,
},
},
valid_payload::{call_forkchoice_updated, call_new_payload},
valid_payload::{block_to_new_payload, call_forkchoice_updated, call_new_payload},
};
use alloy_provider::Provider;
use alloy_rpc_types_engine::{ExecutionPayload, ForkchoiceState};
use alloy_rpc_types_engine::ForkchoiceState;
use clap::Parser;
use csv::Writer;
use eyre::Context;
use humantime::parse_duration;
use reth_cli_runner::CliContext;
use reth_node_core::args::BenchmarkArgs;
@@ -39,32 +40,27 @@ pub struct Command {
impl Command {
/// Execute `benchmark new-payload-fcu` command
pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> {
let BenchContext { benchmark_mode, block_provider, auth_provider, mut next_block } =
BenchContext::new(&self.benchmark, self.rpc_url).await?;
let BenchContext {
benchmark_mode,
block_provider,
auth_provider,
mut next_block,
is_optimism,
} = BenchContext::new(&self.benchmark, self.rpc_url).await?;
let (sender, mut receiver) = tokio::sync::mpsc::channel(1000);
tokio::task::spawn(async move {
while benchmark_mode.contains(next_block) {
let block_res = block_provider.get_block_by_number(next_block.into()).full().await;
let block_res = block_provider
.get_block_by_number(next_block.into())
.full()
.await
.wrap_err_with(|| format!("Failed to fetch block by number {next_block}"));
let block = block_res.unwrap().unwrap();
let header = block.header.clone();
let block = block
.into_inner()
.map_header(|header| header.map(|h| h.into_header_with_defaults()))
.try_map_transactions(|tx| {
// try to convert unknowns into op type so that we can also support optimism
tx.try_into_either::<op_alloy_consensus::OpTxEnvelope>()
})
.unwrap()
.into_consensus();
let blob_versioned_hashes =
block.body.blob_versioned_hashes_iter().copied().collect::<Vec<_>>();
// Convert to execution payload
let (payload, sidecar) = ExecutionPayload::from_block_slow(&block);
let header = block.header;
let head_block_hash = payload.block_hash();
let (version, params) = block_to_new_payload(block, is_optimism).unwrap();
let head_block_hash = header.hash;
let safe_block_hash =
block_provider.get_block_by_number(header.number.saturating_sub(32).into());
@@ -81,9 +77,8 @@ impl Command {
sender
.send((
header,
blob_versioned_hashes,
payload,
sidecar,
version,
params,
head_block_hash,
safe_block_hash,
finalized_block_hash,
@@ -98,7 +93,7 @@ impl Command {
let total_benchmark_duration = Instant::now();
let mut total_wait_time = Duration::ZERO;
while let Some((header, versioned_hashes, payload, sidecar, head, safe, finalized)) = {
while let Some((header, version, params, head, safe, finalized)) = {
let wait_start = Instant::now();
let result = receiver.recv().await;
total_wait_time += wait_start.elapsed();
@@ -118,19 +113,11 @@ impl Command {
};
let start = Instant::now();
let message_version = call_new_payload(
&auth_provider,
payload,
sidecar,
header.parent_beacon_block_root,
versioned_hashes,
)
.await?;
call_new_payload(&auth_provider, version, params).await?;
let new_payload_result = NewPayloadResult { gas_used, latency: start.elapsed() };
call_forkchoice_updated(&auth_provider, message_version, forkchoice_state, None)
.await?;
call_forkchoice_updated(&auth_provider, version, forkchoice_state, None).await?;
// calculate the total duration and the fcu latency, record
let total_latency = start.elapsed();
@@ -182,7 +169,7 @@ impl Command {
}
// accumulate the results and calculate the overall Ggas/s
let gas_output = TotalGasOutput::new(gas_output_results);
let gas_output = TotalGasOutput::new(gas_output_results)?;
info!(
total_duration=?gas_output.total_duration,
total_gas_used=?gas_output.total_gas_used,

View File

@@ -8,12 +8,12 @@ use crate::{
NEW_PAYLOAD_OUTPUT_SUFFIX,
},
},
valid_payload::call_new_payload,
valid_payload::{block_to_new_payload, call_new_payload},
};
use alloy_provider::Provider;
use alloy_rpc_types_engine::ExecutionPayload;
use clap::Parser;
use csv::Writer;
use eyre::Context;
use reth_cli_runner::CliContext;
use reth_node_core::args::BenchmarkArgs;
use std::time::{Duration, Instant};
@@ -33,29 +33,29 @@ pub struct Command {
impl Command {
/// Execute `benchmark new-payload-only` command
pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> {
let BenchContext { benchmark_mode, block_provider, auth_provider, mut next_block } =
BenchContext::new(&self.benchmark, self.rpc_url).await?;
let BenchContext {
benchmark_mode,
block_provider,
auth_provider,
mut next_block,
is_optimism,
} = BenchContext::new(&self.benchmark, self.rpc_url).await?;
let (sender, mut receiver) = tokio::sync::mpsc::channel(1000);
tokio::task::spawn(async move {
while benchmark_mode.contains(next_block) {
let block_res = block_provider.get_block_by_number(next_block.into()).full().await;
let block_res = block_provider
.get_block_by_number(next_block.into())
.full()
.await
.wrap_err_with(|| format!("Failed to fetch block by number {next_block}"));
let block = block_res.unwrap().unwrap();
let block = block
.into_inner()
.map_header(|header| header.map(|h| h.into_header_with_defaults()))
.try_map_transactions(|tx| {
tx.try_into_either::<op_alloy_consensus::OpTxEnvelope>()
})
.unwrap()
.into_consensus();
let header = block.header.clone();
let blob_versioned_hashes =
block.body.blob_versioned_hashes_iter().copied().collect::<Vec<_>>();
let (payload, sidecar) = ExecutionPayload::from_block_slow(&block);
let (version, params) = block_to_new_payload(block, is_optimism).unwrap();
next_block += 1;
sender.send((block.header, blob_versioned_hashes, payload, sidecar)).await.unwrap();
sender.send((header, version, params)).await.unwrap();
}
});
@@ -64,7 +64,7 @@ impl Command {
let total_benchmark_duration = Instant::now();
let mut total_wait_time = Duration::ZERO;
while let Some((header, versioned_hashes, payload, sidecar)) = {
while let Some((header, version, params)) = {
let wait_start = Instant::now();
let result = receiver.recv().await;
total_wait_time += wait_start.elapsed();
@@ -73,7 +73,7 @@ impl Command {
// just put gas used here
let gas_used = header.gas_used;
let block_number = payload.block_number();
let block_number = header.number;
debug!(
target: "reth-bench",
@@ -82,14 +82,7 @@ impl Command {
);
let start = Instant::now();
call_new_payload(
&auth_provider,
payload,
sidecar,
header.parent_beacon_block_root,
versioned_hashes,
)
.await?;
call_new_payload(&auth_provider, version, params).await?;
let new_payload_result = NewPayloadResult { gas_used, latency: start.elapsed() };
info!(%new_payload_result);
@@ -130,7 +123,7 @@ impl Command {
}
// accumulate the results and calculate the overall Ggas/s
let gas_output = TotalGasOutput::new(gas_output_results);
let gas_output = TotalGasOutput::new(gas_output_results)?;
info!(
total_duration=?gas_output.total_duration,
total_gas_used=?gas_output.total_gas_used,

View File

@@ -1,6 +1,7 @@
//! Contains various benchmark output formats, either for logging or for
//! serialization to / from files.
use eyre::OptionExt;
use reth_primitives_traits::constants::GIGAGAS;
use serde::{ser::SerializeStruct, Serialize};
use std::time::Duration;
@@ -52,7 +53,7 @@ impl Serialize for NewPayloadResult {
{
// convert the time to microseconds
let time = self.latency.as_micros();
let mut state = serializer.serialize_struct("NewPayloadResult", 3)?;
let mut state = serializer.serialize_struct("NewPayloadResult", 2)?;
state.serialize_field("gas_used", &self.gas_used)?;
state.serialize_field("latency", &time)?;
state.end()
@@ -145,15 +146,14 @@ pub(crate) struct TotalGasOutput {
impl TotalGasOutput {
/// Create a new [`TotalGasOutput`] from a list of [`TotalGasRow`].
pub(crate) fn new(rows: Vec<TotalGasRow>) -> Self {
pub(crate) fn new(rows: Vec<TotalGasRow>) -> eyre::Result<Self> {
// the duration is obtained from the last row
let total_duration =
rows.last().map(|row| row.time).expect("the row has at least one element");
let total_duration = rows.last().map(|row| row.time).ok_or_eyre("empty results")?;
let blocks_processed = rows.len() as u64;
let total_gas_used: u64 = rows.into_iter().map(|row| row.gas_used).sum();
let total_gas_per_second = total_gas_used as f64 / total_duration.as_secs_f64();
Self { total_gas_used, total_duration, total_gas_per_second, blocks_processed }
Ok(Self { total_gas_used, total_duration, total_gas_per_second, blocks_processed })
}
/// Return the total gigagas per second.

View File

@@ -26,7 +26,9 @@ use reth_cli_runner::CliRunner;
fn main() {
// Enable backtraces unless a RUST_BACKTRACE value has already been explicitly provided.
if std::env::var_os("RUST_BACKTRACE").is_none() {
std::env::set_var("RUST_BACKTRACE", "1");
unsafe {
std::env::set_var("RUST_BACKTRACE", "1");
}
}
// Run until either exit or sigint or sigterm

View File

@@ -2,53 +2,20 @@
//! response. This is useful for benchmarking, as it allows us to wait for a payload to be valid
//! before sending additional calls.
use alloy_eips::eip7685::RequestsOrHash;
use alloy_primitives::B256;
use alloy_provider::{ext::EngineApi, Network, Provider};
use alloy_eips::eip7685::Requests;
use alloy_provider::{ext::EngineApi, network::AnyRpcBlock, Network, Provider};
use alloy_rpc_types_engine::{
ExecutionPayload, ExecutionPayloadInputV2, ExecutionPayloadSidecar, ExecutionPayloadV1,
ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus,
ExecutionPayload, ExecutionPayloadInputV2, ForkchoiceState, ForkchoiceUpdated,
PayloadAttributes, PayloadStatus,
};
use alloy_transport::TransportResult;
use op_alloy_rpc_types_engine::OpExecutionPayloadV4;
use reth_node_api::EngineApiMessageVersion;
use tracing::error;
/// An extension trait for providers that implement the engine API, to wait for a VALID response.
#[async_trait::async_trait]
pub trait EngineApiValidWaitExt<N>: Send + Sync {
/// Calls `engine_newPayloadV1` with the given [`ExecutionPayloadV1`], and waits until the
/// response is VALID.
async fn new_payload_v1_wait(
&self,
payload: ExecutionPayloadV1,
) -> TransportResult<PayloadStatus>;
/// Calls `engine_newPayloadV2` with the given [`ExecutionPayloadInputV2`], and waits until the
/// response is VALID.
async fn new_payload_v2_wait(
&self,
payload: ExecutionPayloadInputV2,
) -> TransportResult<PayloadStatus>;
/// Calls `engine_newPayloadV3` with the given [`ExecutionPayloadV3`], parent beacon block root,
/// and versioned hashes, and waits until the response is VALID.
async fn new_payload_v3_wait(
&self,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
) -> TransportResult<PayloadStatus>;
/// Calls `engine_newPayloadV4` with the given [`ExecutionPayloadV3`], parent beacon block root,
/// versioned hashes, and requests hash, and waits until the response is VALID.
async fn new_payload_v4_wait(
&self,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
requests_hash: B256,
) -> TransportResult<PayloadStatus>;
/// Calls `engine_forkChoiceUpdatedV1` with the given [`ForkchoiceState`] and optional
/// [`PayloadAttributes`], and waits until the response is VALID.
async fn fork_choice_updated_v1_wait(
@@ -80,122 +47,6 @@ where
N: Network,
P: Provider<N> + EngineApi<N>,
{
async fn new_payload_v1_wait(
&self,
payload: ExecutionPayloadV1,
) -> TransportResult<PayloadStatus> {
let mut status = self.new_payload_v1(payload.clone()).await?;
while !status.is_valid() {
if status.is_invalid() {
error!(?status, ?payload, "Invalid newPayloadV1",);
panic!("Invalid newPayloadV1: {status:?}");
}
status = self.new_payload_v1(payload.clone()).await?;
}
Ok(status)
}
async fn new_payload_v2_wait(
&self,
payload: ExecutionPayloadInputV2,
) -> TransportResult<PayloadStatus> {
let mut status = self.new_payload_v2(payload.clone()).await?;
while !status.is_valid() {
if status.is_invalid() {
error!(?status, ?payload, "Invalid newPayloadV2",);
panic!("Invalid newPayloadV2: {status:?}");
}
status = self.new_payload_v2(payload.clone()).await?;
}
Ok(status)
}
async fn new_payload_v3_wait(
&self,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
) -> TransportResult<PayloadStatus> {
let mut status = self
.new_payload_v3(payload.clone(), versioned_hashes.clone(), parent_beacon_block_root)
.await?;
while !status.is_valid() {
if status.is_invalid() {
error!(
?status,
?payload,
?versioned_hashes,
?parent_beacon_block_root,
"Invalid newPayloadV3",
);
panic!("Invalid newPayloadV3: {status:?}");
}
if status.is_syncing() {
return Err(alloy_json_rpc::RpcError::UnsupportedFeature(
"invalid range: no canonical state found for parent of requested block",
))
}
status = self
.new_payload_v3(payload.clone(), versioned_hashes.clone(), parent_beacon_block_root)
.await?;
}
Ok(status)
}
async fn new_payload_v4_wait(
&self,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
requests_hash: B256,
) -> TransportResult<PayloadStatus> {
// We cannot use `self.new_payload_v4` because it does not support sending
// `RequestsOrHash::Hash`
let mut status: PayloadStatus = self
.client()
.request(
"engine_newPayloadV4",
(
payload.clone(),
versioned_hashes.clone(),
parent_beacon_block_root,
RequestsOrHash::Hash(requests_hash),
),
)
.await?;
while !status.is_valid() {
if status.is_invalid() {
error!(
?status,
?payload,
?versioned_hashes,
?parent_beacon_block_root,
"Invalid newPayloadV4",
);
panic!("Invalid newPayloadV4: {status:?}");
}
if status.is_syncing() {
return Err(alloy_json_rpc::RpcError::UnsupportedFeature(
"invalid range: no canonical state found for parent of requested block",
))
}
status = self
.client()
.request(
"engine_newPayloadV4",
(
payload.clone(),
versioned_hashes.clone(),
parent_beacon_block_root,
RequestsOrHash::Hash(requests_hash),
),
)
.await?;
}
Ok(status)
}
async fn fork_choice_updated_v1_wait(
&self,
fork_choice_state: ForkchoiceState,
@@ -282,39 +133,60 @@ where
}
}
/// Calls the correct `engine_newPayload` method depending on the given [`ExecutionPayload`] and its
/// versioned variant. Returns the [`EngineApiMessageVersion`] depending on the payload's version.
///
/// # Panics
/// If the given payload is a V3 payload, but a parent beacon block root is provided as `None`.
pub(crate) async fn call_new_payload<N, P: EngineApiValidWaitExt<N>>(
provider: P,
payload: ExecutionPayload,
sidecar: ExecutionPayloadSidecar,
parent_beacon_block_root: Option<B256>,
versioned_hashes: Vec<B256>,
) -> TransportResult<EngineApiMessageVersion> {
match payload {
ExecutionPayload::V3(payload) => {
// We expect the caller to provide `parent_beacon_block_root` for V3 payloads.
let parent_beacon_block_root = parent_beacon_block_root
.expect("parent_beacon_block_root is required for V3 payloads and higher");
pub(crate) fn block_to_new_payload(
block: AnyRpcBlock,
is_optimism: bool,
) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value)> {
let block = block
.into_inner()
.map_header(|header| header.map(|h| h.into_header_with_defaults()))
.try_map_transactions(|tx| {
// try to convert unknowns into op type so that we can also support optimism
tx.try_into_either::<op_alloy_consensus::OpTxEnvelope>()
})?
.into_consensus();
if let Some(requests_hash) = sidecar.requests_hash() {
provider
.new_payload_v4_wait(
payload,
versioned_hashes,
parent_beacon_block_root,
requests_hash,
// Convert to execution payload
let (payload, sidecar) = ExecutionPayload::from_block_slow(&block);
let (version, params) = match payload {
ExecutionPayload::V3(payload) => {
let cancun = sidecar.cancun().unwrap();
if let Some(prague) = sidecar.prague() {
if is_optimism {
(
EngineApiMessageVersion::V4,
serde_json::to_value((
OpExecutionPayloadV4 {
payload_inner: payload,
withdrawals_root: block.withdrawals_root.unwrap(),
},
cancun.versioned_hashes.clone(),
cancun.parent_beacon_block_root,
Requests::default(),
))?,
)
.await?;
Ok(EngineApiMessageVersion::V4)
} else {
(
EngineApiMessageVersion::V4,
serde_json::to_value((
payload,
cancun.versioned_hashes.clone(),
cancun.parent_beacon_block_root,
prague.requests.requests_hash(),
))?,
)
}
} else {
provider
.new_payload_v3_wait(payload, versioned_hashes, parent_beacon_block_root)
.await?;
Ok(EngineApiMessageVersion::V3)
(
EngineApiMessageVersion::V3,
serde_json::to_value((
payload,
cancun.versioned_hashes.clone(),
cancun.parent_beacon_block_root,
))?,
)
}
}
ExecutionPayload::V2(payload) => {
@@ -323,16 +195,43 @@ pub(crate) async fn call_new_payload<N, P: EngineApiValidWaitExt<N>>(
withdrawals: Some(payload.withdrawals),
};
provider.new_payload_v2_wait(input).await?;
Ok(EngineApiMessageVersion::V2)
(EngineApiMessageVersion::V2, serde_json::to_value((input,))?)
}
ExecutionPayload::V1(payload) => {
provider.new_payload_v1_wait(payload).await?;
Ok(EngineApiMessageVersion::V1)
(EngineApiMessageVersion::V1, serde_json::to_value((payload,))?)
}
};
Ok((version, params))
}
/// Calls the correct `engine_newPayload` method depending on the given [`ExecutionPayload`] and its
/// versioned variant. Returns the [`EngineApiMessageVersion`] depending on the payload's version.
///
/// # Panics
/// If the given payload is a V3 payload, but a parent beacon block root is provided as `None`.
pub(crate) async fn call_new_payload<N: Network, P: Provider<N>>(
provider: P,
version: EngineApiMessageVersion,
params: serde_json::Value,
) -> TransportResult<()> {
let method = version.method_name();
let mut status: PayloadStatus = provider.client().request(method, &params).await?;
while !status.is_valid() {
if status.is_invalid() {
error!(?status, ?params, "Invalid {method}",);
panic!("Invalid {method}: {status:?}");
}
if status.is_syncing() {
return Err(alloy_json_rpc::RpcError::UnsupportedFeature(
"invalid range: no canonical state found for parent of requested block",
))
}
status = provider.client().request(method, &params).await?;
}
Ok(())
}
/// Calls the correct `engine_forkchoiceUpdated` method depending on the given

View File

@@ -64,7 +64,6 @@ eyre.workspace = true
[dev-dependencies]
backon.workspace = true
similar-asserts.workspace = true
tempfile.workspace = true
[features]
@@ -76,6 +75,7 @@ asm-keccak = [
"reth-node-core/asm-keccak",
"reth-primitives/asm-keccak",
"reth-ethereum-cli/asm-keccak",
"reth-node-ethereum/asm-keccak",
]
jemalloc = [

View File

@@ -2,7 +2,7 @@ use reth_ethereum_primitives::EthPrimitives;
use reth_evm::ConfigureEvm;
use reth_network::{protocol::IntoRlpxSubProtocol, NetworkProtocols};
use reth_network_api::FullNetwork;
use reth_node_api::BeaconConsensusEngineEvent;
use reth_node_api::ConsensusEngineEvent;
use reth_node_core::args::RessArgs;
use reth_provider::providers::{BlockchainProvider, ProviderNodeTypes};
use reth_ress_protocol::{NodeType, ProtocolState, RessProtocolHandler};
@@ -19,7 +19,7 @@ pub fn install_ress_subprotocol<P, E, N>(
evm_config: E,
network: N,
task_executor: TaskExecutor,
engine_events: EventStream<BeaconConsensusEngineEvent<EthPrimitives>>,
engine_events: EventStream<ConsensusEngineEvent<EthPrimitives>>,
) -> eyre::Result<()>
where
P: ProviderNodeTypes<Primitives = EthPrimitives>,

Binary file not shown.

View File

@@ -1,47 +0,0 @@
- [`reth`](/cli/reth)
- [`reth node`](/cli/reth/node)
- [`reth init`](/cli/reth/init)
- [`reth init-state`](/cli/reth/init-state)
- [`reth import`](/cli/reth/import)
- [`reth import-era`](/cli/reth/import-era)
- [`reth dump-genesis`](/cli/reth/dump-genesis)
- [`reth db`](/cli/reth/db)
- [`reth db stats`](/cli/reth/db/stats)
- [`reth db list`](/cli/reth/db/list)
- [`reth db checksum`](/cli/reth/db/checksum)
- [`reth db diff`](/cli/reth/db/diff)
- [`reth db get`](/cli/reth/db/get)
- [`reth db get mdbx`](/cli/reth/db/get/mdbx)
- [`reth db get static-file`](/cli/reth/db/get/static-file)
- [`reth db drop`](/cli/reth/db/drop)
- [`reth db clear`](/cli/reth/db/clear)
- [`reth db clear mdbx`](/cli/reth/db/clear/mdbx)
- [`reth db clear static-file`](/cli/reth/db/clear/static-file)
- [`reth db version`](/cli/reth/db/version)
- [`reth db path`](/cli/reth/db/path)
- [`reth download`](/cli/reth/download)
- [`reth stage`](/cli/reth/stage)
- [`reth stage run`](/cli/reth/stage/run)
- [`reth stage drop`](/cli/reth/stage/drop)
- [`reth stage dump`](/cli/reth/stage/dump)
- [`reth stage dump execution`](/cli/reth/stage/dump/execution)
- [`reth stage dump storage-hashing`](/cli/reth/stage/dump/storage-hashing)
- [`reth stage dump account-hashing`](/cli/reth/stage/dump/account-hashing)
- [`reth stage dump merkle`](/cli/reth/stage/dump/merkle)
- [`reth stage unwind`](/cli/reth/stage/unwind)
- [`reth stage unwind to-block`](/cli/reth/stage/unwind/to-block)
- [`reth stage unwind num-blocks`](/cli/reth/stage/unwind/num-blocks)
- [`reth p2p`](/cli/reth/p2p)
- [`reth p2p header`](/cli/reth/p2p/header)
- [`reth p2p body`](/cli/reth/p2p/body)
- [`reth p2p rlpx`](/cli/reth/p2p/rlpx)
- [`reth p2p rlpx ping`](/cli/reth/p2p/rlpx/ping)
- [`reth config`](/cli/reth/config)
- [`reth debug`](/cli/reth/debug)
- [`reth debug execution`](/cli/reth/debug/execution)
- [`reth debug merkle`](/cli/reth/debug/merkle)
- [`reth debug in-memory-merkle`](/cli/reth/debug/in-memory-merkle)
- [`reth debug build-block`](/cli/reth/debug/build-block)
- [`reth recover`](/cli/reth/recover)
- [`reth recover storage-tries`](/cli/reth/recover/storage-tries)
- [`reth prune`](/cli/reth/prune)

View File

@@ -1,328 +0,0 @@
# reth debug execution
Debug the roundtrip execution of blocks as well as the generated data
```bash
$ reth debug execution --help
```
```txt
Usage: reth debug execution [OPTIONS] --to <TO>
Options:
-h, --help
Print help (see a summary with '-h')
Datadir:
--datadir <DATA_DIR>
The path to the data dir for all reth files and subdirectories.
Defaults to the OS-specific data directory:
- Linux: `$XDG_DATA_HOME/reth/` or `$HOME/.local/share/reth/`
- Windows: `{FOLDERID_RoamingAppData}/reth/`
- macOS: `$HOME/Library/Application Support/reth/`
[default: default]
--datadir.static-files <PATH>
The absolute path to store static files in.
--config <FILE>
The path to the configuration file to use
--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]
Database:
--db.log-level <LOG_LEVEL>
Database logging level. Levels higher than "notice" require a debug build
Possible values:
- fatal: Enables logging for critical conditions, i.e. assertion failures
- error: Enables logging for error conditions
- warn: Enables logging for warning conditions
- notice: Enables logging for normal but significant condition
- verbose: Enables logging for verbose informational
- debug: Enables logging for debug-level messages
- trace: Enables logging for trace debug-level messages
- extra: Enables logging for extra debug-level messages
--db.exclusive <EXCLUSIVE>
Open environment in exclusive/monopolistic mode. Makes it possible to open a database on an NFS volume
[possible values: true, false]
--db.max-size <MAX_SIZE>
Maximum database size (e.g., 4TB, 8MB)
--db.growth-step <GROWTH_STEP>
Database growth step (e.g., 4GB, 4KB)
--db.read-transaction-timeout <READ_TRANSACTION_TIMEOUT>
Read transaction timeout in seconds, 0 means no timeout
Networking:
-d, --disable-discovery
Disable the discovery service
--disable-dns-discovery
Disable the DNS discovery
--disable-discv4-discovery
Disable Discv4 discovery
--enable-discv5-discovery
Enable Discv5 discovery
--disable-nat
Disable Nat discovery
--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4
[default: 0.0.0.0]
--discovery.port <DISCOVERY_PORT>
The UDP port to use for devp2p peer discovery version 4
[default: 30303]
--discovery.v5.addr <DISCOVERY_V5_ADDR>
The UDP IPv4 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` address, if it's also IPv4
--discovery.v5.addr.ipv6 <DISCOVERY_V5_ADDR_IPV6>
The UDP IPv6 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` address, if it's also IPv6
--discovery.v5.port <DISCOVERY_V5_PORT>
The UDP IPv4 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv4, or `--discovery.v5.addr` is set
[default: 9200]
--discovery.v5.port.ipv6 <DISCOVERY_V5_PORT_IPV6>
The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set
[default: 9200]
--discovery.v5.lookup-interval <DISCOVERY_V5_LOOKUP_INTERVAL>
The interval in seconds at which to carry out periodic lookup queries, for the whole run of the program
[default: 20]
--discovery.v5.bootstrap.lookup-interval <DISCOVERY_V5_BOOTSTRAP_LOOKUP_INTERVAL>
The interval in seconds at which to carry out boost lookup queries, for a fixed number of times, at bootstrap
[default: 5]
--discovery.v5.bootstrap.lookup-countdown <DISCOVERY_V5_BOOTSTRAP_LOOKUP_COUNTDOWN>
The number of times to carry out boost lookup queries at bootstrap
[default: 200]
--trusted-peers <TRUSTED_PEERS>
Comma separated enode URLs of trusted peers for P2P connections.
--trusted-peers enode://abcd@192.168.0.1:30303
--trusted-only
Connect to or accept from trusted peers only
--bootnodes <BOOTNODES>
Comma separated enode URLs for P2P discovery bootstrap.
Will fall back to a network-specific default if not specified.
--dns-retries <DNS_RETRIES>
Amount of DNS resolution requests retries to perform when peering
[default: 0]
--peers-file <FILE>
The path to the known peers file. Connected peers are dumped to this file on nodes
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
--identity <IDENTITY>
Custom node identity
[default: reth/<VERSION>-<SHA>/<ARCH>]
--p2p-secret-key <PATH>
Secret key to use for this node.
This will also deterministically set the peer ID. If not specified, it will be set in the data dir for the chain being used.
--no-persist-peers
Do not persist peers.
--nat <NAT>
NAT resolution method (any|none|upnp|publicip|extip:\<IP\>)
[default: any]
--addr <ADDR>
Network listening address
[default: 0.0.0.0]
--port <PORT>
Network listening port
[default: 30303]
--max-outbound-peers <MAX_OUTBOUND_PEERS>
Maximum number of outbound requests. default: 100
--max-inbound-peers <MAX_INBOUND_PEERS>
Maximum number of inbound requests. default: 30
--max-tx-reqs <COUNT>
Max concurrent `GetPooledTransactions` requests.
[default: 130]
--max-tx-reqs-peer <COUNT>
Max concurrent `GetPooledTransactions` requests per peer.
[default: 1]
--max-seen-tx-history <COUNT>
Max number of seen transactions to remember per peer.
Default is 320 transaction hashes.
[default: 320]
--max-pending-imports <COUNT>
Max number of transactions to import concurrently.
[default: 4096]
--pooled-tx-response-soft-limit <BYTES>
Experimental, for usage in research. Sets the max accumulated byte size of transactions
to pack in one response.
Spec'd at 2MiB.
[default: 2097152]
--pooled-tx-pack-soft-limit <BYTES>
Experimental, for usage in research. Sets the max accumulated byte size of transactions to
request in one request.
Since `RLPx` protocol version 68, the byte size of a transaction is shared as metadata in a
transaction announcement (see `RLPx` specs). This allows a node to request a specific size
response.
By default, nodes request only 128 KiB worth of transactions, but should a peer request
more, up to 2 MiB, a node will answer with more than 128 KiB.
Default is 128 KiB.
[default: 131072]
--max-tx-pending-fetch <COUNT>
Max capacity of cache of hashes for transactions pending fetch.
[default: 25600]
--net-if.experimental <IF_NAME>
Name of network interface used to communicate with peers.
If flag is set, but no value is passed, the default interface for docker `eth0` is tried.
--tx-propagation-policy <TX_PROPAGATION_POLICY>
Transaction Propagation Policy
The policy determines which peers transactions are gossiped to.
[default: All]
--to <TO>
The maximum block height
--interval <INTERVAL>
The block interval for sync and unwind. Defaults to `1000`
[default: 1000]
Logging:
--log.stdout.format <FORMAT>
The format to use for logs written to stdout
[default: terminal]
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
--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
[default: terminal]
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
--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.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
[default: always]
Possible values:
- always: Colors on
- auto: Colors on
- never: Colors off
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
```

View File

@@ -1,331 +0,0 @@
# reth debug merkle
Debug the clean & incremental state root calculations
```bash
$ reth debug merkle --help
```
```txt
Usage: reth debug merkle [OPTIONS] --to <TO>
Options:
-h, --help
Print help (see a summary with '-h')
Datadir:
--datadir <DATA_DIR>
The path to the data dir for all reth files and subdirectories.
Defaults to the OS-specific data directory:
- Linux: `$XDG_DATA_HOME/reth/` or `$HOME/.local/share/reth/`
- Windows: `{FOLDERID_RoamingAppData}/reth/`
- macOS: `$HOME/Library/Application Support/reth/`
[default: default]
--datadir.static-files <PATH>
The absolute path to store static files in.
--config <FILE>
The path to the configuration file to use
--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]
Database:
--db.log-level <LOG_LEVEL>
Database logging level. Levels higher than "notice" require a debug build
Possible values:
- fatal: Enables logging for critical conditions, i.e. assertion failures
- error: Enables logging for error conditions
- warn: Enables logging for warning conditions
- notice: Enables logging for normal but significant condition
- verbose: Enables logging for verbose informational
- debug: Enables logging for debug-level messages
- trace: Enables logging for trace debug-level messages
- extra: Enables logging for extra debug-level messages
--db.exclusive <EXCLUSIVE>
Open environment in exclusive/monopolistic mode. Makes it possible to open a database on an NFS volume
[possible values: true, false]
--db.max-size <MAX_SIZE>
Maximum database size (e.g., 4TB, 8MB)
--db.growth-step <GROWTH_STEP>
Database growth step (e.g., 4GB, 4KB)
--db.read-transaction-timeout <READ_TRANSACTION_TIMEOUT>
Read transaction timeout in seconds, 0 means no timeout
Networking:
-d, --disable-discovery
Disable the discovery service
--disable-dns-discovery
Disable the DNS discovery
--disable-discv4-discovery
Disable Discv4 discovery
--enable-discv5-discovery
Enable Discv5 discovery
--disable-nat
Disable Nat discovery
--discovery.addr <DISCOVERY_ADDR>
The UDP address to use for devp2p peer discovery version 4
[default: 0.0.0.0]
--discovery.port <DISCOVERY_PORT>
The UDP port to use for devp2p peer discovery version 4
[default: 30303]
--discovery.v5.addr <DISCOVERY_V5_ADDR>
The UDP IPv4 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` address, if it's also IPv4
--discovery.v5.addr.ipv6 <DISCOVERY_V5_ADDR_IPV6>
The UDP IPv6 address to use for devp2p peer discovery version 5. Overwritten by `RLPx` address, if it's also IPv6
--discovery.v5.port <DISCOVERY_V5_PORT>
The UDP IPv4 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv4, or `--discovery.v5.addr` is set
[default: 9200]
--discovery.v5.port.ipv6 <DISCOVERY_V5_PORT_IPV6>
The UDP IPv6 port to use for devp2p peer discovery version 5. Not used unless `--addr` is IPv6, or `--discovery.addr.ipv6` is set
[default: 9200]
--discovery.v5.lookup-interval <DISCOVERY_V5_LOOKUP_INTERVAL>
The interval in seconds at which to carry out periodic lookup queries, for the whole run of the program
[default: 20]
--discovery.v5.bootstrap.lookup-interval <DISCOVERY_V5_BOOTSTRAP_LOOKUP_INTERVAL>
The interval in seconds at which to carry out boost lookup queries, for a fixed number of times, at bootstrap
[default: 5]
--discovery.v5.bootstrap.lookup-countdown <DISCOVERY_V5_BOOTSTRAP_LOOKUP_COUNTDOWN>
The number of times to carry out boost lookup queries at bootstrap
[default: 200]
--trusted-peers <TRUSTED_PEERS>
Comma separated enode URLs of trusted peers for P2P connections.
--trusted-peers enode://abcd@192.168.0.1:30303
--trusted-only
Connect to or accept from trusted peers only
--bootnodes <BOOTNODES>
Comma separated enode URLs for P2P discovery bootstrap.
Will fall back to a network-specific default if not specified.
--dns-retries <DNS_RETRIES>
Amount of DNS resolution requests retries to perform when peering
[default: 0]
--peers-file <FILE>
The path to the known peers file. Connected peers are dumped to this file on nodes
shutdown, and read on startup. Cannot be used with `--no-persist-peers`.
--identity <IDENTITY>
Custom node identity
[default: reth/<VERSION>-<SHA>/<ARCH>]
--p2p-secret-key <PATH>
Secret key to use for this node.
This will also deterministically set the peer ID. If not specified, it will be set in the data dir for the chain being used.
--no-persist-peers
Do not persist peers.
--nat <NAT>
NAT resolution method (any|none|upnp|publicip|extip:\<IP\>)
[default: any]
--addr <ADDR>
Network listening address
[default: 0.0.0.0]
--port <PORT>
Network listening port
[default: 30303]
--max-outbound-peers <MAX_OUTBOUND_PEERS>
Maximum number of outbound requests. default: 100
--max-inbound-peers <MAX_INBOUND_PEERS>
Maximum number of inbound requests. default: 30
--max-tx-reqs <COUNT>
Max concurrent `GetPooledTransactions` requests.
[default: 130]
--max-tx-reqs-peer <COUNT>
Max concurrent `GetPooledTransactions` requests per peer.
[default: 1]
--max-seen-tx-history <COUNT>
Max number of seen transactions to remember per peer.
Default is 320 transaction hashes.
[default: 320]
--max-pending-imports <COUNT>
Max number of transactions to import concurrently.
[default: 4096]
--pooled-tx-response-soft-limit <BYTES>
Experimental, for usage in research. Sets the max accumulated byte size of transactions
to pack in one response.
Spec'd at 2MiB.
[default: 2097152]
--pooled-tx-pack-soft-limit <BYTES>
Experimental, for usage in research. Sets the max accumulated byte size of transactions to
request in one request.
Since `RLPx` protocol version 68, the byte size of a transaction is shared as metadata in a
transaction announcement (see `RLPx` specs). This allows a node to request a specific size
response.
By default, nodes request only 128 KiB worth of transactions, but should a peer request
more, up to 2 MiB, a node will answer with more than 128 KiB.
Default is 128 KiB.
[default: 131072]
--max-tx-pending-fetch <COUNT>
Max capacity of cache of hashes for transactions pending fetch.
[default: 25600]
--net-if.experimental <IF_NAME>
Name of network interface used to communicate with peers.
If flag is set, but no value is passed, the default interface for docker `eth0` is tried.
--tx-propagation-policy <TX_PROPAGATION_POLICY>
Transaction Propagation Policy
The policy determines which peers transactions are gossiped to.
[default: All]
--retries <RETRIES>
The number of retries per request
[default: 5]
--to <TO>
The height to finish at
--skip-node-depth <SKIP_NODE_DEPTH>
The depth after which we should start comparing branch nodes
Logging:
--log.stdout.format <FORMAT>
The format to use for logs written to stdout
[default: terminal]
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
--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
[default: terminal]
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
--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.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
[default: always]
Possible values:
- always: Colors on
- auto: Colors on
- never: Colors off
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
```

View File

@@ -1,95 +0,0 @@
# reth p2p body
Download block body
```bash
$ reth p2p body --help
```
```txt
Usage: reth p2p body [OPTIONS] <ID>
Arguments:
<ID>
The block number or hash
Options:
-h, --help
Print help (see a summary with '-h')
Logging:
--log.stdout.format <FORMAT>
The format to use for logs written to stdout
[default: terminal]
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
--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
[default: terminal]
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
--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.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
[default: always]
Possible values:
- always: Colors on
- auto: Colors on
- never: Colors off
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
```

View File

@@ -1,12 +0,0 @@
# Using Standalone Components
This guide demonstrates how to use Reth components independently without running a full node. This is useful for building tools, analyzers, indexers, or any application that needs direct access to blockchain data.
## Direct Database Access
## Next Steps
- Learn about [Modifying Nodes](/sdk/examples/modify-node) to add functionality
- Explore the [Type System](/sdk/typesystem/block) for working with data
- Check [Custom Node Building](/sdk/custom-node/prerequisites) for production use

View File

@@ -1,127 +0,0 @@
# Reth for Developers
Reth can be used as a library to build custom Ethereum nodes, interact with blockchain data, or create specialized tools for blockchain analysis and indexing.
## What is the Reth SDK?
The Reth SDK allows developers to:
- Use components of the Reth node as libraries
- Build custom Ethereum execution nodes with modified behavior (e.g. payload building)
- Access blockchain data directly from the database
- Create high-performance indexing solutions
- Extend a new with new RPC endpoints and functionality
- Implement custom consensus mechanisms
- Build specialized tools for blockchain analysis
## Quick Start
Add Reth to your project:
## Ethereum
```toml
[dependencies]
# Ethereum meta crate
reth-ethereum = { git = "https://github.com/paradigmxyz/reth" }
```
## Opstack
```toml
[dependencies]
reth-op = { git = "https://github.com/paradigmxyz/reth" }
```
## Key Concepts
### Node Architecture
Reth is built with modularity in mind. The main components include:
- **Primitives**: Core data type abstractions like `Block`
- **Node Builder**: Constructs and configures node instances
- **Database**: Efficient storage using MDBX and static files
- **Network**: P2P communication and block synchronization
- **Consensus**: Block validation and chain management
- **EVM**: Transaction execution and state transitions
- **RPC**: JSON-RPC server for external communication
- **Transaction Pool**: Pending transaction management
### Dependency Management
Reth is primarily built on top of the [alloy](https://github.com/alloy-rs/alloy) ecosystem, which provides the necessary abstractions and implementations for core ethereum blockchain data types, transaction handling, and EVM execution.
### Type System
Reth uses its own type system to handle different representations of blockchain data:
- **Primitives**: Core types like `B256`, `Address`, `U256`
- **Transactions**: Multiple representations for different contexts (pooled, consensus, RPC)
- **Blocks**: Headers, bodies, and sealed blocks with proven properties
- **State**: Accounts, storage, and state transitions
### Building Custom Nodes
The node builder pattern allows you to customize every aspect of node behavior:
```rust
use reth_ethereum::node::{EthereumNode, NodeBuilder};
// Build a custom node with modified components
let node = NodeBuilder::new(config)
// install the ethereum specific node primitives
.with_types::<EthereumNode>()
.with_components(|components| {
// Customize components here
components
})
.build()
.await?;
```
## Architecture Overview
```mermaid
graph TD
A[Node Builder] --> B[Database]
A --> C[Network]
A --> D[Consensus]
A --> E[EVM]
A --> F[RPC Server]
A --> G[Transaction Pool]
B --> H[DB Storage]
B --> I[Static Files]
C --> J[Discovery]
C --> K[ETH Protocol]
E --> L[State Provider]
E --> M[Block Executor]
```
## Nodes Built with Reth
Several production networks have been built using Reth's node builder pattern:
### [BSC Reth](https://github.com/loocapro/reth-bsc)
A Binance Smart Chain execution client, implementing BSC-specific consensus rules and features.
### [Bera Reth](https://github.com/berachain/bera-reth)
Berachain's execution client.
### [Gnosis Reth](https://github.com/gnosischain/reth_gnosis)
Gnosis Chain's implementation using Reth.
## Next Steps
- **[Node Components](/sdk/node-components)**: Deep dive into each component
- **[Type System](/sdk/typesystem/block)**: Understanding Reth's type system
- **[Custom Nodes](/sdk/custom-node/prerequisites)**: Building production nodes
- **[Examples](/sdk/examples/modify-node)**: Real-world implementations
## Resources
- [API Documentation](https://docs.rs/reth/latest/reth/)
- [GitHub Repository](https://github.com/paradigmxyz/reth)

View File

@@ -1,17 +0,0 @@
{
"timestamp": "2025-06-23T11:20:27.303Z",
"totalFiles": 106,
"totalLinks": 150,
"brokenLinks": [
{
"file": "docs/pages/index.mdx",
"link": "/introduction/benchmarks",
"line": 110,
"reason": "Absolute path not found: /introduction/benchmarks"
}
],
"summary": {
"brokenCount": 1,
"validCount": 149
}
}

View File

@@ -1,22 +0,0 @@
{
"name": "vocs",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vocs dev",
"build": "vocs build && bun generate-redirects.ts",
"preview": "vocs preview",
"check-links": "bun check-links.ts",
"generate-redirects": "bun generate-redirects.ts"
},
"dependencies": {
"react": "latest",
"react-dom": "latest",
"vocs": "latest"
},
"devDependencies": {
"@types/react": "latest",
"typescript": "latest"
}
}

View File

@@ -1,4 +1,3 @@
msrv = "1.86"
too-large-for-stack = 128
doc-valid-idents = [
"P2P",

View File

@@ -1,60 +0,0 @@
# Alloy Provider for Reth
This crate provides an implementation of reth's `StateProviderFactory` and related traits that fetches state data via RPC instead of from a local database.
Originally created by [cakevm](https://github.com/cakevm/alloy-reth-provider).
## Features
- Implements `StateProviderFactory` for remote RPC state access
- Supports Ethereum networks
- Useful for testing without requiring a full database
- Can be used with reth ExEx (Execution Extensions) for testing
## Usage
```rust
use alloy_provider::ProviderBuilder;
use reth_alloy_provider::AlloyRethProvider;
use reth_ethereum_node::EthereumNode;
// Initialize provider
let provider = ProviderBuilder::new()
.builtin("https://eth.merkle.io")
.await
.unwrap();
// Create database provider with NodeTypes
let db_provider = AlloyRethProvider::new(provider, EthereumNode);
// Get state at specific block
let state = db_provider.state_by_block_id(BlockId::number(16148323)).unwrap();
```
## Configuration
The provider can be configured with custom settings:
```rust
use reth_alloy_provider::{AlloyRethProvider, AlloyRethProviderConfig};
use reth_ethereum_node::EthereumNode;
let config = AlloyRethProviderConfig {
compute_state_root: true, // Enable state root computation
};
let db_provider = AlloyRethProvider::new_with_config(provider, EthereumNode, config);
```
## Technical Details
The provider uses `alloy_network::AnyNetwork` for network operations, providing compatibility with various Ethereum-based networks while maintaining the expected block structure with headers.
## License
Licensed under either of:
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

View File

@@ -53,8 +53,8 @@ reth-primitives-traits = { workspace = true, features = ["test-utils"] }
reth-testing-utils.workspace = true
alloy-signer.workspace = true
alloy-signer-local.workspace = true
alloy-consensus.workspace = true
rand.workspace = true
criterion.workspace = true
[features]
serde = [
@@ -83,3 +83,8 @@ test-utils = [
"reth-trie/test-utils",
"reth-ethereum-primitives/test-utils",
]
[[bench]]
name = "canonical_hashes_range"
harness = false
required-features = ["test-utils"]

View File

@@ -0,0 +1,99 @@
#![allow(missing_docs)]
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use reth_chain_state::{
test_utils::TestBlockBuilder, ExecutedBlockWithTrieUpdates, MemoryOverlayStateProviderRef,
};
use reth_ethereum_primitives::EthPrimitives;
use reth_storage_api::{noop::NoopProvider, BlockHashReader};
criterion_group!(benches, bench_canonical_hashes_range);
criterion_main!(benches);
fn bench_canonical_hashes_range(c: &mut Criterion) {
let mut group = c.benchmark_group("canonical_hashes_range");
let scenarios = [("small", 10), ("medium", 100), ("large", 1000)];
for (name, num_blocks) in scenarios {
group.bench_function(format!("{}_blocks_{}", name, num_blocks), |b| {
let (provider, blocks) = setup_provider_with_blocks(num_blocks);
let start_block = blocks[0].recovered_block().number;
let end_block = blocks[num_blocks / 2].recovered_block().number;
b.iter(|| {
black_box(
provider
.canonical_hashes_range(black_box(start_block), black_box(end_block))
.unwrap(),
)
})
});
}
let (provider, blocks) = setup_provider_with_blocks(500);
let base_block = blocks[100].recovered_block().number;
let range_sizes = [1, 10, 50, 100, 250];
for range_size in range_sizes {
group.bench_function(format!("range_size_{}", range_size), |b| {
let end_block = base_block + range_size;
b.iter(|| {
black_box(
provider
.canonical_hashes_range(black_box(base_block), black_box(end_block))
.unwrap(),
)
})
});
}
// Benchmark edge cases
group.bench_function("no_in_memory_matches", |b| {
let (provider, blocks) = setup_provider_with_blocks(100);
let first_block = blocks[0].recovered_block().number;
let start_block = first_block - 50;
let end_block = first_block - 10;
b.iter(|| {
black_box(
provider
.canonical_hashes_range(black_box(start_block), black_box(end_block))
.unwrap(),
)
})
});
group.bench_function("all_in_memory_matches", |b| {
let (provider, blocks) = setup_provider_with_blocks(100);
let first_block = blocks[0].recovered_block().number;
let last_block = blocks[blocks.len() - 1].recovered_block().number;
b.iter(|| {
black_box(
provider
.canonical_hashes_range(black_box(first_block), black_box(last_block + 1))
.unwrap(),
)
})
});
group.finish();
}
fn setup_provider_with_blocks(
num_blocks: usize,
) -> (
MemoryOverlayStateProviderRef<'static, EthPrimitives>,
Vec<ExecutedBlockWithTrieUpdates<EthPrimitives>>,
) {
let mut builder = TestBlockBuilder::<EthPrimitives>::default();
let blocks: Vec<_> = builder.get_executed_blocks(1000..1000 + num_blocks as u64).collect();
let historical = Box::new(NoopProvider::default());
let provider = MemoryOverlayStateProviderRef::new(historical, blocks.clone());
(provider, blocks)
}

View File

@@ -5,15 +5,16 @@ use crate::{
ChainInfoTracker, MemoryOverlayStateProvider,
};
use alloy_consensus::{transaction::TransactionMeta, BlockHeader};
use alloy_eips::{eip2718::Encodable2718, BlockHashOrNumber, BlockNumHash};
use alloy_primitives::{map::HashMap, TxHash, B256};
use alloy_eips::{BlockHashOrNumber, BlockNumHash};
use alloy_primitives::{map::HashMap, BlockNumber, TxHash, B256};
use parking_lot::RwLock;
use reth_chainspec::ChainInfo;
use reth_ethereum_primitives::EthPrimitives;
use reth_execution_types::{Chain, ExecutionOutcome};
use reth_metrics::{metrics::Gauge, Metrics};
use reth_primitives_traits::{
BlockBody as _, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader, SignedTransaction,
BlockBody as _, IndexedTx, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader,
SignedTransaction,
};
use reth_storage_api::StateProviderBox;
use reth_trie::{updates::TrieUpdates, HashedPostState};
@@ -42,8 +43,9 @@ pub(crate) struct InMemoryStateMetrics {
///
/// # Locking behavior on state updates
///
/// All update calls must be atomic, meaning that they must acquire all locks at once, before
/// modifying the state. This is to ensure that the internal state is always consistent.
/// All update calls must acquire all locks at once before modifying state to ensure the internal
/// state remains consistent. This prevents readers from observing partially updated state where
/// the numbers and blocks maps are out of sync.
/// Update functions ensure that the numbers write lock is always acquired first, because lookup by
/// numbers first read the numbers map and then the blocks map.
/// By acquiring the numbers lock first, we ensure that read-only lookups don't deadlock updates.
@@ -159,7 +161,7 @@ impl<N: NodePrimitives> CanonicalInMemoryStateInner<N> {
}
type PendingBlockAndReceipts<N> =
(SealedBlock<<N as NodePrimitives>::Block>, Vec<reth_primitives_traits::ReceiptTy<N>>);
(RecoveredBlock<<N as NodePrimitives>::Block>, Vec<reth_primitives_traits::ReceiptTy<N>>);
/// This type is responsible for providing the blocks, receipts, and state for
/// all canonical blocks not on disk yet and keeps track of the block range that
@@ -480,7 +482,7 @@ impl<N: NodePrimitives> CanonicalInMemoryState<N> {
pub fn pending_block_and_receipts(&self) -> Option<PendingBlockAndReceipts<N>> {
self.pending_state().map(|block_state| {
(
block_state.block_ref().recovered_block().sealed_block().clone(),
block_state.block_ref().recovered_block().clone(),
block_state.executed_block_receipts(),
)
})
@@ -553,24 +555,8 @@ impl<N: NodePrimitives> CanonicalInMemoryState<N> {
tx_hash: TxHash,
) -> Option<(N::SignedTx, TransactionMeta)> {
for block_state in self.canonical_chain() {
if let Some((index, tx)) = block_state
.block_ref()
.recovered_block()
.body()
.transactions_iter()
.enumerate()
.find(|(_, tx)| tx.trie_hash() == tx_hash)
{
let meta = TransactionMeta {
tx_hash,
index: index as u64,
block_hash: block_state.hash(),
block_number: block_state.block_ref().recovered_block().number(),
base_fee: block_state.block_ref().recovered_block().base_fee_per_gas(),
timestamp: block_state.block_ref().recovered_block().timestamp(),
excess_blob_gas: block_state.block_ref().recovered_block().excess_blob_gas(),
};
return Some((tx.clone(), meta))
if let Some(indexed) = block_state.find_indexed(tx_hash) {
return Some((indexed.tx().clone(), indexed.meta()));
}
}
None
@@ -603,11 +589,11 @@ impl<N: NodePrimitives> BlockState<N> {
/// Returns the hash and block of the on disk block this state can be traced back to.
pub fn anchor(&self) -> BlockNumHash {
if let Some(parent) = &self.parent {
parent.anchor()
} else {
self.block.recovered_block().parent_num_hash()
let mut current = self;
while let Some(parent) = &current.parent {
current = parent;
}
current.block.recovered_block().parent_num_hash()
}
/// Returns the executed block that determines the state.
@@ -725,30 +711,14 @@ impl<N: NodePrimitives> BlockState<N> {
tx_hash: TxHash,
) -> Option<(N::SignedTx, TransactionMeta)> {
self.chain().find_map(|block_state| {
block_state
.block_ref()
.recovered_block()
.body()
.transactions_iter()
.enumerate()
.find(|(_, tx)| tx.trie_hash() == tx_hash)
.map(|(index, tx)| {
let meta = TransactionMeta {
tx_hash,
index: index as u64,
block_hash: block_state.hash(),
block_number: block_state.block_ref().recovered_block().number(),
base_fee: block_state.block_ref().recovered_block().base_fee_per_gas(),
timestamp: block_state.block_ref().recovered_block().timestamp(),
excess_blob_gas: block_state
.block_ref()
.recovered_block()
.excess_blob_gas(),
};
(tx.clone(), meta)
})
block_state.find_indexed(tx_hash).map(|indexed| (indexed.tx().clone(), indexed.meta()))
})
}
/// Finds a transaction by hash and returns it with its index and block context.
pub fn find_indexed(&self, tx_hash: TxHash) -> Option<IndexedTx<'_, N::Block>> {
self.block_ref().recovered_block().find_indexed(tx_hash)
}
}
/// Represents an executed block stored in-memory.
@@ -796,6 +766,12 @@ impl<N: NodePrimitives> ExecutedBlock<N> {
pub fn hashed_state(&self) -> &HashedPostState {
&self.hashed_state
}
/// Returns a [`BlockNumber`] of the block.
#[inline]
pub fn block_number(&self) -> BlockNumber {
self.recovered_block.header().number()
}
}
/// Trie updates that result from calculating the state root for the block.
@@ -925,14 +901,14 @@ pub enum NewCanonicalChain<N: NodePrimitives = EthPrimitives> {
impl<N: NodePrimitives<SignedTx: SignedTransaction>> NewCanonicalChain<N> {
/// Returns the length of the new chain.
pub fn new_block_count(&self) -> usize {
pub const fn new_block_count(&self) -> usize {
match self {
Self::Commit { new } | Self::Reorg { new, .. } => new.len(),
}
}
/// Returns the length of the reorged chain.
pub fn reorged_block_count(&self) -> usize {
pub const fn reorged_block_count(&self) -> usize {
match self {
Self::Commit { .. } => 0,
Self::Reorg { old, .. } => old.len(),
@@ -1347,7 +1323,7 @@ mod tests {
// Check the pending block and receipts
assert_eq!(
state.pending_block_and_receipts().unwrap(),
(block2.recovered_block().sealed_block().clone(), vec![])
(block2.recovered_block().clone(), vec![])
);
}

View File

@@ -21,7 +21,7 @@ pub struct MemoryOverlayStateProviderRef<
'a,
N: NodePrimitives = reth_ethereum_primitives::EthPrimitives,
> {
/// Historical state provider for state lookups that are not found in in-memory blocks.
/// Historical state provider for state lookups that are not found in memory blocks.
pub(crate) historical: Box<dyn StateProvider + 'a>,
/// The collection of executed parent blocks. Expected order is newest to oldest.
pub(crate) in_memory: Vec<ExecutedBlockWithTrieUpdates<N>>,
@@ -84,14 +84,22 @@ impl<N: NodePrimitives> BlockHashReader for MemoryOverlayStateProviderRef<'_, N>
) -> ProviderResult<Vec<B256>> {
let range = start..end;
let mut earliest_block_number = None;
let mut in_memory_hashes = Vec::new();
let mut in_memory_hashes = Vec::with_capacity(range.size_hint().0);
// iterate in ascending order (oldest to newest = low to high)
for block in &self.in_memory {
if range.contains(&block.recovered_block().number()) {
in_memory_hashes.insert(0, block.recovered_block().hash());
earliest_block_number = Some(block.recovered_block().number());
let block_num = block.recovered_block().number();
if range.contains(&block_num) {
in_memory_hashes.push(block.recovered_block().hash());
earliest_block_number = Some(block_num);
}
}
// `self.in_memory` stores executed blocks in ascending order (oldest to newest).
// However, `in_memory_hashes` should be constructed in descending order (newest to oldest),
// so we reverse the vector after collecting the hashes.
in_memory_hashes.reverse();
let mut hashes =
self.historical.canonical_hashes_range(start, earliest_block_number.unwrap_or(end))?;
hashes.append(&mut in_memory_hashes);

View File

@@ -122,16 +122,36 @@ impl<N: NodePrimitives> CanonStateNotification<N> {
}
}
/// Get the new tip of the chain.
/// Gets the new tip of the chain.
///
/// Returns the new tip for [`Self::Reorg`] and [`Self::Commit`] variants which commit at least
/// 1 new block.
///
/// # Panics
///
/// If chain doesn't have any blocks.
pub fn tip(&self) -> &RecoveredBlock<N::Block> {
match self {
Self::Commit { new } | Self::Reorg { new, .. } => new.tip(),
}
}
/// Gets the new tip of the chain.
///
/// If the chain has no blocks, it returns `None`. Otherwise, it returns the new tip for
/// [`Self::Reorg`] and [`Self::Commit`] variants.
pub fn tip_checked(&self) -> Option<&RecoveredBlock<N::Block>> {
match self {
Self::Commit { new } | Self::Reorg { new, .. } => {
if new.is_empty() {
None
} else {
Some(new.tip())
}
}
}
}
/// Get receipts in the reverted and newly imported chain segments with their corresponding
/// block numbers and transaction hashes.
///

View File

@@ -2,9 +2,7 @@ use crate::{
in_memory::ExecutedBlockWithTrieUpdates, CanonStateNotification, CanonStateNotifications,
CanonStateSubscriptions, ExecutedTrieUpdates,
};
use alloy_consensus::{
Header, SignableTransaction, Transaction as _, TxEip1559, TxReceipt, EMPTY_ROOT_HASH,
};
use alloy_consensus::{Header, SignableTransaction, TxEip1559, TxReceipt, EMPTY_ROOT_HASH};
use alloy_eips::{
eip1559::{ETHEREUM_BLOCK_GAS_LIMIT_30M, INITIAL_BASE_FEE},
eip7685::Requests,
@@ -266,6 +264,16 @@ impl<N: NodePrimitives> TestBlockBuilder<N> {
&mut self,
block: RecoveredBlock<reth_ethereum_primitives::Block>,
) -> ExecutionOutcome {
let num_txs = block.body().transactions.len() as u64;
let single_cost = Self::single_tx_cost();
let mut final_balance = self.signer_execute_account_info.balance;
for _ in 0..num_txs {
final_balance -= single_cost;
}
let final_nonce = self.signer_execute_account_info.nonce + num_txs;
let receipts = block
.body()
.transactions
@@ -279,26 +287,18 @@ impl<N: NodePrimitives> TestBlockBuilder<N> {
})
.collect::<Vec<_>>();
let mut bundle_state_builder = BundleState::builder(block.number..=block.number);
for tx in &block.body().transactions {
self.signer_execute_account_info.balance -= Self::single_tx_cost();
bundle_state_builder = bundle_state_builder.state_present_account_info(
let bundle_state = BundleState::builder(block.number..=block.number)
.state_present_account_info(
self.signer,
AccountInfo {
nonce: tx.nonce(),
balance: self.signer_execute_account_info.balance,
..Default::default()
},
);
}
AccountInfo { nonce: final_nonce, balance: final_balance, ..Default::default() },
)
.build();
let execution_outcome = ExecutionOutcome::new(
bundle_state_builder.build(),
vec![vec![]],
block.number,
Vec::new(),
);
self.signer_execute_account_info.balance = final_balance;
self.signer_execute_account_info.nonce = final_nonce;
let execution_outcome =
ExecutionOutcome::new(bundle_state, vec![vec![]], block.number, Vec::new());
execution_outcome.with_receipts(vec![receipts])
}

View File

@@ -35,7 +35,6 @@ derive_more.workspace = true
alloy-trie = { workspace = true, features = ["arbitrary"] }
alloy-eips = { workspace = true, features = ["arbitrary"] }
alloy-rlp = { workspace = true, features = ["arrayvec"] }
alloy-genesis.workspace = true
[features]
default = ["std"]

View File

@@ -2,18 +2,19 @@ use crate::{ChainSpec, DepositContract};
use alloc::{boxed::Box, vec::Vec};
use alloy_chains::Chain;
use alloy_consensus::Header;
use alloy_eips::{eip1559::BaseFeeParams, eip7840::BlobParams};
use alloy_eips::{calc_next_block_base_fee, eip1559::BaseFeeParams, eip7840::BlobParams};
use alloy_genesis::Genesis;
use alloy_primitives::{B256, U256};
use core::fmt::{Debug, Display};
use reth_ethereum_forks::EthereumHardforks;
use reth_network_peers::NodeRecord;
use reth_primitives_traits::{AlloyBlockHeader, BlockHeader};
/// Trait representing type configuring a chain spec.
#[auto_impl::auto_impl(&, Arc)]
pub trait EthChainSpec: Send + Sync + Unpin + Debug {
/// The header type of the network.
type Header;
type Header: BlockHeader;
/// Returns the [`Chain`] object this spec targets.
fn chain(&self) -> Chain;
@@ -23,9 +24,6 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug {
self.chain().id()
}
/// Get the [`BaseFeeParams`] for the chain at the given block.
fn base_fee_params_at_block(&self, block_number: u64) -> BaseFeeParams;
/// Get the [`BaseFeeParams`] for the chain at the given timestamp.
fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams;
@@ -65,6 +63,16 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug {
/// Returns the final total difficulty if the Paris hardfork is known.
fn final_paris_total_difficulty(&self) -> Option<U256>;
/// See [`calc_next_block_base_fee`].
fn next_block_base_fee(&self, parent: &Self::Header, target_timestamp: u64) -> Option<u64> {
Some(calc_next_block_base_fee(
parent.gas_used(),
parent.gas_limit(),
parent.base_fee_per_gas()?,
self.base_fee_params_at_timestamp(target_timestamp),
))
}
}
impl EthChainSpec for ChainSpec {
@@ -74,10 +82,6 @@ impl EthChainSpec for ChainSpec {
self.chain
}
fn base_fee_params_at_block(&self, block_number: u64) -> BaseFeeParams {
self.base_fee_params_at_block(block_number)
}
fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams {
self.base_fee_params_at_timestamp(timestamp)
}

View File

@@ -145,4 +145,34 @@ mod tests {
let chain: Chain = NamedChain::Holesky.into();
assert_eq!(s, chain.public_dns_network_protocol().unwrap().as_str());
}
#[test]
fn test_centralized_base_fee_calculation() {
use crate::{ChainSpec, EthChainSpec};
use alloy_consensus::Header;
use alloy_eips::eip1559::INITIAL_BASE_FEE;
fn parent_header() -> Header {
Header {
gas_used: 15_000_000,
gas_limit: 30_000_000,
base_fee_per_gas: Some(INITIAL_BASE_FEE),
timestamp: 1_000,
..Default::default()
}
}
let spec = ChainSpec::default();
let parent = parent_header();
// For testing, assume next block has timestamp 12 seconds later
let next_timestamp = parent.timestamp + 12;
let expected = parent
.next_block_base_fee(spec.base_fee_params_at_timestamp(next_timestamp))
.unwrap_or_default();
let got = spec.next_block_base_fee(&parent, next_timestamp).unwrap_or_default();
assert_eq!(expected, got, "Base fee calculation does not match expected value");
}
}

View File

@@ -3,19 +3,20 @@ use alloy_evm::eth::spec::EthExecutorSpec;
use crate::{
constants::{MAINNET_DEPOSIT_CONTRACT, MAINNET_PRUNE_DELETE_LIMIT},
EthChainSpec,
holesky, hoodi, mainnet, sepolia, EthChainSpec,
};
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloy_chains::{Chain, NamedChain};
use alloy_consensus::{
constants::{
DEV_GENESIS_HASH, EMPTY_WITHDRAWALS, HOLESKY_GENESIS_HASH, HOODI_GENESIS_HASH,
MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH,
EMPTY_WITHDRAWALS, HOLESKY_GENESIS_HASH, HOODI_GENESIS_HASH, MAINNET_GENESIS_HASH,
SEPOLIA_GENESIS_HASH,
},
Header,
};
use alloy_eips::{
eip1559::INITIAL_BASE_FEE, eip7685::EMPTY_REQUESTS_HASH, eip7892::BlobScheduleBlobParams,
eip1559::INITIAL_BASE_FEE, eip7685::EMPTY_REQUESTS_HASH, eip7840::BlobParams,
eip7892::BlobScheduleBlobParams,
};
use alloy_genesis::Genesis;
use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256};
@@ -107,7 +108,10 @@ pub static MAINNET: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| {
deposit_contract: Some(MAINNET_DEPOSIT_CONTRACT),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: MAINNET_PRUNE_DELETE_LIMIT,
blob_params: BlobScheduleBlobParams::default(),
blob_params: BlobScheduleBlobParams::default().with_scheduled([
(mainnet::MAINNET_BPO1_TIMESTAMP, BlobParams::bpo1()),
(mainnet::MAINNET_BPO2_TIMESTAMP, BlobParams::bpo2()),
]),
};
spec.genesis.config.dao_fork_support = true;
spec.into()
@@ -136,7 +140,10 @@ pub static SEPOLIA: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| {
)),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 10000,
blob_params: BlobScheduleBlobParams::default(),
blob_params: BlobScheduleBlobParams::default().with_scheduled([
(sepolia::SEPOLIA_BPO1_TIMESTAMP, BlobParams::bpo1()),
(sepolia::SEPOLIA_BPO2_TIMESTAMP, BlobParams::bpo2()),
]),
};
spec.genesis.config.dao_fork_support = true;
spec.into()
@@ -163,7 +170,10 @@ pub static HOLESKY: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| {
)),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 10000,
blob_params: BlobScheduleBlobParams::default(),
blob_params: BlobScheduleBlobParams::default().with_scheduled([
(holesky::HOLESKY_BPO1_TIMESTAMP, BlobParams::bpo1()),
(holesky::HOLESKY_BPO2_TIMESTAMP, BlobParams::bpo2()),
]),
};
spec.genesis.config.dao_fork_support = true;
spec.into()
@@ -192,7 +202,10 @@ pub static HOODI: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| {
)),
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
prune_delete_limit: 10000,
blob_params: BlobScheduleBlobParams::default(),
blob_params: BlobScheduleBlobParams::default().with_scheduled([
(hoodi::HOODI_BPO1_TIMESTAMP, BlobParams::bpo1()),
(hoodi::HOODI_BPO2_TIMESTAMP, BlobParams::bpo2()),
]),
};
spec.genesis.config.dao_fork_support = true;
spec.into()
@@ -208,13 +221,10 @@ pub static DEV: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| {
let hardforks = DEV_HARDFORKS.clone();
ChainSpec {
chain: Chain::dev(),
genesis_header: SealedHeader::new(
make_genesis_header(&genesis, &hardforks),
DEV_GENESIS_HASH,
),
genesis_header: SealedHeader::seal_slow(make_genesis_header(&genesis, &hardforks)),
genesis,
paris_block_and_final_difficulty: Some((0, U256::from(0))),
hardforks: DEV_HARDFORKS.clone(),
hardforks,
base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()),
deposit_contract: None, // TODO: do we even have?
..Default::default()
@@ -393,25 +403,6 @@ impl ChainSpec {
}
}
/// Get the [`BaseFeeParams`] for the chain at the given block number
pub fn base_fee_params_at_block(&self, block_number: u64) -> BaseFeeParams {
match self.base_fee_params {
BaseFeeParamsKind::Constant(bf_params) => bf_params,
BaseFeeParamsKind::Variable(ForkBaseFeeParams(ref bf_params)) => {
// Walk through the base fee params configuration in reverse order, and return the
// first one that corresponds to a hardfork that is active at the
// given timestamp.
for (fork, params) in bf_params.iter().rev() {
if self.hardforks.is_fork_active_at_block(fork.clone(), block_number) {
return *params
}
}
bf_params.first().map(|(_, params)| *params).unwrap_or(BaseFeeParams::ethereum())
}
}
}
/// Get the hash of the genesis block.
pub fn genesis_hash(&self) -> B256 {
self.genesis_header.hash()
@@ -474,8 +465,8 @@ impl ChainSpec {
/// Creates a [`ForkFilter`] for the block described by [Head].
pub fn fork_filter(&self, head: Head) -> ForkFilter {
let forks = self.hardforks.forks_iter().filter_map(|(_, condition)| {
// We filter out TTD-based forks w/o a pre-known block since those do not show up in the
// fork filter.
// We filter out TTD-based forks w/o a pre-known block since those do not show up in
// the fork filter.
Some(match condition {
ForkCondition::Block(block) |
ForkCondition::TTD { fork_block: Some(block), .. } => ForkFilterKey::Block(block),
@@ -689,6 +680,11 @@ impl From<Genesis> for ChainSpec {
(EthereumHardfork::Cancun.boxed(), genesis.config.cancun_time),
(EthereumHardfork::Prague.boxed(), genesis.config.prague_time),
(EthereumHardfork::Osaka.boxed(), genesis.config.osaka_time),
(EthereumHardfork::Bpo1.boxed(), genesis.config.bpo1_time),
(EthereumHardfork::Bpo2.boxed(), genesis.config.bpo2_time),
(EthereumHardfork::Bpo3.boxed(), genesis.config.bpo3_time),
(EthereumHardfork::Bpo4.boxed(), genesis.config.bpo4_time),
(EthereumHardfork::Bpo5.boxed(), genesis.config.bpo5_time),
];
let mut time_hardforks = time_hardfork_opts
@@ -804,6 +800,12 @@ impl ChainSpecBuilder {
self
}
/// Resets any existing hardforks from the builder.
pub fn reset(mut self) -> Self {
self.hardforks = ChainHardforks::default();
self
}
/// Set the genesis block.
pub fn genesis(mut self, genesis: Genesis) -> Self {
self.genesis = Some(genesis);
@@ -942,6 +944,12 @@ impl ChainSpecBuilder {
self
}
/// Enable Prague at the given timestamp.
pub fn with_prague_at(mut self, timestamp: u64) -> Self {
self.hardforks.insert(EthereumHardfork::Prague, ForkCondition::Timestamp(timestamp));
self
}
/// Enable Osaka at genesis.
pub fn osaka_activated(mut self) -> Self {
self = self.prague_activated();
@@ -949,6 +957,12 @@ impl ChainSpecBuilder {
self
}
/// Enable Osaka at the given timestamp.
pub fn with_osaka_at(mut self, timestamp: u64) -> Self {
self.hardforks.insert(EthereumHardfork::Osaka, ForkCondition::Timestamp(timestamp));
self
}
/// Build the resulting [`ChainSpec`].
///
/// # Panics
@@ -1050,9 +1064,9 @@ mod tests {
"Expected fork ID {expected_id:?}, computed fork ID {computed_id:?} for hardfork {hardfork}"
);
if matches!(hardfork, EthereumHardfork::Shanghai) {
if let Some(shangai_id) = spec.shanghai_fork_id() {
if let Some(shanghai_id) = spec.shanghai_fork_id() {
assert_eq!(
expected_id, &shangai_id,
expected_id, &shanghai_id,
"Expected fork ID {expected_id:?}, computed fork ID {computed_id:?} for Shanghai hardfork"
);
} else {
@@ -1087,7 +1101,10 @@ Merge hard forks:
Post-merge hard forks (timestamp based):
- Shanghai @1681338455
- Cancun @1710338135
- Prague @1746612311"
- Prague @1746612311
- Osaka @1764798551
- Bpo1 @1765978199
- Bpo2 @1767747671"
);
}
@@ -1331,7 +1348,10 @@ Post-merge hard forks (timestamp based):
),
(
EthereumHardfork::Prague,
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
ForkId {
hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]),
next: mainnet::MAINNET_OSAKA_TIMESTAMP,
},
),
],
);
@@ -1396,7 +1416,10 @@ Post-merge hard forks (timestamp based):
),
(
EthereumHardfork::Prague,
ForkId { hash: ForkHash([0xed, 0x88, 0xb5, 0xfd]), next: 0 },
ForkId {
hash: ForkHash([0xed, 0x88, 0xb5, 0xfd]),
next: sepolia::SEPOLIA_OSAKA_TIMESTAMP,
},
),
],
);
@@ -1472,12 +1495,22 @@ Post-merge hard forks (timestamp based):
// First Prague block
(
Head { number: 20000002, timestamp: 1746612311, ..Default::default() },
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
ForkId {
hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]),
next: mainnet::MAINNET_OSAKA_TIMESTAMP,
},
),
// Future Prague block
// Osaka block
(
Head { number: 20000002, timestamp: 2000000000, ..Default::default() },
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
Head {
number: 20000002,
timestamp: mainnet::MAINNET_OSAKA_TIMESTAMP,
..Default::default()
},
ForkId {
hash: ForkHash(hex!("0x5167e2a6")),
next: mainnet::MAINNET_BPO1_TIMESTAMP,
},
),
],
);
@@ -1495,7 +1528,22 @@ Post-merge hard forks (timestamp based):
// First Prague block
(
Head { number: 0, timestamp: 1742999833, ..Default::default() },
ForkId { hash: ForkHash([0x09, 0x29, 0xe2, 0x4e]), next: 0 },
ForkId {
hash: ForkHash([0x09, 0x29, 0xe2, 0x4e]),
next: hoodi::HOODI_OSAKA_TIMESTAMP,
},
),
// First Osaka block
(
Head {
number: 0,
timestamp: hoodi::HOODI_OSAKA_TIMESTAMP,
..Default::default()
},
ForkId {
hash: ForkHash(hex!("0xe7e0e7ff")),
next: hoodi::HOODI_BPO1_TIMESTAMP,
},
),
],
)
@@ -1543,7 +1591,22 @@ Post-merge hard forks (timestamp based):
// First Prague block
(
Head { number: 123, timestamp: 1740434112, ..Default::default() },
ForkId { hash: ForkHash([0xdf, 0xbd, 0x9b, 0xed]), next: 0 },
ForkId {
hash: ForkHash([0xdf, 0xbd, 0x9b, 0xed]),
next: holesky::HOLESKY_OSAKA_TIMESTAMP,
},
),
// First Osaka block
(
Head {
number: 123,
timestamp: holesky::HOLESKY_OSAKA_TIMESTAMP,
..Default::default()
},
ForkId {
hash: ForkHash(hex!("0x783def52")),
next: holesky::HOLESKY_BPO1_TIMESTAMP,
},
),
],
)
@@ -1593,7 +1656,22 @@ Post-merge hard forks (timestamp based):
// First Prague block
(
Head { number: 1735377, timestamp: 1741159776, ..Default::default() },
ForkId { hash: ForkHash([0xed, 0x88, 0xb5, 0xfd]), next: 0 },
ForkId {
hash: ForkHash([0xed, 0x88, 0xb5, 0xfd]),
next: sepolia::SEPOLIA_OSAKA_TIMESTAMP,
},
),
// First Osaka block
(
Head {
number: 1735377,
timestamp: sepolia::SEPOLIA_OSAKA_TIMESTAMP,
..Default::default()
},
ForkId {
hash: ForkHash(hex!("0xe2ae4999")),
next: sepolia::SEPOLIA_BPO1_TIMESTAMP,
},
),
],
);
@@ -1605,7 +1683,7 @@ Post-merge hard forks (timestamp based):
&DEV,
&[(
Head { number: 0, ..Default::default() },
ForkId { hash: ForkHash([0x45, 0xb8, 0x36, 0x12]), next: 0 },
ForkId { hash: ForkHash([0x0b, 0x1a, 0x4e, 0xf7]), next: 0 },
)],
)
}
@@ -1741,11 +1819,22 @@ Post-merge hard forks (timestamp based):
), // First Prague block
(
Head { number: 20000004, timestamp: 1746612311, ..Default::default() },
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
), // Future Prague block
ForkId {
hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]),
next: mainnet::MAINNET_OSAKA_TIMESTAMP,
},
),
// Osaka block
(
Head { number: 20000004, timestamp: 2000000000, ..Default::default() },
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
Head {
number: 20000004,
timestamp: mainnet::MAINNET_OSAKA_TIMESTAMP,
..Default::default()
},
ForkId {
hash: ForkHash(hex!("0x5167e2a6")),
next: mainnet::MAINNET_BPO1_TIMESTAMP,
},
),
],
);
@@ -2402,10 +2491,26 @@ Post-merge hard forks (timestamp based):
#[test]
fn latest_eth_mainnet_fork_id() {
assert_eq!(
ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 },
MAINNET.latest_fork_id()
)
// BPO2
assert_eq!(ForkId { hash: ForkHash(hex!("0xfd414558")), next: 0 }, MAINNET.latest_fork_id())
}
#[test]
fn latest_hoodi_mainnet_fork_id() {
// BPO2
assert_eq!(ForkId { hash: ForkHash(hex!("0x23aa1351")), next: 0 }, HOODI.latest_fork_id())
}
#[test]
fn latest_holesky_mainnet_fork_id() {
// BPO2
assert_eq!(ForkId { hash: ForkHash(hex!("0x9bc6cb31")), next: 0 }, HOLESKY.latest_fork_id())
}
#[test]
fn latest_sepolia_mainnet_fork_id() {
// BPO2
assert_eq!(ForkId { hash: ForkHash(hex!("0x268956b6")), next: 0 }, SEPOLIA.latest_fork_id())
}
#[test]
@@ -2528,6 +2633,7 @@ Post-merge hard forks (timestamp based):
update_fraction: 3338477,
min_blob_fee: BLOB_TX_MIN_BLOB_GASPRICE,
max_blobs_per_tx: 6,
blob_base_cost: 0,
},
prague: BlobParams {
target_blob_count: 3,
@@ -2535,6 +2641,7 @@ Post-merge hard forks (timestamp based):
update_fraction: 3338477,
min_blob_fee: BLOB_TX_MIN_BLOB_GASPRICE,
max_blobs_per_tx: 6,
blob_base_cost: 0,
},
..Default::default()
};

View File

@@ -24,6 +24,7 @@ reth-db-common.workspace = true
reth-downloaders.workspace = true
reth-ecies.workspace = true
reth-eth-wire.workspace = true
reth-era.workspace = true
reth-era-downloader.workspace = true
reth-era-utils.workspace = true
reth-etl.workspace = true
@@ -43,13 +44,14 @@ reth-ethereum-primitives = { workspace = true, optional = true }
reth-provider.workspace = true
reth-prune.workspace = true
reth-prune-types = { workspace = true, optional = true }
reth-revm.workspace = true
reth-stages.workspace = true
reth-stages-types = { workspace = true, optional = true }
reth-static-file-types = { workspace = true, features = ["clap"] }
reth-static-file.workspace = true
reth-trie = { workspace = true, features = ["metrics"] }
reth-trie-db = { workspace = true, features = ["metrics"] }
reth-trie-common = { workspace = true, optional = true }
reth-trie-common.workspace = true
reth-primitives-traits.workspace = true
reth-discv4.workspace = true
reth-discv5.workspace = true
@@ -66,11 +68,12 @@ futures.workspace = true
tokio.workspace = true
# misc
ahash.workspace = true
humantime.workspace = true
human_bytes.workspace = true
eyre.workspace = true
clap = { workspace = true, features = ["derive", "env"] }
lz4.workspace = true
zstd.workspace = true
serde.workspace = true
serde_json.workspace = true
tar.workspace = true
@@ -117,7 +120,7 @@ arbitrary = [
"reth-codecs/arbitrary",
"reth-prune-types?/arbitrary",
"reth-stages-types?/arbitrary",
"reth-trie-common?/arbitrary",
"reth-trie-common/arbitrary",
"alloy-consensus/arbitrary",
"reth-primitives-traits/arbitrary",
"reth-ethereum-primitives/arbitrary",

View File

@@ -5,11 +5,13 @@ use clap::Parser;
use reth_chainspec::EthChainSpec;
use reth_cli::chainspec::ChainSpecParser;
use reth_config::{config::EtlConfig, Config};
use reth_consensus::{noop::NoopConsensus, ConsensusError, FullConsensus};
use reth_consensus::noop::NoopConsensus;
use reth_db::{init_db, open_db_read_only, DatabaseEnv};
use reth_db_common::init::init_genesis;
use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader};
use reth_eth_wire::NetPrimitivesFor;
use reth_evm::{noop::NoopEvmConfig, ConfigureEvm};
use reth_network::NetworkEventListenerProvider;
use reth_node_api::FullNodeTypesAdapter;
use reth_node_builder::{
Node, NodeComponents, NodeComponentsBuilder, NodeTypes, NodeTypesWithDBAdapter,
@@ -214,10 +216,22 @@ type FullTypesAdapter<T> = FullNodeTypesAdapter<
BlockchainProvider<NodeTypesWithDBAdapter<T, Arc<DatabaseEnv>>>,
>;
/// Trait for block headers that can be modified through CLI operations.
pub trait CliHeader {
fn set_number(&mut self, number: u64);
}
impl CliHeader for alloy_consensus::Header {
fn set_number(&mut self, number: u64) {
self.number = number;
}
}
/// Helper trait with a common set of requirements for the
/// [`NodeTypes`] in CLI.
pub trait CliNodeTypes: NodeTypesForProvider {
pub trait CliNodeTypes: Node<FullTypesAdapter<Self>> + NodeTypesForProvider {
type Evm: ConfigureEvm<Primitives = Self::Primitives>;
type NetworkPrimitives: NetPrimitivesFor<Self::Primitives>;
}
impl<N> CliNodeTypes for N
@@ -225,34 +239,47 @@ where
N: Node<FullTypesAdapter<Self>> + NodeTypesForProvider,
{
type Evm = <<N::ComponentsBuilder as NodeComponentsBuilder<FullTypesAdapter<Self>>>::Components as NodeComponents<FullTypesAdapter<Self>>>::Evm;
type NetworkPrimitives = <<<N::ComponentsBuilder as NodeComponentsBuilder<FullTypesAdapter<Self>>>::Components as NodeComponents<FullTypesAdapter<Self>>>::Network as NetworkEventListenerProvider>::Primitives;
}
type EvmFor<N> = <<<N as Node<FullTypesAdapter<N>>>::ComponentsBuilder as NodeComponentsBuilder<
FullTypesAdapter<N>,
>>::Components as NodeComponents<FullTypesAdapter<N>>>::Evm;
type ConsensusFor<N> =
<<<N as Node<FullTypesAdapter<N>>>::ComponentsBuilder as NodeComponentsBuilder<
FullTypesAdapter<N>,
>>::Components as NodeComponents<FullTypesAdapter<N>>>::Consensus;
/// Helper trait aggregating components required for the CLI.
pub trait CliNodeComponents<N: CliNodeTypes> {
/// Evm to use.
type Evm: ConfigureEvm<Primitives = N::Primitives> + 'static;
/// Consensus implementation.
type Consensus: FullConsensus<N::Primitives, Error = ConsensusError> + Clone + 'static;
pub trait CliNodeComponents<N: CliNodeTypes>: Send + Sync + 'static {
/// Returns the configured EVM.
fn evm_config(&self) -> &Self::Evm;
fn evm_config(&self) -> &EvmFor<N>;
/// Returns the consensus implementation.
fn consensus(&self) -> &Self::Consensus;
fn consensus(&self) -> &ConsensusFor<N>;
}
impl<N: CliNodeTypes, E, C> CliNodeComponents<N> for (E, C)
where
E: ConfigureEvm<Primitives = N::Primitives> + 'static,
C: FullConsensus<N::Primitives, Error = ConsensusError> + Clone + 'static,
{
type Evm = E;
type Consensus = C;
fn evm_config(&self) -> &Self::Evm {
impl<N: CliNodeTypes> CliNodeComponents<N> for (EvmFor<N>, ConsensusFor<N>) {
fn evm_config(&self) -> &EvmFor<N> {
&self.0
}
fn consensus(&self) -> &Self::Consensus {
fn consensus(&self) -> &ConsensusFor<N> {
&self.1
}
}
/// Helper trait alias for an [`FnOnce`] producing [`CliNodeComponents`].
pub trait CliComponentsBuilder<N: CliNodeTypes>:
FnOnce(Arc<N::ChainSpec>) -> Self::Components + Send + Sync + 'static
{
type Components: CliNodeComponents<N>;
}
impl<N: CliNodeTypes, F, Comp> CliComponentsBuilder<N> for F
where
F: FnOnce(Arc<N::ChainSpec>) -> Comp + Send + Sync + 'static,
Comp: CliNodeComponents<N>,
{
type Components = Comp;
}

View File

@@ -2,7 +2,7 @@ use crate::{
common::CliNodeTypes,
db::get::{maybe_json_value_parser, table_key},
};
use ahash::RandomState;
use alloy_primitives::map::foldhash::fast::FixedState;
use clap::Parser;
use reth_chainspec::EthereumHardforks;
use reth_db::DatabaseEnv;
@@ -102,7 +102,7 @@ impl<N: ProviderNodeTypes> TableViewer<(u64, Duration)> for ChecksumViewer<'_, N
};
let start_time = Instant::now();
let mut hasher = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
let mut hasher = FixedState::with_seed(u64::from_be_bytes(*b"RETHRETH")).build_hasher();
let mut total = 0;
let limit = self.limit.unwrap_or(usize::MAX);
@@ -111,7 +111,7 @@ impl<N: ProviderNodeTypes> TableViewer<(u64, Duration)> for ChecksumViewer<'_, N
for (index, entry) in walker.enumerate() {
let (k, v): (RawKey<T::Key>, RawValue<T::Value>) = entry?;
if index % 100_000 == 0 {
if index.is_multiple_of(100_000) {
info!("Hashed {index} entries.");
}

View File

@@ -1,8 +1,11 @@
use alloy_consensus::Header;
use alloy_primitives::{hex, BlockHash};
use clap::Parser;
use reth_db::static_file::{
ColumnSelectorOne, ColumnSelectorTwo, HeaderWithHashMask, ReceiptMask, TransactionMask,
use reth_db::{
static_file::{
ColumnSelectorOne, ColumnSelectorTwo, HeaderWithHashMask, ReceiptMask, TransactionMask,
},
RawDupSort,
};
use reth_db_api::{
table::{Decompress, DupSort, Table},
@@ -72,7 +75,6 @@ impl Command {
StaticFileSegment::Receipts => {
(table_key::<tables::Receipts>(&key)?, <ReceiptMask<ReceiptTy<N>>>::MASK)
}
StaticFileSegment::BlockMeta => todo!(),
};
let content = tool.provider_factory.static_file_provider().find_static_file(
@@ -114,9 +116,6 @@ impl Command {
)?;
println!("{}", serde_json::to_string_pretty(&receipt)?);
}
StaticFileSegment::BlockMeta => {
todo!()
}
}
}
}
@@ -181,9 +180,21 @@ impl<N: ProviderNodeTypes> TableViewer<()> for GetValueViewer<'_, N> {
// process dupsort table
let subkey = table_subkey::<T>(self.subkey.as_deref())?;
match self.tool.get_dup::<T>(key, subkey)? {
let content = if self.raw {
self.tool
.get_dup::<RawDupSort<T>>(RawKey::from(key), RawKey::from(subkey))?
.map(|content| hex::encode_prefixed(content.raw_value()))
} else {
self.tool
.get_dup::<T>(key, subkey)?
.as_ref()
.map(serde_json::to_string_pretty)
.transpose()?
};
match content {
Some(content) => {
println!("{}", serde_json::to_string_pretty(&content)?);
println!("{content}");
}
None => {
error!(target: "reth::cli", "No content for the given table subkey.");

View File

@@ -13,6 +13,7 @@ mod clear;
mod diff;
mod get;
mod list;
mod repair_trie;
mod stats;
/// DB List TUI
mod tui;
@@ -48,6 +49,8 @@ pub enum Subcommands {
},
/// Deletes all table entries
Clear(clear::Command),
/// Verifies trie consistency and outputs any inconsistencies
RepairTrie(repair_trie::Command),
/// Lists current and local database versions
Version,
/// Returns the full database path
@@ -135,6 +138,12 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C>
let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RW)?;
command.execute(provider_factory)?;
}
Subcommands::RepairTrie(command) => {
let access_rights =
if command.dry_run { AccessRights::RO } else { AccessRights::RW };
let Environment { provider_factory, .. } = self.env.init::<N>(access_rights)?;
command.execute(provider_factory)?;
}
Subcommands::Version => {
let local_db_version = match get_db_version(&db_path) {
Ok(version) => Some(version),

View File

@@ -0,0 +1,240 @@
use clap::Parser;
use reth_db_api::{
cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO},
database::Database,
tables,
transaction::{DbTx, DbTxMut},
};
use reth_node_builder::NodeTypesWithDB;
use reth_provider::{providers::ProviderNodeTypes, ProviderFactory, StageCheckpointReader};
use reth_stages::StageId;
use reth_trie::{
verify::{Output, Verifier},
Nibbles,
};
use reth_trie_common::{StorageTrieEntry, StoredNibbles, StoredNibblesSubKey};
use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
use std::time::{Duration, Instant};
use tracing::{info, warn};
const PROGRESS_PERIOD: Duration = Duration::from_secs(5);
/// The arguments for the `reth db repair-trie` command
#[derive(Parser, Debug)]
pub struct Command {
/// Only show inconsistencies without making any repairs
#[arg(long)]
pub(crate) dry_run: bool,
}
impl Command {
/// Execute `db repair-trie` command
pub fn execute<N: ProviderNodeTypes>(
self,
provider_factory: ProviderFactory<N>,
) -> eyre::Result<()> {
if self.dry_run {
verify_only(provider_factory)?
} else {
verify_and_repair(provider_factory)?
}
Ok(())
}
}
fn verify_only<N: NodeTypesWithDB>(provider_factory: ProviderFactory<N>) -> eyre::Result<()> {
// Get a database transaction directly from the database
let db = provider_factory.db_ref();
let mut tx = db.tx()?;
tx.disable_long_read_transaction_safety();
// Create the verifier
let hashed_cursor_factory = DatabaseHashedCursorFactory::new(&tx);
let trie_cursor_factory = DatabaseTrieCursorFactory::new(&tx);
let verifier = Verifier::new(trie_cursor_factory, hashed_cursor_factory)?;
let mut inconsistent_nodes = 0;
let start_time = Instant::now();
let mut last_progress_time = Instant::now();
// Iterate over the verifier and repair inconsistencies
for output_result in verifier {
let output = output_result?;
if let Output::Progress(path) = output {
if last_progress_time.elapsed() > PROGRESS_PERIOD {
output_progress(path, start_time, inconsistent_nodes);
last_progress_time = Instant::now();
}
} else {
warn!("Inconsistency found: {output:?}");
inconsistent_nodes += 1;
}
}
info!("Found {} inconsistencies (dry run - no changes made)", inconsistent_nodes);
Ok(())
}
/// Checks that the merkle stage has completed running up to the account and storage hashing stages.
fn verify_checkpoints(provider: impl StageCheckpointReader) -> eyre::Result<()> {
let account_hashing_checkpoint =
provider.get_stage_checkpoint(StageId::AccountHashing)?.unwrap_or_default();
let storage_hashing_checkpoint =
provider.get_stage_checkpoint(StageId::StorageHashing)?.unwrap_or_default();
let merkle_checkpoint =
provider.get_stage_checkpoint(StageId::MerkleExecute)?.unwrap_or_default();
if account_hashing_checkpoint.block_number != merkle_checkpoint.block_number {
return Err(eyre::eyre!(
"MerkleExecute stage checkpoint ({}) != AccountHashing stage checkpoint ({}), you must first complete the pipeline sync by running `reth node`",
merkle_checkpoint.block_number,
account_hashing_checkpoint.block_number,
))
}
if storage_hashing_checkpoint.block_number != merkle_checkpoint.block_number {
return Err(eyre::eyre!(
"MerkleExecute stage checkpoint ({}) != StorageHashing stage checkpoint ({}), you must first complete the pipeline sync by running `reth node`",
merkle_checkpoint.block_number,
storage_hashing_checkpoint.block_number,
))
}
let merkle_checkpoint_progress =
provider.get_stage_checkpoint_progress(StageId::MerkleExecute)?;
if merkle_checkpoint_progress.is_some_and(|progress| !progress.is_empty()) {
return Err(eyre::eyre!(
"MerkleExecute sync stage in-progress, you must first complete the pipeline sync by running `reth node`",
))
}
Ok(())
}
fn verify_and_repair<N: ProviderNodeTypes>(
provider_factory: ProviderFactory<N>,
) -> eyre::Result<()> {
// Get a read-write database provider
let mut provider_rw = provider_factory.provider_rw()?;
// Check that a pipeline sync isn't in progress.
verify_checkpoints(provider_rw.as_ref())?;
let tx = provider_rw.tx_mut();
tx.disable_long_read_transaction_safety();
// Create the hashed cursor factory
let hashed_cursor_factory = DatabaseHashedCursorFactory::new(tx);
// Create the trie cursor factory
let trie_cursor_factory = DatabaseTrieCursorFactory::new(tx);
// Create the verifier
let verifier = Verifier::new(trie_cursor_factory, hashed_cursor_factory)?;
let mut account_trie_cursor = tx.cursor_write::<tables::AccountsTrie>()?;
let mut storage_trie_cursor = tx.cursor_dup_write::<tables::StoragesTrie>()?;
let mut inconsistent_nodes = 0;
let start_time = Instant::now();
let mut last_progress_time = Instant::now();
// Iterate over the verifier and repair inconsistencies
for output_result in verifier {
let output = output_result?;
if !matches!(output, Output::Progress(_)) {
warn!("Inconsistency found, will repair: {output:?}");
inconsistent_nodes += 1;
}
match output {
Output::AccountExtra(path, _node) => {
// Extra account node in trie, remove it
let nibbles = StoredNibbles(path);
if account_trie_cursor.seek_exact(nibbles)?.is_some() {
account_trie_cursor.delete_current()?;
}
}
Output::StorageExtra(account, path, _node) => {
// Extra storage node in trie, remove it
let nibbles = StoredNibblesSubKey(path);
if storage_trie_cursor
.seek_by_key_subkey(account, nibbles.clone())?
.filter(|e| e.nibbles == nibbles)
.is_some()
{
storage_trie_cursor.delete_current()?;
}
}
Output::AccountWrong { path, expected: node, .. } |
Output::AccountMissing(path, node) => {
// Wrong/missing account node value, upsert it
let nibbles = StoredNibbles(path);
account_trie_cursor.upsert(nibbles, &node)?;
}
Output::StorageWrong { account, path, expected: node, .. } |
Output::StorageMissing(account, path, node) => {
// Wrong/missing storage node value, upsert it
let nibbles = StoredNibblesSubKey(path);
let entry = StorageTrieEntry { nibbles, node };
storage_trie_cursor.upsert(account, &entry)?;
}
Output::Progress(path) => {
if last_progress_time.elapsed() > PROGRESS_PERIOD {
output_progress(path, start_time, inconsistent_nodes);
last_progress_time = Instant::now();
}
}
}
}
if inconsistent_nodes == 0 {
info!("No inconsistencies found");
} else {
info!("Repaired {} inconsistencies, committing changes", inconsistent_nodes);
provider_rw.commit()?;
}
Ok(())
}
/// Output progress information based on the last seen account path.
fn output_progress(last_account: Nibbles, start_time: Instant, inconsistent_nodes: u64) {
// Calculate percentage based on position in the trie path space
// For progress estimation, we'll use the first few nibbles as an approximation
// Convert the first 16 nibbles (8 bytes) to a u64 for progress calculation
let mut current_value: u64 = 0;
let nibbles_to_use = last_account.len().min(16);
for i in 0..nibbles_to_use {
current_value = (current_value << 4) | (last_account.get(i).unwrap_or(0) as u64);
}
// Shift left to fill remaining bits if we have fewer than 16 nibbles
if nibbles_to_use < 16 {
current_value <<= (16 - nibbles_to_use) * 4;
}
let progress_percent = current_value as f64 / u64::MAX as f64 * 100.0;
let progress_percent_str = format!("{progress_percent:.2}");
// Calculate ETA based on current speed
let elapsed = start_time.elapsed();
let elapsed_secs = elapsed.as_secs_f64();
let estimated_total_time =
if progress_percent > 0.0 { elapsed_secs / (progress_percent / 100.0) } else { 0.0 };
let remaining_time = estimated_total_time - elapsed_secs;
let eta_duration = Duration::from_secs(remaining_time as u64);
info!(
progress_percent = progress_percent_str,
eta = %humantime::format_duration(eta_duration),
inconsistent_nodes,
"Repairing trie tables",
);
}

View File

@@ -15,10 +15,12 @@ use std::{
use tar::Archive;
use tokio::task;
use tracing::info;
use zstd::stream::read::Decoder as ZstdDecoder;
const BYTE_UNITS: [&str; 4] = ["B", "KB", "MB", "GB"];
const MERKLE_BASE_URL: &str = "https://downloads.merkle.io";
const EXTENSION_TAR_FILE: &str = ".tar.lz4";
const EXTENSION_TAR_LZ4: &str = ".tar.lz4";
const EXTENSION_TAR_ZSTD: &str = ".tar.zst";
#[derive(Debug, Parser)]
pub struct DownloadCommand<C: ChainSpecParser> {
@@ -32,7 +34,7 @@ pub struct DownloadCommand<C: ChainSpecParser> {
long_help = "Specify a snapshot URL or let the command propose a default one.\n\
\n\
Available snapshot sources:\n\
- https://downloads.merkle.io (default, mainnet archive)\n\
- https://www.merkle.io/snapshots (default, mainnet archive)\n\
- https://publicnode.com/snapshots (full nodes & testnets)\n\
\n\
If no URL is provided, the latest mainnet archive snapshot\n\
@@ -139,16 +141,36 @@ impl<R: Read> ProgressReader<R> {
impl<R: Read> Read for ProgressReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let bytes = self.reader.read(buf)?;
if bytes > 0 {
if let Err(e) = self.progress.update(bytes as u64) {
return Err(io::Error::other(e));
}
if bytes > 0 &&
let Err(e) = self.progress.update(bytes as u64)
{
return Err(io::Error::other(e));
}
Ok(bytes)
}
}
/// Downloads and extracts a snapshot with blocking approach
/// Supported compression formats for snapshots
#[derive(Debug, Clone, Copy)]
enum CompressionFormat {
Lz4,
Zstd,
}
impl CompressionFormat {
/// Detect compression format from file extension
fn from_url(url: &str) -> Result<Self> {
if url.ends_with(EXTENSION_TAR_LZ4) {
Ok(Self::Lz4)
} else if url.ends_with(EXTENSION_TAR_ZSTD) {
Ok(Self::Zstd)
} else {
Err(eyre::eyre!("Unsupported file format. Expected .tar.lz4 or .tar.zst, got: {}", url))
}
}
}
/// Downloads and extracts a snapshot, blocking until finished.
fn blocking_download_and_extract(url: &str, target_dir: &Path) -> Result<()> {
let client = reqwest::blocking::Client::builder().build()?;
let response = client.get(url).send()?.error_for_status()?;
@@ -160,11 +182,18 @@ fn blocking_download_and_extract(url: &str, target_dir: &Path) -> Result<()> {
})?;
let progress_reader = ProgressReader::new(response, total_size);
let format = CompressionFormat::from_url(url)?;
let decoder = Decoder::new(progress_reader)?;
let mut archive = Archive::new(decoder);
archive.unpack(target_dir)?;
match format {
CompressionFormat::Lz4 => {
let decoder = Decoder::new(progress_reader)?;
Archive::new(decoder).unpack(target_dir)?;
}
CompressionFormat::Zstd => {
let decoder = ZstdDecoder::new(progress_reader)?;
Archive::new(decoder).unpack(target_dir)?;
}
}
info!(target: "reth::cli", "Extraction complete.");
Ok(())
@@ -191,9 +220,5 @@ async fn get_latest_snapshot_url() -> Result<String> {
.trim()
.to_string();
if !filename.ends_with(EXTENSION_TAR_FILE) {
return Err(eyre::eyre!("Unexpected snapshot filename format: {}", filename));
}
Ok(format!("{MERKLE_BASE_URL}/{filename}"))
}

View File

@@ -0,0 +1,109 @@
//! Command exporting block data to convert them to ERA1 files.
use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs};
use clap::{Args, Parser};
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_era::execution_types::MAX_BLOCKS_PER_ERA1;
use reth_era_utils as era1;
use reth_provider::DatabaseProviderFactory;
use std::{path::PathBuf, sync::Arc};
use tracing::info;
// Default folder name for era1 export files
const ERA1_EXPORT_FOLDER_NAME: &str = "era1-export";
#[derive(Debug, Parser)]
pub struct ExportEraCommand<C: ChainSpecParser> {
#[command(flatten)]
env: EnvironmentArgs<C>,
#[clap(flatten)]
export: ExportArgs,
}
#[derive(Debug, Args)]
pub struct ExportArgs {
/// Optional first block number to export from the db.
/// It is by default 0.
#[arg(long, value_name = "first-block-number", verbatim_doc_comment)]
first_block_number: Option<u64>,
/// Optional last block number to export from the db.
/// It is by default 8191.
#[arg(long, value_name = "last-block-number", verbatim_doc_comment)]
last_block_number: Option<u64>,
/// The maximum number of blocks per file, it can help you to decrease the size of the files.
/// Must be less than or equal to 8192.
#[arg(long, value_name = "max-blocks-per-file", verbatim_doc_comment)]
max_blocks_per_file: Option<u64>,
/// The directory path where to export era1 files.
/// The block data are read from the database.
#[arg(long, value_name = "EXPORT_ERA1_PATH", verbatim_doc_comment)]
path: Option<PathBuf>,
}
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> ExportEraCommand<C> {
/// Execute `export-era` command
pub async fn execute<N>(self) -> eyre::Result<()>
where
N: CliNodeTypes<ChainSpec = C::ChainSpec>,
{
let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RO)?;
// Either specified path or default to `<data-dir>/<chain>/era1-export/`
let data_dir = match &self.export.path {
Some(path) => path.clone(),
None => self
.env
.datadir
.resolve_datadir(self.env.chain.chain())
.data_dir()
.join(ERA1_EXPORT_FOLDER_NAME),
};
let export_config = era1::ExportConfig {
network: self.env.chain.chain().to_string(),
first_block_number: self.export.first_block_number.unwrap_or(0),
last_block_number: self
.export
.last_block_number
.unwrap_or(MAX_BLOCKS_PER_ERA1 as u64 - 1),
max_blocks_per_file: self
.export
.max_blocks_per_file
.unwrap_or(MAX_BLOCKS_PER_ERA1 as u64),
dir: data_dir,
};
export_config.validate()?;
info!(
target: "reth::cli",
"Starting ERA1 block export: blocks {}-{} to {}",
export_config.first_block_number,
export_config.last_block_number,
export_config.dir.display()
);
// Only read access is needed for the database provider
let provider = provider_factory.database_provider_ro()?;
let exported_files = era1::export(&provider, &export_config)?;
info!(
target: "reth::cli",
"Successfully exported {} ERA1 files to {}",
exported_files.len(),
export_config.dir.display()
);
Ok(())
}
}
impl<C: ChainSpecParser> ExportEraCommand<C> {
/// Returns the underlying chain being used to run this command
pub fn chain_spec(&self) -> Option<&Arc<C::ChainSpec>> {
Some(&self.env.chain)
}
}

View File

@@ -1,38 +1,18 @@
//! Command that initializes the node by importing a chain from a file.
use crate::common::{AccessRights, CliNodeComponents, CliNodeTypes, Environment, EnvironmentArgs};
use alloy_primitives::B256;
use crate::{
common::{AccessRights, CliNodeComponents, CliNodeTypes, Environment, EnvironmentArgs},
import_core::{import_blocks_from_file, ImportConfig},
};
use clap::Parser;
use futures::{Stream, StreamExt};
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_chainspec::{ChainSpecProvider, EthChainSpec, EthereumHardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_config::Config;
use reth_consensus::{ConsensusError, FullConsensus};
use reth_db_api::{tables, transaction::DbTx};
use reth_downloaders::{
bodies::bodies::BodiesDownloaderBuilder,
file_client::{ChunkedFileReader, FileClient, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE},
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
};
use reth_evm::ConfigureEvm;
use reth_network_p2p::{
bodies::downloader::BodyDownloader,
headers::downloader::{HeaderDownloader, SyncTarget},
};
use reth_node_api::BlockTy;
use reth_node_core::version::SHORT_VERSION;
use reth_node_events::node::NodeEvent;
use reth_provider::{
providers::ProviderNodeTypes, BlockNumReader, ChainSpecProvider, HeaderProvider, ProviderError,
ProviderFactory, StageCheckpointReader,
};
use reth_prune::PruneModes;
use reth_stages::{prelude::*, Pipeline, StageId, StageSet};
use reth_static_file::StaticFileProducer;
use reth_node_core::version::version_metadata;
use std::{path::PathBuf, sync::Arc};
use tokio::sync::watch;
use tracing::{debug, error, info};
use tracing::info;
/// Syncs RLP encoded blocks from a file.
pub use crate::import_core::build_import_pipeline_impl as build_import_pipeline;
/// Syncs RLP encoded blocks from a file or files.
#[derive(Debug, Parser)]
pub struct ImportCommand<C: ChainSpecParser> {
#[command(flatten)]
@@ -46,118 +26,80 @@ pub struct ImportCommand<C: ChainSpecParser> {
#[arg(long, value_name = "CHUNK_LEN", verbatim_doc_comment)]
chunk_len: Option<u64>,
/// The path to a block file for import.
/// The path(s) to block file(s) for import.
///
/// The online stages (headers and bodies) are replaced by a file import, after which the
/// remaining stages are executed.
#[arg(value_name = "IMPORT_PATH", verbatim_doc_comment)]
path: PathBuf,
/// remaining stages are executed. Multiple files will be imported sequentially.
#[arg(value_name = "IMPORT_PATH", required = true, num_args = 1.., verbatim_doc_comment)]
paths: Vec<PathBuf>,
}
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> ImportCommand<C> {
/// Execute `import` command
pub async fn execute<N, Comp, F>(self, components: F) -> eyre::Result<()>
pub async fn execute<N, Comp>(
self,
components: impl FnOnce(Arc<N::ChainSpec>) -> Comp,
) -> eyre::Result<()>
where
N: CliNodeTypes<ChainSpec = C::ChainSpec>,
Comp: CliNodeComponents<N>,
F: FnOnce(Arc<N::ChainSpec>) -> Comp,
{
info!(target: "reth::cli", "reth {} starting", SHORT_VERSION);
if self.no_state {
info!(target: "reth::cli", "Disabled stages requiring state");
}
debug!(target: "reth::cli",
chunk_byte_len=self.chunk_len.unwrap_or(DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE),
"Chunking chain import"
);
info!(target: "reth::cli", "reth {} starting", version_metadata().short_version);
let Environment { provider_factory, config, .. } = self.env.init::<N>(AccessRights::RW)?;
let components = components(provider_factory.chain_spec());
info!(target: "reth::cli", "Starting import of {} file(s)", self.paths.len());
let import_config = ImportConfig { no_state: self.no_state, chunk_len: self.chunk_len };
let executor = components.evm_config().clone();
let consensus = Arc::new(components.consensus().clone());
info!(target: "reth::cli", "Consensus engine initialized");
// open file
let mut reader = ChunkedFileReader::new(&self.path, self.chunk_len).await?;
let mut total_imported_blocks = 0;
let mut total_imported_txns = 0;
let mut total_decoded_blocks = 0;
let mut total_decoded_txns = 0;
let mut sealed_header = provider_factory
.sealed_header(provider_factory.last_block_number()?)?
.expect("should have genesis");
// Import each file sequentially
for (index, path) in self.paths.iter().enumerate() {
info!(target: "reth::cli", "Importing file {} of {}: {}", index + 1, self.paths.len(), path.display());
while let Some(file_client) =
reader.next_chunk::<BlockTy<N>>(consensus.clone(), Some(sealed_header)).await?
{
// create a new FileClient from chunk read from file
info!(target: "reth::cli",
"Importing chain file chunk"
);
let tip = file_client.tip().ok_or(eyre::eyre!("file client has no tip"))?;
info!(target: "reth::cli", "Chain file chunk read");
total_decoded_blocks += file_client.headers_len();
total_decoded_txns += file_client.total_transactions();
let (mut pipeline, events) = build_import_pipeline(
&config,
let result = import_blocks_from_file(
path,
import_config.clone(),
provider_factory.clone(),
&consensus,
Arc::new(file_client),
StaticFileProducer::new(provider_factory.clone(), PruneModes::default()),
self.no_state,
&config,
executor.clone(),
)?;
consensus.clone(),
)
.await?;
// override the tip
pipeline.set_tip(tip);
debug!(target: "reth::cli", ?tip, "Tip manually set");
total_imported_blocks += result.total_imported_blocks;
total_imported_txns += result.total_imported_txns;
total_decoded_blocks += result.total_decoded_blocks;
total_decoded_txns += result.total_decoded_txns;
let provider = provider_factory.provider()?;
let latest_block_number =
provider.get_stage_checkpoint(StageId::Finish)?.map(|ch| ch.block_number);
tokio::spawn(reth_node_events::node::handle_events(None, latest_block_number, events));
// Run pipeline
info!(target: "reth::cli", "Starting sync pipeline");
tokio::select! {
res = pipeline.run() => res?,
_ = tokio::signal::ctrl_c() => {},
if !result.is_complete() {
return Err(eyre::eyre!(
"Chain was partially imported from file: {}. Imported {}/{} blocks, {}/{} transactions",
path.display(),
result.total_imported_blocks,
result.total_decoded_blocks,
result.total_imported_txns,
result.total_decoded_txns
));
}
sealed_header = provider_factory
.sealed_header(provider_factory.last_block_number()?)?
.expect("should have genesis");
}
let provider = provider_factory.provider()?;
let total_imported_blocks = provider.tx_ref().entries::<tables::HeaderNumbers>()?;
let total_imported_txns = provider.tx_ref().entries::<tables::TransactionHashNumbers>()?;
if total_decoded_blocks != total_imported_blocks ||
total_decoded_txns != total_imported_txns
{
error!(target: "reth::cli",
total_decoded_blocks,
total_imported_blocks,
total_decoded_txns,
total_imported_txns,
"Chain was partially imported"
);
info!(target: "reth::cli",
"Successfully imported file {}: {} blocks, {} transactions",
path.display(), result.total_imported_blocks, result.total_imported_txns);
}
info!(target: "reth::cli",
total_imported_blocks,
total_imported_txns,
"Chain file imported"
);
"All files imported successfully. Total: {}/{} blocks, {}/{} transactions",
total_imported_blocks, total_decoded_blocks, total_imported_txns, total_decoded_txns);
Ok(())
}
@@ -170,82 +112,6 @@ impl<C: ChainSpecParser> ImportCommand<C> {
}
}
/// Builds import pipeline.
///
/// If configured to execute, all stages will run. Otherwise, only stages that don't require state
/// will run.
pub fn build_import_pipeline<N, C, E>(
config: &Config,
provider_factory: ProviderFactory<N>,
consensus: &Arc<C>,
file_client: Arc<FileClient<BlockTy<N>>>,
static_file_producer: StaticFileProducer<ProviderFactory<N>>,
disable_exec: bool,
evm_config: E,
) -> eyre::Result<(Pipeline<N>, impl Stream<Item = NodeEvent<N::Primitives>>)>
where
N: ProviderNodeTypes,
C: FullConsensus<N::Primitives, Error = ConsensusError> + 'static,
E: ConfigureEvm<Primitives = N::Primitives> + 'static,
{
if !file_client.has_canonical_blocks() {
eyre::bail!("unable to import non canonical blocks");
}
// Retrieve latest header found in the database.
let last_block_number = provider_factory.last_block_number()?;
let local_head = provider_factory
.sealed_header(last_block_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(last_block_number.into()))?;
let mut header_downloader = ReverseHeadersDownloaderBuilder::new(config.stages.headers)
.build(file_client.clone(), consensus.clone())
.into_task();
// TODO: The pipeline should correctly configure the downloader on its own.
// Find the possibility to remove unnecessary pre-configuration.
header_downloader.update_local_head(local_head);
header_downloader.update_sync_target(SyncTarget::Tip(file_client.tip().unwrap()));
let mut body_downloader = BodiesDownloaderBuilder::new(config.stages.bodies)
.build(file_client.clone(), consensus.clone(), provider_factory.clone())
.into_task();
// TODO: The pipeline should correctly configure the downloader on its own.
// Find the possibility to remove unnecessary pre-configuration.
body_downloader
.set_download_range(file_client.min_block().unwrap()..=file_client.max_block().unwrap())
.expect("failed to set download range");
let (tip_tx, tip_rx) = watch::channel(B256::ZERO);
let max_block = file_client.max_block().unwrap_or(0);
let pipeline = Pipeline::builder()
.with_tip_sender(tip_tx)
// we want to sync all blocks the file client provides or 0 if empty
.with_max_block(max_block)
.with_fail_on_unwind(true)
.add_stages(
DefaultStages::new(
provider_factory.clone(),
tip_rx,
consensus.clone(),
header_downloader,
body_downloader,
evm_config,
config.stages.clone(),
PruneModes::default(),
None,
)
.builder()
.disable_all_if(&StageId::STATE_REQUIRED, || disable_exec),
)
.build(provider_factory, static_file_producer);
let events = pipeline.events().map(Into::into);
Ok((pipeline, events))
}
#[cfg(test)]
mod tests {
use super::*;
@@ -263,4 +129,14 @@ mod tests {
);
}
}
#[test]
fn parse_import_command_with_multiple_paths() {
let args: ImportCommand<EthereumChainSpecParser> =
ImportCommand::parse_from(["reth", "file1.rlp", "file2.rlp", "file3.rlp"]);
assert_eq!(args.paths.len(), 3);
assert_eq!(args.paths[0], PathBuf::from("file1.rlp"));
assert_eq!(args.paths[1], PathBuf::from("file2.rlp"));
assert_eq!(args.paths[2], PathBuf::from("file3.rlp"));
}
}

View File

@@ -0,0 +1,257 @@
//! Core import functionality without CLI dependencies.
use alloy_primitives::B256;
use futures::StreamExt;
use reth_config::Config;
use reth_consensus::FullConsensus;
use reth_db_api::{tables, transaction::DbTx};
use reth_downloaders::{
bodies::bodies::BodiesDownloaderBuilder,
file_client::{ChunkedFileReader, FileClient, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE},
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
};
use reth_evm::ConfigureEvm;
use reth_network_p2p::{
bodies::downloader::BodyDownloader,
headers::downloader::{HeaderDownloader, SyncTarget},
};
use reth_node_api::BlockTy;
use reth_node_events::node::NodeEvent;
use reth_provider::{
providers::ProviderNodeTypes, BlockNumReader, HeaderProvider, ProviderError, ProviderFactory,
StageCheckpointReader,
};
use reth_prune::PruneModes;
use reth_stages::{prelude::*, Pipeline, StageId, StageSet};
use reth_static_file::StaticFileProducer;
use std::{path::Path, sync::Arc};
use tokio::sync::watch;
use tracing::{debug, error, info};
/// Configuration for importing blocks from RLP files.
#[derive(Debug, Clone, Default)]
pub struct ImportConfig {
/// Disables stages that require state.
pub no_state: bool,
/// Chunk byte length to read from file.
pub chunk_len: Option<u64>,
}
/// Result of an import operation.
#[derive(Debug)]
pub struct ImportResult {
/// Total number of blocks decoded from the file.
pub total_decoded_blocks: usize,
/// Total number of transactions decoded from the file.
pub total_decoded_txns: usize,
/// Total number of blocks imported into the database.
pub total_imported_blocks: usize,
/// Total number of transactions imported into the database.
pub total_imported_txns: usize,
}
impl ImportResult {
/// Returns true if all blocks and transactions were imported successfully.
pub fn is_complete(&self) -> bool {
self.total_decoded_blocks == self.total_imported_blocks &&
self.total_decoded_txns == self.total_imported_txns
}
}
/// Imports blocks from an RLP-encoded file into the database.
///
/// This function reads RLP-encoded blocks from a file in chunks and imports them
/// using the pipeline infrastructure. It's designed to be used both from the CLI
/// and from test code.
pub async fn import_blocks_from_file<N>(
path: &Path,
import_config: ImportConfig,
provider_factory: ProviderFactory<N>,
config: &Config,
executor: impl ConfigureEvm<Primitives = N::Primitives> + 'static,
consensus: Arc<
impl FullConsensus<N::Primitives, Error = reth_consensus::ConsensusError> + 'static,
>,
) -> eyre::Result<ImportResult>
where
N: ProviderNodeTypes,
{
if import_config.no_state {
info!(target: "reth::import", "Disabled stages requiring state");
}
debug!(target: "reth::import",
chunk_byte_len=import_config.chunk_len.unwrap_or(DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE),
"Chunking chain import"
);
info!(target: "reth::import", "Consensus engine initialized");
// open file
let mut reader = ChunkedFileReader::new(path, import_config.chunk_len).await?;
let provider = provider_factory.provider()?;
let init_blocks = provider.tx_ref().entries::<tables::HeaderNumbers>()?;
let init_txns = provider.tx_ref().entries::<tables::TransactionHashNumbers>()?;
drop(provider);
let mut total_decoded_blocks = 0;
let mut total_decoded_txns = 0;
let mut sealed_header = provider_factory
.sealed_header(provider_factory.last_block_number()?)?
.expect("should have genesis");
while let Some(file_client) =
reader.next_chunk::<BlockTy<N>>(consensus.clone(), Some(sealed_header)).await?
{
// create a new FileClient from chunk read from file
info!(target: "reth::import",
"Importing chain file chunk"
);
let tip = file_client.tip().ok_or(eyre::eyre!("file client has no tip"))?;
info!(target: "reth::import", "Chain file chunk read");
total_decoded_blocks += file_client.headers_len();
total_decoded_txns += file_client.total_transactions();
let (mut pipeline, events) = build_import_pipeline_impl(
config,
provider_factory.clone(),
&consensus,
Arc::new(file_client),
StaticFileProducer::new(provider_factory.clone(), PruneModes::default()),
import_config.no_state,
executor.clone(),
)?;
// override the tip
pipeline.set_tip(tip);
debug!(target: "reth::import", ?tip, "Tip manually set");
let latest_block_number =
provider_factory.get_stage_checkpoint(StageId::Finish)?.map(|ch| ch.block_number);
tokio::spawn(reth_node_events::node::handle_events(None, latest_block_number, events));
// Run pipeline
info!(target: "reth::import", "Starting sync pipeline");
tokio::select! {
res = pipeline.run() => res?,
_ = tokio::signal::ctrl_c() => {
info!(target: "reth::import", "Import interrupted by user");
break;
},
}
sealed_header = provider_factory
.sealed_header(provider_factory.last_block_number()?)?
.expect("should have genesis");
}
let provider = provider_factory.provider()?;
let total_imported_blocks = provider.tx_ref().entries::<tables::HeaderNumbers>()? - init_blocks;
let total_imported_txns =
provider.tx_ref().entries::<tables::TransactionHashNumbers>()? - init_txns;
let result = ImportResult {
total_decoded_blocks,
total_decoded_txns,
total_imported_blocks,
total_imported_txns,
};
if !result.is_complete() {
error!(target: "reth::import",
total_decoded_blocks,
total_imported_blocks,
total_decoded_txns,
total_imported_txns,
"Chain was partially imported"
);
} else {
info!(target: "reth::import",
total_imported_blocks,
total_imported_txns,
"Chain was fully imported"
);
}
Ok(result)
}
/// Builds import pipeline.
///
/// If configured to execute, all stages will run. Otherwise, only stages that don't require state
/// will run.
pub fn build_import_pipeline_impl<N, C, E>(
config: &Config,
provider_factory: ProviderFactory<N>,
consensus: &Arc<C>,
file_client: Arc<FileClient<BlockTy<N>>>,
static_file_producer: StaticFileProducer<ProviderFactory<N>>,
disable_exec: bool,
evm_config: E,
) -> eyre::Result<(Pipeline<N>, impl futures::Stream<Item = NodeEvent<N::Primitives>> + use<N, C, E>)>
where
N: ProviderNodeTypes,
C: FullConsensus<N::Primitives, Error = reth_consensus::ConsensusError> + 'static,
E: ConfigureEvm<Primitives = N::Primitives> + 'static,
{
if !file_client.has_canonical_blocks() {
eyre::bail!("unable to import non canonical blocks");
}
// Retrieve latest header found in the database.
let last_block_number = provider_factory.last_block_number()?;
let local_head = provider_factory
.sealed_header(last_block_number)?
.ok_or_else(|| ProviderError::HeaderNotFound(last_block_number.into()))?;
let mut header_downloader = ReverseHeadersDownloaderBuilder::new(config.stages.headers)
.build(file_client.clone(), consensus.clone())
.into_task();
// TODO: The pipeline should correctly configure the downloader on its own.
// Find the possibility to remove unnecessary pre-configuration.
header_downloader.update_local_head(local_head);
header_downloader.update_sync_target(SyncTarget::Tip(file_client.tip().unwrap()));
let mut body_downloader = BodiesDownloaderBuilder::new(config.stages.bodies)
.build(file_client.clone(), consensus.clone(), provider_factory.clone())
.into_task();
// TODO: The pipeline should correctly configure the downloader on its own.
// Find the possibility to remove unnecessary pre-configuration.
body_downloader
.set_download_range(file_client.min_block().unwrap()..=file_client.max_block().unwrap())
.expect("failed to set download range");
let (tip_tx, tip_rx) = watch::channel(B256::ZERO);
let max_block = file_client.max_block().unwrap_or(0);
let pipeline = Pipeline::builder()
.with_tip_sender(tip_tx)
// we want to sync all blocks the file client provides or 0 if empty
.with_max_block(max_block)
.with_fail_on_unwind(true)
.add_stages(
DefaultStages::new(
provider_factory.clone(),
tip_rx,
consensus.clone(),
header_downloader,
body_downloader,
evm_config,
config.stages.clone(),
PruneModes::default(),
None,
)
.builder()
.disable_all_if(&StageId::STATE_REQUIRED, || disable_exec),
)
.build(provider_factory, static_file_producer);
let events = pipeline.events().map(Into::into);
Ok((pipeline, events))
}

View File

@@ -10,7 +10,7 @@ use reth_era_downloader::{read_dir, EraClient, EraStream, EraStreamConfig};
use reth_era_utils as era;
use reth_etl::Collector;
use reth_fs_util as fs;
use reth_node_core::version::SHORT_VERSION;
use reth_node_core::version::version_metadata;
use reth_provider::StaticFileProviderFactory;
use reth_static_file_types::StaticFileSegment;
use std::{path::PathBuf, sync::Arc};
@@ -68,7 +68,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> ImportEraC
where
N: CliNodeTypes<ChainSpec = C::ChainSpec>,
{
info!(target: "reth::cli", "reth {} starting", SHORT_VERSION);
info!(target: "reth::cli", "reth {} starting", version_metadata().short_version);
let Environment { provider_factory, config, .. } = self.env.init::<N>(AccessRights::RW)?;

View File

@@ -1,14 +1,14 @@
//! Command that initializes the node from a genesis file.
use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs};
use alloy_consensus::Header;
use crate::common::{AccessRights, CliHeader, CliNodeTypes, Environment, EnvironmentArgs};
use alloy_consensus::BlockHeader as AlloyBlockHeader;
use alloy_primitives::{B256, U256};
use clap::Parser;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_db_common::init::init_from_state_dump;
use reth_node_api::NodePrimitives;
use reth_primitives_traits::SealedHeader;
use reth_primitives_traits::{BlockHeader, SealedHeader};
use reth_provider::{
BlockNumReader, DatabaseProviderFactory, StaticFileProviderFactory, StaticFileWriter,
};
@@ -72,7 +72,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateC
where
N: CliNodeTypes<
ChainSpec = C::ChainSpec,
Primitives: NodePrimitives<BlockHeader = alloy_consensus::Header>,
Primitives: NodePrimitives<BlockHeader: BlockHeader + CliHeader>,
>,
{
info!(target: "reth::cli", "Reth init-state starting");
@@ -85,7 +85,9 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateC
if self.without_evm {
// ensure header, total difficulty and header hash are provided
let header = self.header.ok_or_else(|| eyre::eyre!("Header file must be provided"))?;
let header = without_evm::read_header_from_file(header)?;
let header = without_evm::read_header_from_file::<
<N::Primitives as NodePrimitives>::BlockHeader,
>(header)?;
let header_hash =
self.header_hash.ok_or_else(|| eyre::eyre!("Header hash must be provided"))?;
@@ -103,7 +105,12 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateC
&provider_rw,
SealedHeader::new(header, header_hash),
total_difficulty,
|number| Header { number, ..Default::default() },
|number| {
let mut header =
<<N::Primitives as NodePrimitives>::BlockHeader>::default();
header.set_number(number);
header
},
)?;
// SAFETY: it's safe to commit static files, since in the event of a crash, they
@@ -112,7 +119,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateC
// Necessary to commit, so the header is accessible to provider_rw and
// init_state_dump
static_file_provider.commit()?;
} else if last_block_number > 0 && last_block_number < header.number {
} else if last_block_number > 0 && last_block_number < header.number() {
return Err(eyre::eyre!(
"Data directory should be empty when calling init-state with --without-evm-history."
));

View File

@@ -1,4 +1,4 @@
use alloy_consensus::{BlockHeader, Header};
use alloy_consensus::BlockHeader;
use alloy_primitives::{BlockNumber, B256, U256};
use alloy_rlp::Decodable;
use reth_codecs::Compact;
@@ -12,14 +12,16 @@ use reth_stages::{StageCheckpoint, StageId};
use reth_static_file_types::StaticFileSegment;
use std::{fs::File, io::Read, path::PathBuf};
use tracing::info;
/// Reads the header RLP from a file and returns the Header.
pub(crate) fn read_header_from_file(path: PathBuf) -> Result<Header, eyre::Error> {
pub(crate) fn read_header_from_file<H>(path: PathBuf) -> Result<H, eyre::Error>
where
H: Decodable,
{
let mut file = File::open(path)?;
let mut buf = Vec::new();
file.read_to_end(&mut buf)?;
let header = Header::decode(&mut &buf[..])?;
let header = H::decode(&mut &buf[..])?;
Ok(header)
}

View File

@@ -2,7 +2,7 @@ use futures::Future;
use reth_cli::chainspec::ChainSpecParser;
use reth_db::DatabaseEnv;
use reth_node_builder::{NodeBuilder, WithLaunchContext};
use std::{fmt, marker::PhantomData, sync::Arc};
use std::{fmt, sync::Arc};
/// A trait for launching a reth node with custom configuration strategies.
///
@@ -40,14 +40,12 @@ where
/// This struct adapts existing closures to work with the new [`Launcher`] trait,
/// maintaining backward compatibility with current node implementations while
/// enabling the transition to the more flexible trait-based approach.
pub struct FnLauncher<F, Fut> {
pub struct FnLauncher<F> {
/// The function to execute when launching the node
func: F,
/// Phantom data to track the future type
_result: PhantomData<Fut>,
}
impl<F, Fut> FnLauncher<F, Fut> {
impl<F> FnLauncher<F> {
/// Creates a new function launcher adapter.
///
/// Type parameters `C` and `Ext` help the compiler infer correct types
@@ -59,18 +57,23 @@ impl<F, Fut> FnLauncher<F, Fut> {
pub fn new<C, Ext>(func: F) -> Self
where
C: ChainSpecParser,
F: FnOnce(WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>, Ext) -> Fut,
F: AsyncFnOnce(
WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>,
Ext,
) -> eyre::Result<()>,
{
Self { func, _result: PhantomData }
Self { func }
}
}
impl<C, Ext, F, Fut> Launcher<C, Ext> for FnLauncher<F, Fut>
impl<C, Ext, F> Launcher<C, Ext> for FnLauncher<F>
where
C: ChainSpecParser,
Ext: clap::Args + fmt::Debug,
F: FnOnce(WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>, Ext) -> Fut,
Fut: Future<Output = eyre::Result<()>>,
F: AsyncFnOnce(
WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>,
Ext,
) -> eyre::Result<()>,
{
fn entrypoint(
self,

View File

@@ -13,7 +13,9 @@ pub mod config_cmd;
pub mod db;
pub mod download;
pub mod dump_genesis;
pub mod export_era;
pub mod import;
pub mod import_core;
pub mod import_era;
pub mod init_cmd;
pub mod init_state;
@@ -21,7 +23,7 @@ pub mod launcher;
pub mod node;
pub mod p2p;
pub mod prune;
pub mod recover;
pub mod re_execute;
pub mod stage;
#[cfg(feature = "arbitrary")]
pub mod test_vectors;

View File

@@ -59,7 +59,7 @@ pub struct NodeCommand<C: ChainSpecParser, Ext: clap::Args + fmt::Debug = NoArgs
/// - `HTTP_RPC_PORT`: default - `instance` + 1
/// - `WS_RPC_PORT`: default + `instance` * 2 - 2
/// - `IPC_PATH`: default + `-instance`
#[arg(long, value_name = "INSTANCE", global = true, value_parser = value_parser!(u16).range(..=200))]
#[arg(long, value_name = "INSTANCE", global = true, value_parser = value_parser!(u16).range(1..=200))]
pub instance: Option<u16>,
/// Sets all ports to unused, allowing the OS to choose random unused ports when sockets are
@@ -148,7 +148,7 @@ where
where
L: Launcher<C, Ext>,
{
tracing::info!(target: "reth::cli", version = ?version::SHORT_VERSION, "Starting reth");
tracing::info!(target: "reth::cli", version = ?version::version_metadata().short_version, "Starting reth");
let Self {
datadir,

View File

@@ -5,7 +5,7 @@ use reth_discv4::{DiscoveryUpdate, Discv4, Discv4Config};
use reth_discv5::{discv5::Event, Config, Discv5};
use reth_net_nat::NatResolver;
use reth_network_peers::NodeRecord;
use std::{net::SocketAddr, str::FromStr};
use std::net::SocketAddr;
use tokio::select;
use tokio_stream::StreamExt;
use tracing::info;
@@ -13,9 +13,9 @@ use tracing::info;
/// Start a discovery only bootnode.
#[derive(Parser, Debug)]
pub struct Command {
/// Listen address for the bootnode (default: ":30301").
#[arg(long, default_value = ":30301")]
pub addr: String,
/// Listen address for the bootnode (default: "0.0.0.0:30301").
#[arg(long, default_value = "0.0.0.0:30301")]
pub addr: SocketAddr,
/// Generate a new node key and save it to the specified file.
#[arg(long, default_value = "")]
@@ -39,15 +39,13 @@ impl Command {
pub async fn execute(self) -> eyre::Result<()> {
info!("Bootnode started with config: {:?}", self);
let sk = reth_network::config::rng_secret_key();
let socket_addr = SocketAddr::from_str(&self.addr)?;
let local_enr = NodeRecord::from_secret_key(socket_addr, &sk);
let local_enr = NodeRecord::from_secret_key(self.addr, &sk);
let config = Discv4Config::builder().external_ip_resolver(Some(self.nat)).build();
let (_discv4, mut discv4_service) =
Discv4::bind(socket_addr, local_enr, sk, config).await?;
let (_discv4, mut discv4_service) = Discv4::bind(self.addr, local_enr, sk, config).await?;
info!("Started discv4 at address:{:?}", socket_addr);
info!("Started discv4 at address:{:?}", self.addr);
let mut discv4_updates = discv4_service.update_stream();
discv4_service.spawn();
@@ -57,7 +55,7 @@ impl Command {
if self.v5 {
info!("Starting discv5");
let config = Config::builder(socket_addr).build();
let config = Config::builder(self.addr).build();
let (_discv5, updates, _local_enr_discv5) = Discv5::start(&sk, config).await?;
discv5_updates = Some(updates);
};

View File

@@ -2,6 +2,7 @@
use std::{path::PathBuf, sync::Arc};
use crate::common::CliNodeTypes;
use alloy_eips::BlockHashOrNumber;
use backon::{ConstantBuilder, Retryable};
use clap::{Parser, Subcommand};
@@ -9,124 +10,44 @@ use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_cli_util::{get_secret_key, hash_or_num_value_parser};
use reth_config::Config;
use reth_network::{BlockDownloaderProvider, NetworkConfigBuilder, NetworkPrimitives};
use reth_network::{BlockDownloaderProvider, NetworkConfigBuilder};
use reth_network_p2p::bodies::client::BodiesClient;
use reth_node_core::{
args::{DatabaseArgs, DatadirArgs, NetworkArgs},
args::{DatadirArgs, NetworkArgs},
utils::get_single_header,
};
pub mod bootnode;
mod rlpx;
pub mod rlpx;
/// `reth p2p` command
#[derive(Debug, Parser)]
pub struct Command<C: ChainSpecParser> {
/// The path to the configuration file to use.
#[arg(long, value_name = "FILE", verbatim_doc_comment)]
config: Option<PathBuf>,
/// The chain this node is running.
///
/// Possible values are either a built-in chain or the path to a chain specification file.
#[arg(
long,
value_name = "CHAIN_OR_PATH",
long_help = C::help_message(),
default_value = C::SUPPORTED_CHAINS[0],
value_parser = C::parser()
)]
chain: Arc<C::ChainSpec>,
/// The number of retries per request
#[arg(long, default_value = "5")]
retries: usize,
#[command(flatten)]
network: NetworkArgs,
#[command(flatten)]
datadir: DatadirArgs,
#[command(flatten)]
db: DatabaseArgs,
#[command(subcommand)]
command: Subcommands,
}
/// `reth p2p` subcommands
#[derive(Subcommand, Debug)]
pub enum Subcommands {
/// Download block header
Header {
/// The header number or hash
#[arg(value_parser = hash_or_num_value_parser)]
id: BlockHashOrNumber,
},
/// Download block body
Body {
/// The block number or hash
#[arg(value_parser = hash_or_num_value_parser)]
id: BlockHashOrNumber,
},
// RLPx utilities
Rlpx(rlpx::Command),
command: Subcommands<C>,
}
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>> Command<C> {
/// Execute `p2p` command
pub async fn execute<N: NetworkPrimitives>(self) -> eyre::Result<()> {
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain());
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
// Load configuration
let mut config = Config::from_path(&config_path).unwrap_or_default();
config.peers.trusted_nodes.extend(self.network.trusted_peers.clone());
if config.peers.trusted_nodes.is_empty() && self.network.trusted_only {
eyre::bail!(
"No trusted nodes. Set trusted peer with `--trusted-peer <enode record>` or set `--trusted-only` to `false`"
)
}
config.peers.trusted_nodes_only = self.network.trusted_only;
let default_secret_key_path = data_dir.p2p_secret();
let secret_key_path =
self.network.p2p_secret_key.clone().unwrap_or(default_secret_key_path);
let p2p_secret_key = get_secret_key(&secret_key_path)?;
let rlpx_socket = (self.network.addr, self.network.port).into();
let boot_nodes = self.chain.bootnodes().unwrap_or_default();
let net = NetworkConfigBuilder::<N>::new(p2p_secret_key)
.peer_config(config.peers_config_with_basic_nodes_from_file(None))
.external_ip_resolver(self.network.nat)
.disable_discv4_discovery_if(self.chain.chain().is_optimism())
.boot_nodes(boot_nodes.clone())
.apply(|builder| {
self.network.discovery.apply_to_builder(builder, rlpx_socket, boot_nodes)
})
.build_with_noop_provider(self.chain)
.manager()
.await?;
let network = net.handle().clone();
tokio::task::spawn(net);
let fetch_client = network.fetch_client().await?;
let retries = self.retries.max(1);
let backoff = ConstantBuilder::default().with_max_times(retries);
pub async fn execute<N: CliNodeTypes<ChainSpec = C::ChainSpec>>(self) -> eyre::Result<()> {
match self.command {
Subcommands::Header { id } => {
Subcommands::Header { args, id } => {
let handle = args.launch_network::<N>().await?;
let fetch_client = handle.fetch_client().await?;
let backoff = args.backoff();
let header = (move || get_single_header(fetch_client.clone(), id))
.retry(backoff)
.notify(|err, _| println!("Error requesting header: {err}. Retrying..."))
.await?;
println!("Successfully downloaded header: {header:?}");
}
Subcommands::Body { id } => {
Subcommands::Body { args, id } => {
let handle = args.launch_network::<N>().await?;
let fetch_client = handle.fetch_client().await?;
let backoff = args.backoff();
let hash = match id {
BlockHashOrNumber::Hash(hash) => hash,
BlockHashOrNumber::Number(number) => {
@@ -161,6 +82,9 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>
Subcommands::Rlpx(command) => {
command.execute().await?;
}
Subcommands::Bootnode(command) => {
command.execute().await?;
}
}
Ok(())
@@ -170,6 +94,136 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>
impl<C: ChainSpecParser> Command<C> {
/// Returns the underlying chain being used to run this command
pub fn chain_spec(&self) -> Option<&Arc<C::ChainSpec>> {
Some(&self.chain)
match &self.command {
Subcommands::Header { args, .. } => Some(&args.chain),
Subcommands::Body { args, .. } => Some(&args.chain),
Subcommands::Rlpx(_) => None,
Subcommands::Bootnode(_) => None,
}
}
}
/// `reth p2p` subcommands
#[derive(Subcommand, Debug)]
pub enum Subcommands<C: ChainSpecParser> {
/// Download block header
Header {
#[command(flatten)]
args: DownloadArgs<C>,
/// The header number or hash
#[arg(value_parser = hash_or_num_value_parser)]
id: BlockHashOrNumber,
},
/// Download block body
Body {
#[command(flatten)]
args: DownloadArgs<C>,
/// The block number or hash
#[arg(value_parser = hash_or_num_value_parser)]
id: BlockHashOrNumber,
},
// RLPx utilities
Rlpx(rlpx::Command),
/// Bootnode command
Bootnode(bootnode::Command),
}
#[derive(Debug, Clone, Parser)]
pub struct DownloadArgs<C: ChainSpecParser> {
/// The number of retries per request
#[arg(long, default_value = "5")]
retries: usize,
#[command(flatten)]
network: NetworkArgs,
#[command(flatten)]
datadir: DatadirArgs,
/// The path to the configuration file to use.
#[arg(long, value_name = "FILE", verbatim_doc_comment)]
config: Option<PathBuf>,
/// The chain this node is running.
///
/// Possible values are either a built-in chain or the path to a chain specification file.
#[arg(
long,
value_name = "CHAIN_OR_PATH",
long_help = C::help_message(),
default_value = C::SUPPORTED_CHAINS[0],
value_parser = C::parser()
)]
chain: Arc<C::ChainSpec>,
}
impl<C: ChainSpecParser> DownloadArgs<C> {
/// Creates and spawns the network and returns the handle.
pub async fn launch_network<N>(
&self,
) -> eyre::Result<reth_network::NetworkHandle<N::NetworkPrimitives>>
where
C::ChainSpec: EthChainSpec + Hardforks + EthereumHardforks + Send + Sync + 'static,
N: CliNodeTypes<ChainSpec = C::ChainSpec>,
{
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain());
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
// Load configuration
let mut config = Config::from_path(&config_path).unwrap_or_default();
config.peers.trusted_nodes.extend(self.network.trusted_peers.clone());
if config.peers.trusted_nodes.is_empty() && self.network.trusted_only {
eyre::bail!(
"No trusted nodes. Set trusted peer with `--trusted-peer <enode record>` or set `--trusted-only` to `false`"
)
}
config.peers.trusted_nodes_only = self.network.trusted_only;
let default_secret_key_path = data_dir.p2p_secret();
let secret_key_path =
self.network.p2p_secret_key.clone().unwrap_or(default_secret_key_path);
let p2p_secret_key = get_secret_key(&secret_key_path)?;
let rlpx_socket = (self.network.addr, self.network.port).into();
let boot_nodes = self.chain.bootnodes().unwrap_or_default();
let net = NetworkConfigBuilder::<N::NetworkPrimitives>::new(p2p_secret_key)
.peer_config(config.peers_config_with_basic_nodes_from_file(None))
.external_ip_resolver(self.network.nat)
.boot_nodes(boot_nodes.clone())
.apply(|builder| {
self.network.discovery.apply_to_builder(builder, rlpx_socket, boot_nodes)
})
.build_with_noop_provider(self.chain.clone())
.manager()
.await?;
let handle = net.handle().clone();
tokio::task::spawn(net);
Ok(handle)
}
pub fn backoff(&self) -> ConstantBuilder {
ConstantBuilder::default().with_max_times(self.retries.max(1))
}
}
#[cfg(test)]
mod tests {
use super::*;
use reth_ethereum_cli::chainspec::EthereumChainSpecParser;
#[test]
fn parse_header_cmd() {
let _args: Command<EthereumChainSpecParser> =
Command::parse_from(["reth", "header", "--chain", "mainnet", "1000"]);
}
#[test]
fn parse_body_cmd() {
let _args: Command<EthereumChainSpecParser> =
Command::parse_from(["reth", "body", "--chain", "mainnet", "1000"]);
}
}

View File

@@ -0,0 +1,222 @@
//! Re-execute blocks from database in parallel.
use crate::common::{
AccessRights, CliComponentsBuilder, CliNodeComponents, CliNodeTypes, Environment,
EnvironmentArgs,
};
use alloy_consensus::{transaction::TxHashRef, BlockHeader, TxReceipt};
use clap::Parser;
use eyre::WrapErr;
use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_consensus::FullConsensus;
use reth_evm::{execute::Executor, ConfigureEvm};
use reth_primitives_traits::{format_gas_throughput, BlockBody, GotExpected};
use reth_provider::{
BlockNumReader, BlockReader, ChainSpecProvider, DatabaseProviderFactory, ReceiptProvider,
StaticFileProviderFactory, TransactionVariant,
};
use reth_revm::database::StateProviderDatabase;
use reth_stages::stages::calculate_gas_used_from_headers;
use std::{
sync::Arc,
time::{Duration, Instant},
};
use tokio::{sync::mpsc, task::JoinSet};
use tracing::*;
/// `reth re-execute` command
///
/// Re-execute blocks in parallel to verify historical sync correctness.
#[derive(Debug, Parser)]
pub struct Command<C: ChainSpecParser> {
#[command(flatten)]
env: EnvironmentArgs<C>,
/// The height to start at.
#[arg(long, default_value = "1")]
from: u64,
/// The height to end at. Defaults to the latest block.
#[arg(long)]
to: Option<u64>,
/// Number of tasks to run in parallel
#[arg(long, default_value = "10")]
num_tasks: u64,
}
impl<C: ChainSpecParser> Command<C> {
/// Returns the underlying chain being used to run this command
pub fn chain_spec(&self) -> Option<&Arc<C::ChainSpec>> {
Some(&self.env.chain)
}
}
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>> Command<C> {
/// Execute `re-execute` command
pub async fn execute<N>(self, components: impl CliComponentsBuilder<N>) -> eyre::Result<()>
where
N: CliNodeTypes<ChainSpec = C::ChainSpec>,
{
let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RO)?;
let provider = provider_factory.database_provider_ro()?;
let components = components(provider_factory.chain_spec());
let min_block = self.from;
let max_block = self.to.unwrap_or(provider.best_block_number()?);
let total_blocks = max_block - min_block;
let total_gas = calculate_gas_used_from_headers(
&provider_factory.static_file_provider(),
min_block..=max_block,
)?;
let blocks_per_task = total_blocks / self.num_tasks;
let db_at = {
let provider_factory = provider_factory.clone();
move |block_number: u64| {
StateProviderDatabase(
provider_factory.history_by_block_number(block_number).unwrap(),
)
}
};
let (stats_tx, mut stats_rx) = mpsc::unbounded_channel();
let mut tasks = JoinSet::new();
for i in 0..self.num_tasks {
let start_block = min_block + i * blocks_per_task;
let end_block =
if i == self.num_tasks - 1 { max_block } else { start_block + blocks_per_task };
// Spawn thread executing blocks
let provider_factory = provider_factory.clone();
let evm_config = components.evm_config().clone();
let consensus = components.consensus().clone();
let db_at = db_at.clone();
let stats_tx = stats_tx.clone();
tasks.spawn_blocking(move || {
let mut executor = evm_config.batch_executor(db_at(start_block - 1));
for block in start_block..end_block {
let block = provider_factory
.recovered_block(block.into(), TransactionVariant::NoHash)?
.unwrap();
let result = executor.execute_one(&block)?;
if let Err(err) = consensus
.validate_block_post_execution(&block, &result)
.wrap_err_with(|| format!("Failed to validate block {}", block.number()))
{
let correct_receipts =
provider_factory.receipts_by_block(block.number().into())?.unwrap();
for (i, (receipt, correct_receipt)) in
result.receipts.iter().zip(correct_receipts.iter()).enumerate()
{
if receipt != correct_receipt {
let tx_hash = block.body().transactions()[i].tx_hash();
error!(
?receipt,
?correct_receipt,
index = i,
?tx_hash,
"Invalid receipt"
);
let expected_gas_used = correct_receipt.cumulative_gas_used() -
if i == 0 {
0
} else {
correct_receipts[i - 1].cumulative_gas_used()
};
let got_gas_used = receipt.cumulative_gas_used() -
if i == 0 {
0
} else {
result.receipts[i - 1].cumulative_gas_used()
};
if got_gas_used != expected_gas_used {
let mismatch = GotExpected {
expected: expected_gas_used,
got: got_gas_used,
};
error!(number=?block.number(), ?mismatch, "Gas usage mismatch");
return Err(err);
}
} else {
continue;
}
}
return Err(err);
}
let _ = stats_tx.send(block.gas_used());
// Reset DB once in a while to avoid OOM
if executor.size_hint() > 1_000_000 {
executor = evm_config.batch_executor(db_at(block.number()));
}
}
eyre::Ok(())
});
}
let instant = Instant::now();
let mut total_executed_blocks = 0;
let mut total_executed_gas = 0;
let mut last_logged_gas = 0;
let mut last_logged_blocks = 0;
let mut last_logged_time = Instant::now();
let mut interval = tokio::time::interval(Duration::from_secs(10));
loop {
tokio::select! {
Some(gas_used) = stats_rx.recv() => {
total_executed_blocks += 1;
total_executed_gas += gas_used;
}
result = tasks.join_next() => {
if let Some(result) = result {
if matches!(result, Err(_) | Ok(Err(_))) {
error!(?result);
return Err(eyre::eyre!("Re-execution failed: {result:?}"));
}
} else {
break;
}
}
_ = interval.tick() => {
let blocks_executed = total_executed_blocks - last_logged_blocks;
let gas_executed = total_executed_gas - last_logged_gas;
if blocks_executed > 0 {
let progress = 100.0 * total_executed_gas as f64 / total_gas as f64;
info!(
throughput=?format_gas_throughput(gas_executed, last_logged_time.elapsed()),
progress=format!("{progress:.2}%"),
"Executed {blocks_executed} blocks"
);
}
last_logged_blocks = total_executed_blocks;
last_logged_gas = total_executed_gas;
last_logged_time = Instant::now();
}
}
}
info!(
start_block = min_block,
end_block = max_block,
throughput=?format_gas_throughput(total_executed_gas, instant.elapsed()),
"Re-executed successfully"
);
Ok(())
}
}

View File

@@ -1,45 +0,0 @@
//! `reth recover` command.
use crate::common::CliNodeTypes;
use clap::{Parser, Subcommand};
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_cli::chainspec::ChainSpecParser;
use reth_cli_runner::CliContext;
use std::sync::Arc;
mod storage_tries;
/// `reth recover` command
#[derive(Debug, Parser)]
pub struct Command<C: ChainSpecParser> {
#[command(subcommand)]
command: Subcommands<C>,
}
/// `reth recover` subcommands
#[derive(Subcommand, Debug)]
pub enum Subcommands<C: ChainSpecParser> {
/// Recover the node by deleting dangling storage tries.
StorageTries(storage_tries::Command<C>),
}
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C> {
/// Execute `recover` command
pub async fn execute<N: CliNodeTypes<ChainSpec = C::ChainSpec>>(
self,
ctx: CliContext,
) -> eyre::Result<()> {
match self.command {
Subcommands::StorageTries(command) => command.execute::<N>(ctx).await,
}
}
}
impl<C: ChainSpecParser> Command<C> {
/// Returns the underlying chain being used to run this command
pub fn chain_spec(&self) -> Option<&Arc<C::ChainSpec>> {
match &self.command {
Subcommands::StorageTries(command) => command.chain_spec(),
}
}
}

Some files were not shown because too many files have changed in this diff Show More