feat: fast confirmation rule - #8837
Conversation
Summary of ChangesHello @nazarhussain, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant new feature: an assumption-based Fast Confirmation Rule (FCR) for the beacon node. The primary goal is to accelerate the confirmation of blocks by implementing a sophisticated algorithm that evaluates various network and validator-related metrics. This involves deep integration into the existing fork choice mechanism, providing a new configurable option for users, and updating how 'safe' blocks are identified within the system. The changes are comprehensive, spanning core logic, configuration, state management, and observability. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a fast confirmation rule, an experimental feature designed to provide faster block confirmations. The changes are comprehensive, including the core logic in a new FastConfirmationRule class, configuration options to enable it, and integration into the existing ForkChoice and safe block determination logic. The implementation appears to align well with the provided specification. My review includes a couple of minor suggestions to enhance code quality and readability.
Performance Report✔️ no performance regression detected Full benchmark results
|
|
Hey @nazarhussain, we chatted about running FCR tests at the meeting today. This is how you can generate these tests:
This will write the tests to Note: There is currently a failing test with Gloas, which sort of breaks test generation. So you could generate the reference tests for a specific fork instead, something like the following. After Mikhail fixes the issue, you can use the command above. |
10a6c01 to
8a1a41f
Compare
77c0c84 to
47f2f6b
Compare
|
@lodekeeper Here are the followup issues #9438 #9437 |
|
@lodekeeper If all points are addressed please approve the RP. :) |
|
Walking through my points against the current head (`9a0c038` / `500226c2d8` "as per feedback"): Inline — all resolved in `500226c2`:
Issue-level — deferred but tracked:
From my review surface every point I raised is addressed or tracked. One caveat I want to repeat from the original review (`pullrequestreview-4395743466`): the bugs-class reviewer timed out and I flagged "recommend a focused bug-class pass before merge" — that part hasn't happened yet, just noting. On the formal APPROVE — I'm staying with a COMMENTED review here (that's the lodekeeper pattern across PRs #9350 / #9332 / #9317 / #9430 / #9334). The merge gate is better held by maintainer review — Nico's "did you confirm on mainnet? consistent with Prysm?" question + twoeths' `onFastConfirmation` integration discussion are the active ones from my side. |
https://ethpandaops.io/posts/fcr-simulator/ has some great data points |
lodekeeper
left a comment
There was a problem hiding this comment.
All concerns from my multi-persona review (#8837 (review)) are now either addressed in-PR or tracked as follow-ups:
Addressed in-PR (commit 500226c2 "update code as per feedback" + a8559a53 "align FCR chain safety check for ethereum/consensus-specs#5288"):
- All 14 inline wisdom items (loop renames, tuple-keys removal,
BalanceSourceKey,ensureVoteMapsdedup,FastConfirmationDecisionReasonenum,SAFETY_THRESHOLD_UNREACHABLE, optional-chaining drop,FCR*aliases removed, deaddecision.stopremoved, passthrough removed, spec link on= 5, FCR warning meta, null instead of 0 for missing block,EndTimertype alias) - Spec alignment with ethereum/consensus-specs#5288 (FCR chain safety check using
get_checkpoint_for_block) - DA #1 (public API): superseded by #9439 which adds the standardized
fast_confirmationSSE event per ethereum/beacon-APIs#598 + #611 and removes the Lodestar-namespaced polling endpoint
Tracked as follow-up issues (both opened by @nazarhussain 2026-06-01):
- #9437 — DA #2 / A2: isolate FCR state from core fork-choice store
- #9438 — A1: narrow state provider boundary for FCR
Minor remaining (non-blocker):
getTrackedVotesCountis a per-slot linear scan; fine at current call frequency.
CI green incl. spec tests. LGTM.
🤖 Generated with AI assistance.
| while (this.fcStore.currentSlot < currentSlot) { | ||
| const previousSlot = this.fcStore.currentSlot; | ||
| // Note: we are relying upon `onTick` to update `fcStore.time` to ensure we don't get stuck in a loop. | ||
| this.onTick(previousSlot + 1); | ||
| this.queuedAttestationsPreviousSlot = 0; | ||
| // Process any attestations that might now be eligible before running FCR for this slot. | ||
| this.processAttestationQueue(); | ||
| this.runFastConfirmation(); | ||
| this.validatedAttestationDatas = new Set(); | ||
| } | ||
|
|
||
| this.queuedAttestationsPreviousSlot = 0; | ||
| // Process any attestations that might now be eligible. | ||
| this.processAttestationQueue(); | ||
| this.validatedAttestationDatas = new Set(); | ||
| } |
There was a problem hiding this comment.
worth pointing out we moved this inside the while-loop cc @twoeths @nazarhussain, not a blocker for merging this, just need confirmation this was intended, suggests we had a bug before here?
There was a problem hiding this comment.
Intentional — runFastConfirmation() makes per-slot decisions, so the queue has to be drained against each slot's fcStore.currentSlot (not the final one), and the reset/snapshot lines come along with processAttestationQueue to keep the FCR-input ordering correct: reset counter → drain queued attestations into latestMessages → updateHead()+FCR snapshot → clear validatedAttestationDatas.
Pre-PR wasn't a correctness bug as far as I can see: in the single-tick hot path, loop-body vs after-loop are equivalent. For the rare multi-slot tick (resync / clock jump), the old code drained the queue once against the final slot — late but not wrong, since findHead consumers always run after updateTime, so all the queued attestations were always applied before any vote was read. The new code just tightens per-slot semantics so FCR can hook in cleanly.
Minor follow-up worth a separate PR: the docstring above updateTime ("calling this multiple times in the same slot does not update votes…") still reads like the all-at-end model — could be refreshed to note the per-slot inner work.
|
🎉 This PR is included in v1.44.0 🎉 |
File used .ts relative imports since #8837; every other test file in the package uses .js per repo convention. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Motivation
Introduce assumption based fast confirmation rule.
Description
Specs: ethereum/consensus-specs#4747