Skip to content

Verify LaneProposal signer and parent hash chain in PushBlock#2925

Open
wen-coding wants to merge 4 commits intomainfrom
wen/fix_laneproposal_verify
Open

Verify LaneProposal signer and parent hash chain in PushBlock#2925
wen-coding wants to merge 4 commits intomainfrom
wen/fix_laneproposal_verify

Conversation

@wen-coding
Copy link
Contributor

@wen-coding wen-coding commented Feb 18, 2026

Summary

  • Signer == lane check: PushBlock did not verify that the signer of a LaneProposal matches the block's lane. A malicious validator could craft blocks on another validator's lane, bypassing VerifySig (which only checks the signer is a committee replica, not the lane producer). Added a cheap signer-lane comparison before expensive crypto verification.
  • Parent hash chain verification: PushBlock did not verify that the incoming block's parentHash matches the previous block's header hash. A malicious lane proposer could send a block with a fake parentHash, which honest validators would accept and vote on. When headers() later tries to reconstruct the block chain by walking parentHash links backwards, it cannot find a matching vote and waits forever — deadlocking the node. Added parent hash verification when the previous block is available (after pruning, the check is safely skipped since headers() never follows the first block's parentHash in a LaneRange). A mismatch silently drops the block rather than returning an error, since equivocation (same key producing different chains) is a legitimate scenario.

PushBlock accepted blocks without checking that the signer matches the
lane or that the block's parentHash chains to the previous block. A
malicious proposer could impersonate another lane or break the parent
hash chain, which would deadlock header reconstruction in headers().

Added signer == lane check (before expensive crypto verification) and
parent hash chain verification when the previous block is available.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions
Copy link

github-actions bot commented Feb 18, 2026

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 19, 2026, 7:15 PM

@github-actions
Copy link

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedFeb 18, 2026, 8:42 PM

@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 48.37%. Comparing base (dc14fb5) to head (0e2eacc).
⚠️ Report is 3 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (dc14fb5) and HEAD (0e2eacc). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (dc14fb5) HEAD (0e2eacc)
sei-chain 1 0
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #2925       +/-   ##
===========================================
- Coverage   57.32%   48.37%    -8.96%     
===========================================
  Files        2095      671     -1424     
  Lines      172888    50611   -122277     
===========================================
- Hits        99115    24481    -74634     
+ Misses      64880    23982    -40898     
+ Partials     8893     2148     -6745     
Flag Coverage Δ
sei-chain ?
sei-cosmos 48.18% <ø> (-0.01%) ⬇️
sei-db 68.42% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 1547 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

wen-coding and others added 2 commits February 18, 2026 13:59
A parentHash mismatch can happen legitimately when a producer
equivocates (e.g. restarts and produces a different chain). The block
is still prevented from entering the queue, but the caller is not
treated as malicious.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pompon0 pompon0 self-requested a review February 19, 2026 10:07
// Verify parent hash chain to prevent a malicious proposer from
// breaking the block chain, which would deadlock header reconstruction.
// A mismatch is not an error: it can happen legitimately when a
// producer equivocates (restarts and produces a different chain).
Copy link
Contributor

Choose a reason for hiding this comment

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

equivocation of producer is as malicious behavior as equivocation of proposer. It does not endanger the security, but imo it would be worth escalating as an error, so that it gets logged. It will help debugging stalled lanes, if nothing more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, if we return an error, and the producer keep pushing the same equivocating block, then every receiver will repeatedly reconnect?
I've changed it to log an error but return nil for now

Parent hash mismatch indicates a producer equivocated, which is
malicious behavior worth logging to aid debugging stalled lanes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wen-coding wen-coding requested a review from arajasek February 19, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments