Skip to content

op-reth: test the eth_getLogs errors for a range past the head or over pruned receipts - #23448

Draft
einar-oplabs wants to merge 1 commit into
einar/23400-txpool-min-priority-feefrom
einar/23401-getlogs-errors
Draft

einar-oplabs wants to merge 1 commit into
einar/23400-txpool-min-priority-feefrom
einar/23401-getlogs-errors

Conversation

@einar-oplabs

Copy link
Copy Markdown
Contributor

reth 2.6 turns two eth_getLogs answers that were arrays into errors: a fromBlock past the head gets -32602 invalid block range params (reth#26891) and a range whose receipts the node pruned gets 4444 pruned history unavailable (reth#27002), where reth 2.5.2 answers [] and a silently partial array. Nothing in the tree pinned either code; an indexer that polls lastSeen + 1 or reads a pruned range sees the change with the bump (#23046).

What the tests cover

Node-integration tests in rust/op-reth/crates/node/tests/it/get_logs_errors.rs (a file of its own rather than rpc.rs: the fixture builds a chain through the engine API and prunes it, which the one-call tests in rpc.rs do not need). The fixture launches an op-reth node with --prune.receipts.before=4, --prune.block-interval=1 and --prune.minimum-distance=1, v1 storage (receipts live in the database, which the pruner trims block by block; under v2 a short chain's receipts share one static file that the pruner only drops whole), zero-length RPC caches (the cache would otherwise keep serving the receipts the pruner removed, as it does for the newest blocks of a real chain), builds six blocks and waits for the receipts of block 3 to be gone. Block 6 carries a contract creation whose init code emits one LOG0, so a served range has a log to answer with.

test request reth 2.6 (#23046) develop (reth 2.5.2)
from_block_past_the_head_is_rejected fromBlock = 7 on a 6-block chain -32602 invalid block range params []
range_over_pruned_receipts_is_rejected fromBlock = 1, toBlock = 6, receipts of 1-3 pruned 4444 pruned history unavailable the single log of block 6
range_within_kept_receipts_is_served fromBlock = 4, toBlock = 6 the single log of block 6 the single log of block 6

Matrix: transport {http, ws}, as rstest cases on each test. Six cells in all.

engine_driver.rs is the EngineDriver of payload_during_persistence.rs (#23436) moved into a module both tests use, with one addition: build_block_with takes sequencer transactions to put in the block after its L1 info transaction, and spare_signer hands out the funded account the driver never signs with.

Skipped cells

The four cells of from_block_past_the_head_is_rejected and range_over_pruned_receipts_is_rejected are #[ignore]d naming #23401: they assert the reth 2.6 codes and fail on develop with develop's answers. The ignore reasons say what develop answers and that the ignore comes off with the reth 2.6 bump. The two range_within_kept_receipts_is_served cells run in CI (op-reth-integration-tests).

Local verification

Shared cargo target, CARGO_INCREMENTAL=0 (the first run hit a rustc ICE in incremental hash verification).

develop's reth (this branch), all six cells forced to run:

cd rust && cargo test -p reth-optimism-node --test it get_logs_errors -- --include-ignored --test-threads=1
test get_logs_errors::from_block_past_the_head_is_rejected::case_1_http ... FAILED
test get_logs_errors::from_block_past_the_head_is_rejected::case_2_ws ... FAILED
test get_logs_errors::range_over_pruned_receipts_is_rejected::case_1_http ... FAILED
test get_logs_errors::range_over_pruned_receipts_is_rejected::case_2_ws ... FAILED
test get_logs_errors::range_within_kept_receipts_is_served::case_1_http ... ok
test get_logs_errors::range_within_kept_receipts_is_served::case_2_ws ... ok
test result: FAILED. 2 passed; 4 failed; 0 ignored

with the develop failures being, verbatim:

expected error -32602 `invalid block range params`, got Ok([])
expected error 4444 `pruned history unavailable`, got Ok([Log { inner: Log { address: 0x8464135c8f25da09e49bc8782676a84730c318bc, data: LogData { topics: [], data: 0x } }, block_hash: Some(0x…), block_number: Some(6), block_timestamp: Some(6), transaction_hash: Some(0x…), transaction_index: Some(1), log_index: Some(0), removed: false }])

develop's reth, the default run (what CI runs): test result: ok. 2 passed; 0 failed; 4 ignored.

reth 2.6: the two new files, the main.rs module lines and the rstest dev-dependency copied onto a detached checkout of #23046's head (93d9ec9), same command:

test result: ok. 6 passed; 0 failed; 0 ignored

cargo clippy -p reth-optimism-node --all-targets: no warnings. cargo +nightly-2026-08-22 fmt -p reth-optimism-node run.

Who calls L2 eth_getLogs

  • op-node: no. Its only FilterLogs calls are the abigen bindings under op-node/bindings/; L1 receipts are fetched by block hash through op-service/sources. kona-node: no eth_getLogs / get_logs call in rust/kona.
  • Ops, from the local checkouts of k8s, infrastructure-services and devnets: the only L2 caller is op-benchmark's interop sweep (op-benchmark/internal/interop/{producer,confirm}.go), which polls eth_getLogs from its last seen block to the head on the messenger and inbox, and would hit -32602 only if it asked past the head. deposit-eth-monitor queries logs by block hash on L1, op-monitorism's deployed monitors (global_events, liveness_expiration) read L1, and op-dispute-mon/dispute-explorer read the L1 dispute game factory. The public L2 RPCs expose eth_getLogs through proxyd (kustomize/proxyd/*/proxyd-l2-*), so external indexers reach op-reth there; none of ours polls L2 logs.

Corrections to the issue text

  • The issue names init-state --without-ovm as a second source of 4444. That path exists on develop already: it comes from earliest_block_number() (EIP-4444 history expiry, the lowest static-file block), which reth 2.5.2 checks too. What the bump adds is the 4444 for receipts missing inside the served range (ReceiptsUnavailable), which is what the test drives through --prune.receipts.
  • With no toBlock, reth 2.6 answers fromBlock > head with invalid block range params (the range resolves to fromBlock > toBlock = head), not with the block range extends beyond current head block message; that message needs an explicit toBlock past the head, which both versions already reject.

Stacked on #23444, #23443, #23440, #23438, #23436, #23431, #23427, #23421 and #23418.

Closes #23401

🤖 Generated with Claude Code

@einar-oplabs einar-oplabs self-assigned this Oct 15, 2026
@einar-oplabs
einar-oplabs force-pushed the einar/23400-txpool-min-priority-fee branch from dd0ae8e to 84f267f Compare October 15, 2026 16:01
…r pruned receipts

reth 2.6 answers -32602 for a fromBlock past the head (reth#26891) and 4444
for a range whose receipts are pruned (reth#27002), where reth 2.5.2 answers
an empty or silently partial array. Pin both codes and a served range over
http and ws in node-integration tests. The pruned fixture drives reth's own
receipts pruner through PruningArgs, with v1 storage so receipts are trimmed
block by block and a zero-length RPC cache so the cache does not mask the
pruning. The two error tests are ignored until the reth 2.6 bump, naming
#23401. The engine driver of the persistence test moves into a shared module
that can put extra sequencer transactions into a block.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@einar-oplabs
einar-oplabs force-pushed the einar/23401-getlogs-errors branch from 39b9c31 to e7565f8 Compare October 15, 2026 16:01

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant