Skip to content

refactor(stdlib): carry the proposed tip header on chain-proposed events - #25116

Merged
nventuro merged 7 commits into
merge-train/fairiesfrom
nchamo/block-stream-tip-prefetch
Aug 6, 2026
Merged

refactor(stdlib): carry the proposed tip header on chain-proposed events#25116
nventuro merged 7 commits into
merge-train/fairiesfrom
nchamo/block-stream-tip-prefetch

Conversation

@nchamo

@nchamo nchamo commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Why we are doing this

Follow-up to #25089 in the PXE↔node RPC-reduction line. When PXE tracks the proposed chain tip it anchors on the tip's header, but the block stream's chain-proposed event only carried the block id, so the PXE handler had to fetch the header back from the node on every tip movement.

Our fix

chain-proposed now carries the tip's BlockHeader as a required payload, so consumers anchor on the event without a fetch of their own. The stream sources the header from whatever the pass already has: the delivered tip block in block mode, a prefetch that runs in parallel with the reorg walk-back in tips-only mode, or an on-demand by-hash read as a fallback. If the header cannot be obtained the pass aborts and retries on the next poll, so tier events never get ahead of a proposed tip the consumer never received.

Metrics

Measured on the key_flows transfers benchmark with a counting wrapper between the benchmarking wallet and the in-process node, applied to both base and this branch. Per-flow calls are unchanged; the saving is one serial fetch (round trip) per tip movement.

Flow RPC calls Round trips
ecdsar1+transfer_0_recursions+sponsored_fpc 35 → 35 26 → 25 (−3.8%)
ecdsar1+transfer_1_recursions+sponsored_fpc 37 → 37 23 → 21 (−8.7%)
ecdsar1+transfer_0_recursions+private_fpc 56 → 56 34 → 33 (−2.9%)
ecdsar1+transfer_1_recursions+private_fpc 56 → 56 32 → 31 (−3.1%)
whole suite (both wallets, incl. setup) 460 → 459 333 → 320 (−3.9%)

@nchamo nchamo self-assigned this Aug 5, 2026
@nchamo nchamo added ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure labels Aug 5, 2026
@nchamo
nchamo marked this pull request as ready for review August 5, 2026 16:04
@nchamo
nchamo requested review from nventuro and vezenovm August 5, 2026 16:04
Comment thread yarn-project/stdlib/src/block/l2_block_stream/l2_block_stream.test.ts Outdated
Comment thread yarn-project/stdlib/src/block/l2_block_stream/l2_block_stream.ts Outdated
// below). Throwing here propagates before the tips-store cursor advances, so the cursor stays put and the
// next sync re-emits chain-proposed (at-least-once). Were we to warn-and-skip, the cursor would advance and
// a quiet chain would never re-emit, leaving the anchor stale indefinitely.
throw new Error(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we ok with dropping this error scenario?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think so. We moved it into a warn in l2_block_stream.ts:

this.log.warn(`No header for the proposed tip; aborting this sync pass`, {
    blockNumber: sourceTips.proposed.number,
    blockHash: sourceTips.proposed.hash,
});

The idea is that we can retry again and maybe the node error was only temporary. We could potentially remember attempts and fail if we tried too many times, but it feels like an overkill to me

What do you think we should do?

@nventuro
nventuro enabled auto-merge (squash) August 6, 2026 19:16
@nventuro
nventuro merged commit d56293c into merge-train/fairies Aug 6, 2026
11 checks passed
@nventuro
nventuro deleted the nchamo/block-stream-tip-prefetch branch August 6, 2026 23:34
AztecBot pushed a commit that referenced this pull request Aug 6, 2026
…nts (#25116)

## Why we are doing this

Follow-up to #25089 in the PXE↔node RPC-reduction line. When PXE tracks
the proposed chain tip it anchors on the tip's header, but the block
stream's `chain-proposed` event only carried the block id, so the PXE
handler had to fetch the header back from the node on every tip
movement.

## Our fix

`chain-proposed` now carries the tip's `BlockHeader` as a required
payload, so consumers anchor on the event without a fetch of their own.
The stream sources the header from whatever the pass already has: the
delivered tip block in block mode, a prefetch that runs in parallel with
the reorg walk-back in tips-only mode, or an on-demand by-hash read as a
fallback. If the header cannot be obtained the pass aborts and retries
on the next poll, so tier events never get ahead of a proposed tip the
consumer never received.

## Metrics

Measured on the `key_flows` transfers benchmark with a counting wrapper
between the benchmarking wallet and the in-process node, applied to both
base and this branch. Per-flow calls are unchanged; the saving is one
serial fetch (round trip) per tip movement.

| Flow | RPC calls | Round trips |
|---|---|---|
| `ecdsar1+transfer_0_recursions+sponsored_fpc` | 35 → 35 | 26 → 25
(−3.8%) |
| `ecdsar1+transfer_1_recursions+sponsored_fpc` | 37 → 37 | 23 → 21
(−8.7%) |
| `ecdsar1+transfer_0_recursions+private_fpc` | 56 → 56 | 34 → 33
(−2.9%) |
| `ecdsar1+transfer_1_recursions+private_fpc` | 56 → 56 | 32 → 31
(−3.1%) |
| whole suite (both wallets, incl. setup) | 460 → 459 | 333 → 320
(−3.9%) |
@AztecBot

AztecBot commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

✅ Successfully backported to backport-to-v5-next-staging #25135.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v5-next ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants