erigontech / erigontech/erigon
rpc: eth_getLogs processes the rest of a block with a stale or nil header
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
In `getLogsV3` (`rpc/jsonrpc/eth_receipts.go:380`, `main` at 52b071b5d8) a nil header skips only the current txNum:
```go
if blockNumChanged {
if header, err = api._blockReader.HeaderByNumber(ctx, tx, blockNum); err != nil {
return nil, err
}
if header == nil {
log.Warn("[rpc] header is nil", "blockNum", blockNum)
continue
}
}
```
The iterator reports `blockNumChanged` only for the first txNum of a block, so the remaining txNums of that block are processed with whatever `header` holds:
- If an earlier block in the range loaded a header, its hash and time are used: logs come back stamped with the previous block, and `TryGetCachedReceipt` looks up receipts under the wrong block hash.
- If the nil header is the first one in the range, `header` is still nil and `header.Hash()` panics; the call fails with "method handler crashed".
This looks reachable on a standalone rpcdaemon when a block is pruned or reorged away while the request runs. Found in the review of #23963.
Fix: when the header is nil, skip every txNum of that block (for example, remember the skipped block number and continue until it changes), or return an error.
Contributor guide
Research direction
Start in rpc/jsonrpc/eth_receipts.go at getLogsV3 around line 380 and inspect how the iterator reports blockNumChanged. Trace the nil-header path across all transaction numbers in a block. Done means a missing header cannot reuse a stale header or cause a nil dereference: the block is skipped entirely or the request returns an error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, blockchain
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100