Skip to content

Fix envelopes-by-range to only serve canonical payloads backward#16553

Open
terencechain wants to merge 4 commits intodevelopfrom
fix-envelopes-by-range-backward-walk
Open

Fix envelopes-by-range to only serve canonical payloads backward#16553
terencechain wants to merge 4 commits intodevelopfrom
fix-envelopes-by-range-backward-walk

Conversation

@terencechain
Copy link
Collaborator

  • The ExecutionPayloadEnvelopesByRange handler previously served any envelope found in the DB for canonical blocks, without verifying the payload was actually included (full vs empty). This could serve empty/withheld payloads as if they were canonical.
  • Fix by walking the ParentBlockHash chain backward from a successor block: a child's bid.ParentBlockHash determines which parent payload it built on, so only envelopes reachable through this chain are canonical.
  • Add parent_block_hash field to BlindedExecutionPayloadEnvelope proto so the walk can follow the chain using only blinded envelopes from the DB, without loading full beacon blocks.
  • Handle stale BlockHash → Root index look up in the DB.

@terencechain terencechain force-pushed the fix-envelopes-by-range-backward-walk branch from 08f4c45 to a63883b Compare March 17, 2026 15:12
Copy link
Contributor

@potuz potuz left a comment

Choose a reason for hiding this comment

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

First pass, checked up to the db methods and they LGTM

LatestBlockHash: make([]byte, 32),
PayloadExpectedWithdrawals: make([]*enginev1.Withdrawal, 0),
ProposerLookahead: make([]uint64, 64),
LatestBlockHash: make([]byte, 32),
Copy link
Contributor

Choose a reason for hiding this comment

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

linters always want to commit things that are not related :)

if slot == math.MaxUint64 {
return 0, nil, nil
}
// Seek to slot+1 so we find the first key strictly above slot.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's better to find above or equal and let the caller decide if it needs to send slot + 1. Otherwise it's probably better to add "strictly above" to the name.

db := setupDB(t)
ctx := t.Context()

block1, err := tt.newBlock(primitives.Slot(10), nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably good to have a test with different blocks on the same slot.

Co-authored-by: satushh <satushh@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Unassigned

Development

Successfully merging this pull request may close these issues.

3 participants