erigontech / erigontech/erigon
txnprovider/txpool: refresh stale state views after OnNewBlock overtakes admission
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
## Problem
`AddLocalTxns` and `processRemoteTxns` open their core-state transaction and cache view before acquiring `p.lock`. An admission request can therefore:
1. obtain a view of state version N;
2. wait for `p.lock`;
3. be overtaken by `OnNewBlock`, which applies state version N+1 and completes sender re-evaluation;
4. acquire the lock and mutate the pool using the old view.
This can bypass validation that depends on current sender state. For example, if the new block installs EIP-7702 delegation, the old view still reports empty code and several contiguous transactions can be admitted after the delegated-sender cleanup has already run. They enter `pending`, so the existing fallback that re-evaluates untouched queued senders on later blocks does not revisit them.
Pool reload has the same ordering risk: `start` opens `coreTx` before `fromDB` acquires the pool lock.
## Reproduction
A deterministic test can use a blocking cache or DB wrapper:
1. initialize an EOA at nonce 0 with empty code;
2. start local admission, remote admission, or pool reload and pause after it opens the old state view;
3. update the account to nonce 1 with delegation code and let `OnNewBlock` finish;
4. release the paused operation with transactions at nonces 0, 1, and 2.
Expected: only nonce 1 remains.
Actual:
- local admission returns `Success` for all three transactions;
- remote admission retains all three transactions;
- reload restores all three transactions;
- the transactions are pending rather than queued.
The stale pending chain also survives a following block that does not change this sender.
## Suggested direction
Establish a consistent ordering between the state view and `p.lock`. If `OnNewBlock` advances while admission or reload is waiting for the lock, reopen or retry the state transaction and cache view before mutating the pool.
Cover local admission, remote admission, and pool reload with deterministic regression tests.
## Context
Found while reviewing #23294. That PR handles steady-state delegated senders and normal state-transition ordering; this race is a broader synchronization concern and should be handled separately.
#20998 describes a related re-evaluation refactor, but it does not prevent an operation from mutating the pool through an older state view after `OnNewBlock` completes.
Contributor guide
Assessment
This issue has not been assessed yet.