Skip to content

Commit 245b325

Browse files
committed
refactor: remove deprecated L2Block and L2BlockHeader
1 parent a238f84 commit 245b325

File tree

66 files changed

+819
-1219
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+819
-1219
lines changed

.claude/settings.local.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(git show:*)",
5+
"Skill(ci-log-reader)",
6+
"Bash(./ci.sh:*)",
7+
"Bash(sort:*)",
8+
"Bash(ls:*)",
9+
"Bash(find:*)",
10+
"Bash(./scripts/tsc.sh:*)",
11+
"Bash(test:*)",
12+
"Bash(./bootstrap.sh:*)",
13+
"Bash(git add:*)",
14+
"Bash(git commit:*)"
15+
]
16+
}
17+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# L2Block to L2BlockNew Migration Plan
2+
3+
## Overview
4+
5+
The `L2Block` class is deprecated in favor of `L2BlockNew`. The key differences:
6+
7+
- **L2Block**: Uses `L2BlockHeader` which combines block header + checkpoint-specific fields (blobsHash, inHash, epochOutHash, blockHeadersHash)
8+
- **L2BlockNew**: Uses pure `BlockHeader` without checkpoint-specific fields, plus `checkpointNumber` and `indexWithinCheckpoint` as separate fields
9+
10+
The migration is needed because `L2Block` requires checkpoint data to be constructed, but with the new feature to push proposed blocks to the archiver before checkpoints exist, we need a block type that doesn't depend on checkpoint data.
11+
12+
## Files to Migrate
13+
14+
### Phase 1: Core Interfaces (stdlib)
15+
16+
| File | Changes Needed |
17+
|------|----------------|
18+
| `stdlib/src/block/l2_block_source.ts` | Replace `getBlock()` return type with `L2BlockNew`, remove deprecated methods |
19+
| `stdlib/src/interfaces/aztec-node.ts` | Update `getBlock()` to return `L2BlockNew` |
20+
| `stdlib/src/interfaces/archiver.ts` | Update interfaces |
21+
| `stdlib/src/interfaces/block-builder.ts` | Update interfaces if needed |
22+
| `stdlib/src/p2p/block_proposal.ts` | Check if uses L2Block |
23+
| `stdlib/src/p2p/consensus_payload.ts` | Check if uses L2Block |
24+
25+
### Phase 2: Archiver Package
26+
27+
| File | Changes Needed |
28+
|------|----------------|
29+
| `archiver/src/modules/data_source_base.ts` | Change `getBlock()` to use `getL2BlockNew()`, remove L2Block conversion logic |
30+
| `archiver/src/store/block_store.ts` | Update any L2Block references |
31+
| `archiver/src/store/kv_archiver_store.ts` | Update store interfaces |
32+
| `archiver/src/archiver.ts` | Update main archiver class |
33+
| `archiver/src/test/mock_archiver.ts` | Update mock |
34+
| `archiver/src/test/mock_l2_block_source.ts` | Update mock |
35+
36+
### Phase 3: Node and Sequencer
37+
38+
| File | Changes Needed |
39+
|------|----------------|
40+
| `aztec-node/src/aztec-node/server.ts` | Update `getBlock()` implementation |
41+
| `sequencer-client/src/sequencer/sequencer.ts` | Check and update |
42+
| `prover-client/src/block-factory/light.ts` | Check and update |
43+
44+
### Phase 4: P2P Package
45+
46+
| File | Changes Needed |
47+
|------|----------------|
48+
| `p2p/src/client/interface.ts` | Update interfaces |
49+
| `p2p/src/client/p2p_client.ts` | Update implementation |
50+
| `p2p/src/services/libp2p/libp2p_service.ts` | Update |
51+
| `p2p/src/services/reqresp/interface.ts` | Update |
52+
| `p2p/src/services/tx_collection/*.ts` | Update |
53+
54+
### Phase 5: Other Packages
55+
56+
| File | Changes Needed |
57+
|------|----------------|
58+
| `txe/src/**/*.ts` | Update all TXE files |
59+
| `world-state/src/synchronizer/server_world_state_synchronizer.ts` | Update |
60+
| `aztec.js/src/api/block.ts` | Update client API |
61+
62+
### Phase 6: End-to-End Tests
63+
64+
| File | Changes Needed |
65+
|------|----------------|
66+
| `end-to-end/src/e2e_l1_publisher/write_json.ts` | Update test utilities |
67+
| `end-to-end/src/shared/gas_portal_test_harness.ts` | Update |
68+
| `end-to-end/src/spartan/*.ts` | Update |
69+
70+
## Migration Strategy
71+
72+
### Step 1: Update L2BlockSource Interface
73+
- Change `getBlock(number: BlockNumber): Promise<L2Block | undefined>` to return `L2BlockNew`
74+
- Keep `getL2BlockNew()` as is or deprecate it once `getBlock()` is migrated
75+
76+
### Step 2: Update Archiver Implementation
77+
- Modify `getBlock()` in `data_source_base.ts` to call `this.store.getBlock()` directly (like `getL2BlockNew()` does)
78+
- Remove `getPublishedBlocks()` dependency for `getBlock()`
79+
80+
### Step 3: Update AztecNode
81+
- Update `getBlock()` in server.ts to return `L2BlockNew`
82+
83+
### Step 4: Update Consumers
84+
- Update all code that calls `getBlock()` to work with `L2BlockNew`
85+
- Replace `block.header.*` accesses with appropriate `L2BlockNew` accessors
86+
87+
### Step 5: Update Tests
88+
- Update e2e tests to use `L2BlockNew` methods instead of `L2Block` methods
89+
90+
## Key Method Migrations
91+
92+
### L2Block methods to L2BlockNew equivalents
93+
94+
| L2Block | L2BlockNew |
95+
|---------|------------|
96+
| `block.header.globalVariables` | `block.header.globalVariables` (same) |
97+
| `block.header.state` | `block.header.state` (same) |
98+
| `block.number` | `block.number` (same) |
99+
| `block.slot` | `block.slot` (same) |
100+
| `block.body` | `block.body` (same) |
101+
| `block.archive` | `block.archive` (same) |
102+
| `block.getCheckpointBlobFields()` | Use `encodeCheckpointBlobDataFromBlocks([block.toBlockBlobData()])` |
103+
| `block.toBlobFields()` | `block.toBlobFields()` (same) |
104+
| `block.getCheckpointHeader()` | No direct equivalent - checkpoint header is separate |
105+
| `block.header.blobsHash` | Not available on L2BlockNew - it's checkpoint-specific |
106+
107+
## Current Progress
108+
109+
- [x] Phase 1: Core Interfaces (stdlib) - COMPLETED
110+
- [x] Phase 2: Archiver Package - COMPLETED
111+
- [x] Phase 3: Node and Sequencer - COMPLETED
112+
- [x] Phase 4: P2P Package - COMPLETED
113+
- [x] Phase 5: Other Packages (pxe, txe, world-state) - COMPLETED
114+
- [x] Phase 6: End-to-End Tests - COMPLETED
115+
116+
**BUILD PASSES**
117+
118+
## Phase 7: Delete deprecated L2Block class
119+
120+
### Remaining L2Block usages to remove:
121+
122+
| File | Usage | Fix |
123+
|------|-------|-----|
124+
| `archiver/src/modules/data_source_base.ts` | `L2Block.fromCheckpoint()` | Pass checkpoint blocks directly as L2BlockNew |
125+
| `archiver/src/test/mock_l2_block_source.ts` | `L2Block[]`, `L2Block.random()` | Use `L2BlockNew.random()` |
126+
| `archiver/src/test/mock_archiver.ts` | `L2Block.fromCheckpoint()` | Use checkpoint blocks directly |
127+
| `sequencer-client/src/publisher/sequencer-publisher.test.ts` | `L2Block.random()` | Use `L2BlockNew.random()` |
128+
| `prover-client/src/block-factory/light.ts` | Creates `L2Block` | Create `L2BlockNew` instead |
129+
| `p2p/src/client/p2p_client.test.ts` | `L2Block.random()` | Use `L2BlockNew.random()` |
130+
| `p2p/src/services/libp2p/libp2p_service.test.ts` | `L2Block.random()` | Use `L2BlockNew.random()` |
131+
132+
### Files to delete after migration:
133+
- `stdlib/src/block/l2_block.ts`
134+
- `stdlib/src/block/l2_block_header.ts`
135+
136+
## Phase 7 Status: COMPLETED ✓
137+
138+
- `L2Block` class deleted from `stdlib/src/block/l2_block.ts`
139+
- All usages migrated to `L2BlockNew`
140+
- Build passes
141+
142+
## Phase 8: Delete deprecated L2BlockHeader class
143+
144+
### Files to update (replace `L2BlockHeader` with `BlockHeader` or `CheckpointHeader`):
145+
146+
| File | Usage | Fix |
147+
|------|-------|-----|
148+
| `stdlib/src/tests/mocks.ts` | `makeL2BlockHeader().toBlockHeader()` | Use `BlockHeader.random()` directly |
149+
| `stdlib/src/tests/mocks.ts` | `makeL2BlockHeader().toCheckpointHeader()` | Use `CheckpointHeader.random()` directly |
150+
| `stdlib/src/tests/factories.ts` | Re-exports `makeL2BlockHeader` | Remove export |
151+
| `p2p/src/mem_pools/attestation_pool/mocks.ts` | `makeL2BlockHeader().toCheckpointHeader()` | Use `CheckpointHeader.random()` |
152+
| `p2p/src/client/test/p2p_client.integration_*.test.ts` | Uses `L2BlockHeader` | Replace with `BlockHeader` |
153+
| `p2p/src/msg_validators/**/*.test.ts` | Uses `L2BlockHeader` | Replace with `BlockHeader`/`CheckpointHeader` |
154+
| `validator-client/src/*.test.ts` | Uses `L2BlockHeader` | Replace with appropriate type |
155+
| `txe/src/utils/block_creation.ts` | Creates `L2BlockHeader` directly | Use `BlockHeader` directly |
156+
157+
### Files to delete:
158+
- `stdlib/src/block/l2_block_header.ts`
159+
- `stdlib/src/block/l2_block_code_to_purge.ts`
160+
161+
### Key replacements:
162+
- `makeL2BlockHeader(seed).toBlockHeader()``BlockHeader.random()`
163+
- `makeL2BlockHeader(seed).toCheckpointHeader()``CheckpointHeader.random()`
164+
- `L2BlockHeader` type → `BlockHeader` or `CheckpointHeader` depending on context
165+
166+
## Phase 8 Status: COMPLETED ✓
167+
168+
- `L2BlockHeader` class deleted from `stdlib/src/block/l2_block_header.ts`
169+
- `l2_block_code_to_purge.ts` deleted
170+
- All usages migrated to `BlockHeader` or `CheckpointHeader`
171+
- Build passes
172+
173+
## Migration Complete ✓
174+
175+
All deprecated classes have been removed:
176+
- [x] `L2Block` class - DELETED
177+
- [x] `L2BlockHeader` class - DELETED
178+
- [x] `l2_block_code_to_purge.ts` - DELETED
179+
180+
## Notes
181+
182+
- The original issue was that `getBlock()` required checkpoint data, but provisional blocks don't have checkpoint data yet
183+
- Migration resolved this by using `L2BlockNew` which doesn't depend on checkpoint-specific fields
184+
- `L2BlockNew` can now be stored and retrieved before checkpoints are created

yarn-project/archiver/src/archiver-sync.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ describe('Archiver Sync', () => {
212212
const expectedTotalNumLogs = (name: 'private' | 'public' | 'contractClass') =>
213213
sum(block.body.txEffects.map(txEffect => txEffect[`${name}Logs`].length));
214214

215-
const privateLogs = (await archiver.getBlock(blockNumber))!.toL2Block().getPrivateLogs();
215+
const privateLogs = (await archiver.getBlock(blockNumber))!.getPrivateLogs();
216216
expect(privateLogs.length).toBe(expectedTotalNumLogs('private'));
217217

218218
const publicLogs = (await archiver.getPublicLogs({ fromBlock: blockNumber, toBlock: blockNumber + 1 })).logs;

yarn-project/archiver/src/modules/data_source_base.ts

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
77
import {
88
type CheckpointedL2Block,
99
CommitteeAttestation,
10-
L2Block,
11-
type L2BlockNew,
10+
L2BlockNew,
1211
type L2Tips,
1312
PublishedL2Block,
1413
} from '@aztec/stdlib/block';
@@ -273,13 +272,13 @@ export abstract class ArchiverDataSourceBase
273272
return this.store.getBlocksForSlot(slotNumber);
274273
}
275274

276-
public async getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2Block[]> {
275+
public async getBlocksForEpoch(epochNumber: EpochNumber): Promise<L2BlockNew[]> {
277276
if (!this.l1Constants) {
278277
throw new Error('L1 constants not set');
279278
}
280279

281280
const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1Constants);
282-
const blocks: L2Block[] = [];
281+
const blocks: L2BlockNew[] = [];
283282

284283
// Walk the list of checkpoints backwards and filter by slots matching the requested epoch.
285284
// We'll typically ask for checkpoints for a very recent epoch, so we shouldn't need an index here.
@@ -361,49 +360,43 @@ export abstract class ArchiverDataSourceBase
361360
await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
362361
).filter(isDefined);
363362

364-
const olbBlocks: PublishedL2Block[] = [];
363+
const publishedBlocks: PublishedL2Block[] = [];
365364
for (let i = 0; i < checkpoints.length; i++) {
366365
const blockForCheckpoint = blocks[i][0];
367366
const checkpoint = checkpoints[i];
368367
if (checkpoint.checkpointNumber > provenCheckpointNumber && proven === true) {
369-
// this checkpointisn't proven and we only want proven
368+
// this checkpoint isn't proven and we only want proven
370369
continue;
371370
}
372-
const oldCheckpoint = new Checkpoint(
373-
blockForCheckpoint.archive,
374-
checkpoint.header,
375-
[blockForCheckpoint],
376-
checkpoint.checkpointNumber,
377-
);
378-
const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
379371
const publishedBlock = new PublishedL2Block(
380-
oldBlock,
372+
blockForCheckpoint,
381373
checkpoint.l1,
382374
checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
383375
);
384-
olbBlocks.push(publishedBlock);
376+
publishedBlocks.push(publishedBlock);
385377
}
386-
return olbBlocks;
378+
return publishedBlocks;
387379
}
388380

389-
public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
381+
public async getBlock(number: BlockNumber): Promise<L2BlockNew | undefined> {
390382
// If the number provided is -ve, then return the latest block.
391383
if (number < 0) {
392384
number = await this.store.getLatestBlockNumber();
393385
}
394386
if (number === 0) {
395387
return undefined;
396388
}
397-
const publishedBlocks = await this.getPublishedBlocks(number, 1);
398-
if (publishedBlocks.length === 0) {
399-
return undefined;
400-
}
401-
return publishedBlocks[0].block;
389+
return this.store.getBlock(number);
402390
}
403391

404-
public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
405-
const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
406-
return publishedBlocks.map(x => x.block);
392+
public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2BlockNew[]> {
393+
const blocks = await this.store.getBlocks(from, limit);
394+
395+
if (proven === true) {
396+
const provenBlockNumber = await this.store.getProvenBlockNumber();
397+
return blocks.filter(b => b.number <= provenBlockNumber);
398+
}
399+
return blocks;
407400
}
408401

409402
public async getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
@@ -416,6 +409,16 @@ export abstract class ArchiverDataSourceBase
416409
return this.buildOldBlockFromCheckpointedBlock(checkpointedBlock);
417410
}
418411

412+
public async getL2BlockNewByHash(blockHash: Fr): Promise<L2BlockNew | undefined> {
413+
const checkpointedBlock = await this.store.getCheckpointedBlockByHash(blockHash);
414+
return checkpointedBlock?.block;
415+
}
416+
417+
public async getL2BlockNewByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
418+
const checkpointedBlock = await this.store.getCheckpointedBlockByArchive(archive);
419+
return checkpointedBlock?.block;
420+
}
421+
419422
private async buildOldBlockFromCheckpointedBlock(
420423
checkpointedBlock: CheckpointedL2Block | undefined,
421424
): Promise<PublishedL2Block | undefined> {
@@ -426,15 +429,8 @@ export abstract class ArchiverDataSourceBase
426429
if (!checkpoint) {
427430
return checkpoint;
428431
}
429-
const fullCheckpoint = new Checkpoint(
430-
checkpointedBlock?.block.archive,
431-
checkpoint?.header,
432-
[checkpointedBlock.block],
433-
checkpoint.checkpointNumber,
434-
);
435-
const oldBlock = L2Block.fromCheckpoint(fullCheckpoint);
436432
const published = new PublishedL2Block(
437-
oldBlock,
433+
checkpointedBlock.block,
438434
checkpoint.l1,
439435
checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
440436
);

yarn-project/archiver/src/test/mock_archiver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { CheckpointNumber } from '@aztec/foundation/branded-types';
22
import type { Fr } from '@aztec/foundation/curves/bn254';
3-
import { L2Block, type L2BlockSource } from '@aztec/stdlib/block';
3+
import type { L2BlockSource } from '@aztec/stdlib/block';
44
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
55
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
66

@@ -57,7 +57,7 @@ export class MockPrefilledArchiver extends MockArchiver {
5757

5858
const fromBlock = this.l2Blocks.length;
5959
// TODO: Add L2 blocks and checkpoints separately once archiver has the apis for that.
60-
this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).map(c => L2Block.fromCheckpoint(c)));
60+
this.addBlocks(this.prefilled.slice(fromBlock, fromBlock + numBlocks).flatMap(c => c.blocks));
6161
return Promise.resolve();
6262
}
6363
}

0 commit comments

Comments
 (0)