kip-227: report candidate failures against the proposer's own prior block - #126
Merged
hyunsooda merged 3 commits intoAug 20, 2026
Merged
Conversation
…lock A cfReport now targets the writer's own most recent prior proposal in the same epoch (so the report writer is the validator that solicited the candidates), and header.VRank carries that target block. Verification requires the target to be a prior, same-epoch block with the same proposer as the reporting block, so any withheld or fabricated failure is attributed to that proposer's own column under CFS aggregation. Reports without such a prior proposal (or across an epoch boundary) are empty. Message flow, PFS, MAX_ROUND, and the byzantine filter are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cfReport no longer carries the evaluated (target) block, only the failed candidate list. A candidate failure is scored against the reporting block's own proposer, so storing and verifying the target block added nothing; the format, the writer/reader note, and the block-validation target/proposer-match checks drop with it.
A candidate now sends VRankCandidate to the proposer that sent the VRankPreprepare, instead of broadcasting to all validators in ValActive. Only that proposer records preprepared_time and collects the replies, since it is the node that reports on the view from its own next proposal. Drop the "arrives before preprepared_time" on-time case: the proposer records preprepared_time before requesting the responses, so a reply never precedes it.
ian0371
approved these changes
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
Aligns KIP-227 with a change to how candidate failures are attributed. Previously
cfReport(N)covered blockN-1and was written by the proposer of blockN— a writer that is not the validator that solicited the candidate responses. That lets a proposer withhold itsVRankPreprepareand have the induced failures spread across honest writers, surviving the top-F byzantine filter.Now a
cfReportreports on the writer's own most recent prior proposal in the same epoch. A candidate failure is scored against the reporting block's own proposer, so any withheld or fabricated failure lands in that proposer's own byzantine-filterable column and is filtered — the report carries only the failed candidate list. Reports without such a prior proposal (or that would cross an epoch boundary) are empty. Message flow, PFS,MAX_ROUND, and the byzantine filter are unchanged.Types of changes
Checklist
I have read the CLA Document and I hereby sign the CLAin first time contributionRelated issues
Further comments