Skip to content

fix: off-by-1 in getBlockHashMembershipWitness archive snapshot#21648

Merged
benesjan merged 1 commit intomerge-train/fairiesfrom
jan/f-464-bug
Mar 17, 2026
Merged

fix: off-by-1 in getBlockHashMembershipWitness archive snapshot#21648
benesjan merged 1 commit intomerge-train/fairiesfrom
jan/f-464-bug

Conversation

@benesjan
Copy link
Contributor

Summary

  • Fix off-by-1 error in AztecNodeService.getBlockHashMembershipWitness: the Noir circuit checks archive membership against anchor_block_header.last_archive.root (the archive at block N-1), but the node was returning a sibling path from the archive at block N. Fixed by fetching world state at referenceBlock - 1.
  • Add comprehensive TXE tests for get_block_header_at covering: past blocks, earliest block, boundary block (N-1), anchor block (early return path), future block rejection, and block number mismatch.

Fixes #21635
Fixes F-464

Test plan

  • Existing stdlib aztec-node interface tests pass (62/62)
  • New Noir TXE tests compile and pass (6/6)
  • CI passes

🤖 Generated with Claude Code

@benesjan benesjan requested a review from nventuro as a code owner March 17, 2026 07:01
get_block_header_at_oracle(block_number)
}

pub fn get_block_header_at(block_number: u32, context: PrivateContext) -> BlockHeader {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Shall we make this function be pub(crate) and force devs to use it via the private context where it's exposed?

@benesjan benesjan requested a review from mverzilli March 17, 2026 07:39
Copy link
Contributor

@mverzilli mverzilli left a comment

Choose a reason for hiding this comment

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

Nasty one

@benesjan benesjan changed the base branch from next to merge-train/fairies March 17, 2026 09:45
The Noir circuit checks archive membership against
`anchor_block_header.last_archive.root`, which is the archive tree root
BEFORE the anchor block was added (state after block N-1). The node was
returning a sibling path from the archive at block N, causing the proof
to fail.

Fix by resolving the reference block number and fetching world state at
block N-1 instead. Also adds comprehensive tests for get_block_header_at
covering past blocks, anchor block, future block rejection, and block
number mismatch.

Closes #21635

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@benesjan benesjan merged commit c02877c into merge-train/fairies Mar 17, 2026
11 checks passed
@benesjan benesjan deleted the jan/f-464-bug branch March 17, 2026 10:41
@AztecBot
Copy link
Collaborator

❌ Failed to cherry-pick to v4 due to conflicts. (🤖) View backport run.

alexghr added a commit that referenced this pull request Mar 17, 2026
BEGIN_COMMIT_OVERRIDE
fix(aztec-nr): return Option from decode functions and fix event
commitment capacity (backport #21264) (#21360)
fix: backport #21271 — handle bad note lengths on
compute_note_hash_and_nullifier (#21364)
fix: not reusing tags of partially reverted txs (#20817)
chore: revert accidental backport of #20817 (#21583)
feat: Implement commit all and revert all for world state checkpoints
(#21532)
cherry-pick: fix: dependabot alerts (#21531)
fix: dependabot alerts (backport #21531 to v4) (#21592)
fix: backport #21443 — Don't update state if we failed to execute
sufficient transactions (v4) (#21610)
chore: Fix msgpack serialisation (#21612)
fix(p2p): fall back to maxTxsPerCheckpoint for per-block tx validation
(#21605)
chore: merge v4 into backport-to-v4-staging (#21618)
fix(revert): avm sim uses event loop again (#21138) (#21630)
fix(e2e): remove historic/finalized block checks from epochs_multiple
test (#21642)
fix: clamp finalized block to oldest available in world-state (#21643)
fix: skip handleChainFinalized when block is behind oldest available
(#21656)
chore: demote finalized block skip log to trace (#21661)
fix: off-by-1 in getBlockHashMembershipWitness archive snapshot
(backport #21648) (#21663)
fix: capture txs not available error reason in proposal handler (#21670)
chore: add L1 inclusion time to stg public (#21665)
END_COMMIT_OVERRIDE

---------

Co-authored-by: Jan Beneš <janbenes1234@gmail.com>
Co-authored-by: PhilWindle <60546371+PhilWindle@users.noreply.github.com>
Co-authored-by: Phil Windle <philip.windle@gmail.com>
Co-authored-by: Santiago Palladino <santiago@aztecprotocol.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: ludamad <adam.domurad@gmail.com>
Co-authored-by: Alex Gherghisan <alexghr@users.noreply.github.com>
github-merge-queue bot pushed a commit that referenced this pull request Mar 17, 2026
BEGIN_COMMIT_OVERRIDE
feat: entrypoint replay protection (#21649)
feat: guard BoundedVec oracle returns against dirty trailing storage
(#21589)
feat: implement manual Packable for structs with sub-Field members
(#21576)
fix: off-by-1 in getBlockHashMembershipWitness archive snapshot (#21648)
END_COMMIT_OVERRIDE
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.

[BUG]

3 participants