Skip to content

chore: Properly compute finalized block (#21156)#21795

Merged
spypsy merged 4 commits intobackport-to-v4-stagingfrom
v4-staging-finalization-fix
Mar 20, 2026
Merged

chore: Properly compute finalized block (#21156)#21795
spypsy merged 4 commits intobackport-to-v4-stagingfrom
v4-staging-finalization-fix

Conversation

@spypsy
Copy link
Copy Markdown
Member

@spypsy spypsy commented Mar 19, 2026

Fixes
A-551

Replaces the heuristic finalized block computation (provenBlock - 2 * epochDuration) with L1 finality.

On each archiver sync iteration, we now:

  1. Fetch the finalized L1 block via getBlock({ blockTag: 'finalized' })
  2. Query the rollup contract for the proven checkpoint number at that L1 block
  3. Persist that as the finalized checkpoint, from which the finalized L2 block number is derived

Failures in this step are caught and logged as warnings so they don't disrupt the rest of the sync loop (e.g. if the RPC node can't serve state at the finalized block).

  • RollupContract.getProvenCheckpointNumber now accepts an optional { blockNumber } to query historical contract state
  • BlockStore stores a lastFinalizedCheckpoint singleton and derives getFinalizedL2BlockNumber from it instead of the old arithmetic heuristic
  • ArchiverL1Synchronizer gains updateFinalizedCheckpoint(), called every sync iteration
  • KVArchiverDataStore constructor no longer takes l1Constants (the epochDuration it was used for is no longer needed)
  • FakeL1State updated to support blockTag: 'finalized' and getProvenCheckpointNumber with a block number, enabling new sync tests

Fixes
[A-551](https://linear.app/aztec-labs/issue/A-551/properly-compute-finalized-block)

Replaces the heuristic finalized block computation (`provenBlock - 2 *
epochDuration`) with L1 finality.

On each archiver sync iteration, we now:
1. Fetch the finalized L1 block via `getBlock({ blockTag: 'finalized'
})`
2. Query the rollup contract for the proven checkpoint number at that L1
block
3. Persist that as the finalized checkpoint, from which the finalized L2
block number is derived

Failures in this step are caught and logged as warnings so they don't
disrupt the rest of the sync loop (e.g. if the RPC node can't serve
state at the finalized block).

- `RollupContract.getProvenCheckpointNumber` now accepts an optional `{
blockNumber }` to query historical contract state
- `BlockStore` stores a `lastFinalizedCheckpoint` singleton and derives
`getFinalizedL2BlockNumber` from it instead of the old arithmetic
heuristic
- `ArchiverL1Synchronizer` gains `updateFinalizedCheckpoint()`, called
every sync iteration
- `KVArchiverDataStore` constructor no longer takes `l1Constants` (the
`epochDuration` it was used for is no longer needed)
- `FakeL1State` updated to support `blockTag: 'finalized'` and
`getProvenCheckpointNumber` with a block number, enabling new sync tests
@spypsy spypsy marked this pull request as ready for review March 19, 2026 15:31
@alexghr alexghr added the ci-release-pr Creates a development tag and runs the release suite label Mar 19, 2026
@AztecBot AztecBot removed the ci-release-pr Creates a development tag and runs the release suite label Mar 19, 2026
@alexghr alexghr added the ci-release-pr Creates a development tag and runs the release suite label Mar 19, 2026
@AztecBot AztecBot removed the ci-release-pr Creates a development tag and runs the release suite label Mar 19, 2026
@spypsy spypsy added the ci-release-pr Creates a development tag and runs the release suite label Mar 20, 2026
@AztecBot AztecBot removed the ci-release-pr Creates a development tag and runs the release suite label Mar 20, 2026
@spypsy spypsy enabled auto-merge (squash) March 20, 2026 12:48
@spypsy spypsy merged commit daff36a into backport-to-v4-staging Mar 20, 2026
23 of 24 checks passed
@spypsy spypsy deleted the v4-staging-finalization-fix branch March 20, 2026 12:51
PhilWindle added a commit that referenced this pull request Mar 20, 2026
Fixes


[A-551](https://linear.app/aztec-labs/issue/A-551/properly-compute-finalized-block)

Replaces the heuristic finalized block computation (`provenBlock - 2 *
epochDuration`) with L1 finality.

On each archiver sync iteration, we now:
1. Fetch the finalized L1 block via `getBlock({ blockTag: 'finalized'
})`
2. Query the rollup contract for the proven checkpoint number at that L1
block
3. Persist that as the finalized checkpoint, from which the finalized L2
block number is derived

Failures in this step are caught and logged as warnings so they don't
disrupt the rest of the sync loop (e.g. if the RPC node can't serve
state at the finalized block).

- `RollupContract.getProvenCheckpointNumber` now accepts an optional `{
blockNumber }` to query historical contract state
- `BlockStore` stores a `lastFinalizedCheckpoint` singleton and derives
`getFinalizedL2BlockNumber` from it instead of the old arithmetic
heuristic
- `ArchiverL1Synchronizer` gains `updateFinalizedCheckpoint()`, called
every sync iteration
- `KVArchiverDataStore` constructor no longer takes `l1Constants` (the
`epochDuration` it was used for is no longer needed)
- `FakeL1State` updated to support `blockTag: 'finalized'` and
`getProvenCheckpointNumber` with a block number, enabling new sync tests

---------
spalladino added a commit that referenced this pull request Mar 26, 2026
## Summary
Merges v4 branch into backport-to-v4-next-staging to bring in 17 commits
from v4 that were missing.

Key changes from v4:
- fix: verify accumulated pairing points in native ChonkVerifier
(#21975)
- chore: Properly compute finalized block (#21795, #21850)
- feat(archiver): validate contract instance addresses before storing
(#21787)
- feat(p2p): add tx validator for contract instance deployment addresses
(#21771)
- Various accumulated backports and bug fixes

## Conflicts resolved
6 files had merge conflicts, all resolved:
- `archiver/src/factory.ts` — kept `ContractClassPublicWithCommitment`
type from staging
- `archiver/src/modules/data_store_updater.ts` — merged imports from
both branches
- `archiver/src/store/kv_archiver_store.test.ts` — took v4's richer
describe block structure, adapted to singular `addProposedBlock` API
- `aztec-node/src/aztec-node/server.ts` — kept staging's block 0 check
and `getWorldState` method name
- `stdlib/src/tx/validator/error_texts.ts` — kept staging's contract
class error constants
- `world-state/src/synchronizer/server_world_state_synchronizer.ts` —
kept verbose log level

## Test plan
- CI should verify the merge compiles and tests pass
- Once merged, this branch can be merged into the backport-to-v4-next
branch

ClaudeBox log: https://claudebox.work/s/0150633f06bfb379?run=1
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