Skip to content

Conversation

@spalladino
Copy link
Contributor

Summary

Adds a PXE_SYNC_CHAIN_TIP config option that controls which chain tip the PXE syncs to:

  • proposed (default): Current behavior, updates anchor on every blocks-added event
  • checkpointed: Only update anchor when blocks are checkpointed on L1
  • proven: Only update anchor when blocks are proven
  • finalized: Only update anchor when blocks are finalized

This allows PXE users to choose a more conservative anchor block source to avoid transactions being built against provisional blocks that may get pruned.

Motivation

With skipPushProposedBlocksToArchiver: false, the sequencer pushes provisional blocks to the archiver before they're checkpointed on L1. The PXE would sync these blocks and use them as anchor, but if those blocks get pruned (slot passes without checkpoint), transactions built against them become invalid.

By setting PXE_SYNC_CHAIN_TIP=checkpointed, the PXE will only advance its anchor when blocks are confirmed on L1, making transactions safer.

Changes

  • Added syncChainTip config option to BlockSynchronizerConfig
  • Updated BlockSynchronizer to handle chain-checkpointed, chain-proven, and chain-finalized events based on config
  • Improved chain prune handling: ignore prunes when anchor is already at or below the prune point
  • Added unit tests for all sync modes

Test plan

  • Unit tests added for all syncChainTip modes
  • Run yarn test src/block_synchronizer/block_synchronizer.test.ts in pxe package

🤖 Generated with Claude Code

Adds a `PXE_SYNC_CHAIN_TIP` config option that controls which chain tip the PXE syncs to:
- `proposed` (default): Current behavior, updates anchor on every blocks-added event
- `checkpointed`: Only update anchor when blocks are checkpointed on L1
- `proven`: Only update anchor when blocks are proven
- `finalized`: Only update anchor when blocks are finalized

This allows PXE users to choose a more conservative anchor block source to avoid
transactions being built against provisional blocks that may get pruned.

Also improves handling of chain prune events by ignoring prunes when the anchor
is already at or below the prune point.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@spalladino spalladino requested a review from nventuro January 23, 2026 01:37
@spalladino spalladino enabled auto-merge January 23, 2026 01:44
Comment on lines +77 to +87
const blockHeader = await this.node.getBlockHeader(BlockNumber(event.block.number));
if (blockHeader) {
await this.updateAnchorBlockHeader(blockHeader);
}
}
break;
}
case 'chain-finalized': {
if (this.config.syncChainTip === 'finalized') {
const blockHeader = await this.node.getBlockHeader(BlockNumber(event.block.number));
if (blockHeader) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These two will add a full roundtrip to these sync modes. Is it possible to have the events include the block header already, like in the other modes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The full roundtrip is already happening in the other sync modes. The only difference is whether it's hidden in the L2BlockStream or explicit here, so they're all equally inefficient.

Comment on lines +96 to +101
if (currentAnchorBlockNumber <= event.block.number) {
this.log.verbose(
`Ignoring prune event to block ${event.block.number} greater than current anchor block ${currentAnchorBlockNumber}`,
{ pruneEvent: event, currentAnchorBlockHeader: currentAnchorBlockHeader.toInspect() },
);
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

I worry that this might break once we add the capacity to select a per-call anchor block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd expect most of this class to need a rework when that's implemented.

@spalladino spalladino added this pull request to the merge queue Jan 23, 2026
@AztecBot
Copy link
Collaborator

AztecBot commented Jan 23, 2026

Flakey Tests

🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry.

\033FLAKED\033 (8;;http://ci.aztec-labs.com/54eef304cb374d6c�54eef304cb374d6c8;;�):  yarn-project/end-to-end/scripts/run_test.sh simple src/e2e_epochs/epochs_l1_reorgs.test.ts (397s) (code: 1) group:e2e-p2p-epoch-flakes (\033Santiago Palladino\033: feat(pxe): add syncChainTip config to control anchor block source (#19874))

Merged via the queue into next with commit 3a0fe12 Jan 23, 2026
16 checks passed
@spalladino spalladino deleted the palla/pxe-sync-chain-tip-config branch January 23, 2026 14:37
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.

4 participants