|
| 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 |
0 commit comments