erigontech / erigontech/erigon
cl/epbs: retain fallback bids after production-time eviction
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
## Problem
`EpbsPool.HighestBids` stores only one bid for each `(slot, parent block hash, parent block root)` market. Bid admission ignores values that do not exceed the current winner, while a newly accepted winner replaces and discards the previous one.
PR #23583 validates the selected external bid with the canonical block transition. If that transition reports a deterministic bid-validation failure, block production evicts the bid and safely falls back to the self-build. This protects proposal liveness, but the local bid market is then usually empty:
- Previously accepted record-high bids were discarded when a higher bid replaced them.
- Their builders remain in `seenCache`, so those bids cannot be accepted again for the slot.
- Lower bids ignored after the winner arrived are available only if another builder gossips them again after eviction.
A bad top bid can therefore suppress otherwise usable external bids and forfeit builder revenue for the slot. See the [review discussion](https://github.com/erigontech/erigon/pull/23583#discussion_r3885629529).
Clearing the rejected builder from `seenCache` is not a complete solution. It weakens duplicate-bid protection and does not restore bids from other builders that the node already discarded.
## Desired behavior
Retain a bounded, value-ordered set of fully validated candidates for each bid market. When production rejects the winner, remove or mark only that candidate and expose the next valid bid without compromising the self-build fallback.
The design should:
- bound candidates and validation work to preserve DoS resistance;
- keep selection and eviction atomic when gossip stores a concurrent replacement;
- prevent a rejected candidate from being selected again;
- preserve the self-build as the final liveness fallback;
- define whether production may try a bounded runner-up within the current request or only expose it to a later retry;
- keep cache lifetime and memory use bounded by the relevant slots;
- cover winner replacement, eviction, concurrent admission, and runner-up selection with regression tests.
Contributor guide
Assessment
This issue has not been assessed yet.