Skip to content

chore: updated follow executor feedback - #7350

Open
hamdiallam wants to merge 9 commits into
pep/decouple-fcu-head-2from
hamdi/follow.executor.updates
Open

chore: updated follow executor feedback#7350
hamdiallam wants to merge 9 commits into
pep/decouple-fcu-head-2from
hamdi/follow.executor.updates

Conversation

@hamdiallam

Copy link
Copy Markdown
Contributor

No description provided.

@hamdiallam

Copy link
Copy Markdown
Contributor Author

cyclops audit fast

@tempoxyz-bot tempoxyz-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️ Cyclops Review

This change separates a follower's certificate-selected execution head from block-driven safe/finalized updates, but a future certificate head can prevent delivered blocks from becoming canonical. One verified high-severity regression and one lower-severity invariant issue require attention.

Reviewer Callouts
  • Acknowledgement after SYNCING (actor.rs:287): newPayload accepts SYNCING and the block is still acknowledged. Confirm that marshal redelivery is not required if Reth's bounded block buffer later evicts that payload.
  • Marshal floor dependency (actor.rs:200-245): verify with a real Reth follower that canonical height, finalized state, persistence, and marshal archive pruning all continue under a multi-block certificate lead.
  • Round provenance (fcu.rs:27,56): document or test the assumption that a block's embedded consensus round equals the certificate round used to select the head.

let forkchoice = self
.latest_fcu
.update_finalized(&block)
.then_some(self.latest_fcu);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [SECURITY] Future certificate head stalls follower canonicalisation and finality

This snapshots latest_fcu after advancing finality, but update_finalized preserves a later certificate digest as the head. When certificates lead block delivery, the post-newPayload FCU names a head Reth has not received. Reth returns SYNCING without applying safe/finalized state or advancing its canonical head; under sustained lead, canonicalisation, persistence, pruning, and the marshal floor stall while retained execution state grows without bound. The verifier reproduced this with a two-block certificate lead.

Recommended Fix:
Use the delivered block as the head for its block-driven FCU so Reth can canonicalise it. Keep the later certificate head for standalone/heartbeat FCUs, or otherwise clamp this FCU to an execution-layer-known head.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reth issue

}

pub(super) fn update_head(&mut self, round: Round, digest: Digest) {
if self.head.0.is_none_or(|current| round > current) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [ISSUE] Forkchoice does not enforce head/finalized ordering

Forkchoice tracks the head's round but not its height, so this accepts any certificate when the current round is absent and cannot ensure the head remains at or above finalized. Current T4 monotonicity makes a malformed state difficult to reach, but the type permits it; Reth rejects such an inconsistent FCU and the follower propagates that rejection as a fatal subsystem exit.

Recommended Fix:
Track head height and reject updates that place it below finalized; assert the invariant before conversion to ForkchoiceState. Recover safely from an execution-layer inconsistent-forkchoice response rather than terminating the follower where possible.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-issue, for finalized heights, round is monotonically increasing

Comment thread crates/consensus/src/follow/executor/actor.rs Outdated
@hamdiallam
hamdiallam changed the base branch from main to pep/decouple-fcu-head-2 August 28, 2026 18:55
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.

3 participants