@aztec/world-state 0.0.1-commit.9b94fc1 → 0.0.1-commit.d3ec352c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,13 @@
1
- import { L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/constants';
2
- import { SHA256Trunc } from '@aztec/foundation/crypto';
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
3
2
  import { createLogger } from '@aztec/foundation/log';
4
3
  import { promiseWithResolvers } from '@aztec/foundation/promise';
5
4
  import { elapsed } from '@aztec/foundation/timer';
6
- import { MerkleTreeCalculator } from '@aztec/foundation/trees';
7
5
  import { WorldStateRunningState } from '@aztec/stdlib/interfaces/server';
8
6
  import { MerkleTreeId } from '@aztec/stdlib/trees';
9
7
  import { TraceableL2BlockStream, getTelemetryClient } from '@aztec/telemetry-client';
10
8
  import { WorldStateInstrumentation } from '../instrumentation/instrumentation.js';
11
9
  import { WorldStateSynchronizerError } from './errors.js';
10
+ import { findFirstBlocksInCheckpoints } from './utils.js';
12
11
  /**
13
12
  * Synchronizes the world state with the L2 blocks from a L2BlockSource via a block stream.
14
13
  * The synchronizer will download the L2 blocks from the L2BlockSource and update the merkle trees.
@@ -35,7 +34,7 @@ import { WorldStateSynchronizerError } from './errors.js';
35
34
  this.config = config;
36
35
  this.instrumentation = instrumentation;
37
36
  this.log = log;
38
- this.latestBlockNumberAtStart = 0;
37
+ this.latestBlockNumberAtStart = BlockNumber.ZERO;
39
38
  this.currentState = WorldStateRunningState.IDLE;
40
39
  this.latestBlockHashQuery = undefined;
41
40
  this.syncPromise = promiseWithResolvers();
@@ -66,7 +65,7 @@ import { WorldStateSynchronizerError } from './errors.js';
66
65
  return this.syncPromise;
67
66
  }
68
67
  // Get the current latest block number
69
- this.latestBlockNumberAtStart = await (this.config.worldStateProvenBlocksOnly ? this.l2BlockSource.getProvenBlockNumber() : this.l2BlockSource.getBlockNumber());
68
+ this.latestBlockNumberAtStart = BlockNumber(await (this.config.worldStateProvenBlocksOnly ? this.l2BlockSource.getProvenBlockNumber() : this.l2BlockSource.getBlockNumber()));
70
69
  const blockToDownloadFrom = await this.getLatestBlockNumber() + 1;
71
70
  if (blockToDownloadFrom <= this.latestBlockNumberAtStart) {
72
71
  // If there are blocks to be retrieved, go to a synching state
@@ -103,10 +102,10 @@ import { WorldStateSynchronizerError } from './errors.js';
103
102
  async status() {
104
103
  const summary = await this.merkleTreeDb.getStatusSummary();
105
104
  const status = {
106
- latestBlockNumber: Number(summary.unfinalizedBlockNumber),
107
- latestBlockHash: await this.getL2BlockHash(Number(summary.unfinalizedBlockNumber)) ?? '',
108
- finalizedBlockNumber: Number(summary.finalizedBlockNumber),
109
- oldestHistoricBlockNumber: Number(summary.oldestHistoricalBlock),
105
+ latestBlockNumber: summary.unfinalizedBlockNumber,
106
+ latestBlockHash: await this.getL2BlockHash(summary.unfinalizedBlockNumber) ?? '',
107
+ finalizedBlockNumber: summary.finalizedBlockNumber,
108
+ oldestHistoricBlockNumber: summary.oldestHistoricalBlock,
110
109
  treesAreSynched: summary.treesAreSynched
111
110
  };
112
111
  return {
@@ -150,7 +149,7 @@ import { WorldStateSynchronizerError } from './errors.js';
150
149
  this.log.debug(`World State at ${currentBlockNumber} told to sync to ${targetBlockNumber ?? 'latest'}`);
151
150
  // If the archiver is behind the target block, force an archiver sync
152
151
  if (targetBlockNumber) {
153
- const archiverLatestBlock = await this.l2BlockSource.getBlockNumber();
152
+ const archiverLatestBlock = BlockNumber(await this.l2BlockSource.getBlockNumber());
154
153
  if (archiverLatestBlock < targetBlockNumber) {
155
154
  this.log.debug(`Archiver is at ${archiverLatestBlock} behind target block ${targetBlockNumber}.`);
156
155
  await this.l2BlockSource.syncImmediate();
@@ -173,7 +172,7 @@ import { WorldStateSynchronizerError } from './errors.js';
173
172
  return updatedBlockNumber;
174
173
  }
175
174
  /** Returns the L2 block hash for a given number. Used by the L2BlockStream for detecting reorgs. */ async getL2BlockHash(number) {
176
- if (number === 0) {
175
+ if (number === BlockNumber.ZERO) {
177
176
  return (await this.merkleTreeCommitted.getInitialHeader().hash()).toString();
178
177
  }
179
178
  if (this.latestBlockHashQuery?.hash === undefined || number !== this.latestBlockHashQuery.blockNumber) {
@@ -186,19 +185,19 @@ import { WorldStateSynchronizerError } from './errors.js';
186
185
  }
187
186
  /** Returns the latest L2 block number for each tip of the chain (latest, proven, finalized). */ async getL2Tips() {
188
187
  const status = await this.merkleTreeDb.getStatusSummary();
189
- const unfinalizedBlockHash = await this.getL2BlockHash(Number(status.unfinalizedBlockNumber));
188
+ const unfinalizedBlockHash = await this.getL2BlockHash(status.unfinalizedBlockNumber);
190
189
  const latestBlockId = {
191
- number: Number(status.unfinalizedBlockNumber),
190
+ number: status.unfinalizedBlockNumber,
192
191
  hash: unfinalizedBlockHash
193
192
  };
194
193
  return {
195
194
  latest: latestBlockId,
196
195
  finalized: {
197
- number: Number(status.finalizedBlockNumber),
196
+ number: status.finalizedBlockNumber,
198
197
  hash: ''
199
198
  },
200
199
  proven: {
201
- number: Number(this.provenBlockNumber ?? status.finalizedBlockNumber),
200
+ number: this.provenBlockNumber ?? status.finalizedBlockNumber,
202
201
  hash: ''
203
202
  }
204
203
  };
@@ -206,16 +205,16 @@ import { WorldStateSynchronizerError } from './errors.js';
206
205
  /** Handles an event emitted by the block stream. */ async handleBlockStreamEvent(event) {
207
206
  switch(event.type){
208
207
  case 'blocks-added':
209
- await this.handleL2Blocks(event.blocks.map((b)=>b.block));
208
+ await this.handleL2Blocks(event.blocks.map((b)=>b.block.toL2Block()));
210
209
  break;
211
210
  case 'chain-pruned':
212
- await this.handleChainPruned(event.block.number);
211
+ await this.handleChainPruned(BlockNumber(event.block.number));
213
212
  break;
214
213
  case 'chain-proven':
215
- await this.handleChainProven(event.block.number);
214
+ await this.handleChainProven(BlockNumber(event.block.number));
216
215
  break;
217
216
  case 'chain-finalized':
218
- await this.handleChainFinalized(event.block.number);
217
+ await this.handleChainFinalized(BlockNumber(event.block.number));
219
218
  break;
220
219
  }
221
220
  }
@@ -225,18 +224,19 @@ import { WorldStateSynchronizerError } from './errors.js';
225
224
  * @returns Whether the block handled was produced by this same node.
226
225
  */ async handleL2Blocks(l2Blocks) {
227
226
  this.log.trace(`Handling L2 blocks ${l2Blocks[0].number} to ${l2Blocks.at(-1).number}`);
228
- const messagePromises = l2Blocks.map((block)=>this.l2BlockSource.getL1ToL2Messages(block.number));
229
- const l1ToL2Messages = await Promise.all(messagePromises);
227
+ const firstBlocksInCheckpoints = await findFirstBlocksInCheckpoints(l2Blocks, this.l2BlockSource);
230
228
  let updateStatus = undefined;
231
- for(let i = 0; i < l2Blocks.length; i++){
232
- const [duration, result] = await elapsed(()=>this.handleL2Block(l2Blocks[i], l1ToL2Messages[i]));
233
- this.log.info(`World state updated with L2 block ${l2Blocks[i].number}`, {
229
+ for (const block of l2Blocks){
230
+ const l1ToL2Messages = firstBlocksInCheckpoints.get(block.number) ?? [];
231
+ const isFirstBlock = firstBlocksInCheckpoints.has(block.number);
232
+ const [duration, result] = await elapsed(()=>this.handleL2Block(block, l1ToL2Messages, isFirstBlock));
233
+ this.log.info(`World state updated with L2 block ${block.number}`, {
234
234
  eventName: 'l2-block-handled',
235
235
  duration,
236
- unfinalizedBlockNumber: result.summary.unfinalizedBlockNumber,
237
- finalizedBlockNumber: result.summary.finalizedBlockNumber,
238
- oldestHistoricBlock: result.summary.oldestHistoricalBlock,
239
- ...l2Blocks[i].getStats()
236
+ unfinalizedBlockNumber: BigInt(result.summary.unfinalizedBlockNumber),
237
+ finalizedBlockNumber: BigInt(result.summary.finalizedBlockNumber),
238
+ oldestHistoricBlock: BigInt(result.summary.oldestHistoricalBlock),
239
+ ...block.getStats()
240
240
  });
241
241
  updateStatus = result;
242
242
  }
@@ -250,19 +250,14 @@ import { WorldStateSynchronizerError } from './errors.js';
250
250
  * @param l2Block - The L2 block to handle.
251
251
  * @param l1ToL2Messages - The L1 to L2 messages for the block.
252
252
  * @returns Whether the block handled was produced by this same node.
253
- */ async handleL2Block(l2Block, l1ToL2Messages) {
254
- // First we check that the L1 to L2 messages hash to the block inHash.
255
- // Note that we cannot optimize this check by checking the root of the subtree after inserting the messages
256
- // to the real L1_TO_L2_MESSAGE_TREE (like we do in merkleTreeDb.handleL2BlockAndMessages(...)) because that
257
- // tree uses pedersen and we don't have access to the converted root.
258
- await this.verifyMessagesHashToInHash(l1ToL2Messages, l2Block.header.contentCommitment.inHash);
253
+ */ async handleL2Block(l2Block, l1ToL2Messages, isFirstBlock) {
259
254
  // If the above check succeeds, we can proceed to handle the block.
260
255
  this.log.trace(`Pushing L2 block ${l2Block.number} to merkle tree db `, {
261
256
  blockNumber: l2Block.number,
262
257
  blockHash: await l2Block.hash().then((h)=>h.toString()),
263
258
  l1ToL2Messages: l1ToL2Messages.map((msg)=>msg.toString())
264
259
  });
265
- const result = await this.merkleTreeDb.handleL2BlockAndMessages(l2Block, l1ToL2Messages);
260
+ const result = await this.merkleTreeDb.handleL2BlockAndMessages(l2Block, l1ToL2Messages, isFirstBlock);
266
261
  if (this.currentState === WorldStateRunningState.SYNCHING && l2Block.number >= this.latestBlockNumberAtStart) {
267
262
  this.setCurrentState(WorldStateRunningState.RUNNING);
268
263
  this.syncPromise.resolve();
@@ -271,12 +266,12 @@ import { WorldStateSynchronizerError } from './errors.js';
271
266
  }
272
267
  async handleChainFinalized(blockNumber) {
273
268
  this.log.verbose(`Finalized chain is now at block ${blockNumber}`);
274
- const summary = await this.merkleTreeDb.setFinalized(BigInt(blockNumber));
269
+ const summary = await this.merkleTreeDb.setFinalized(blockNumber);
275
270
  if (this.historyToKeep === undefined) {
276
271
  return;
277
272
  }
278
- const newHistoricBlock = summary.finalizedBlockNumber - BigInt(this.historyToKeep) + 1n;
279
- if (newHistoricBlock <= 1) {
273
+ const newHistoricBlock = BlockNumber(summary.finalizedBlockNumber - this.historyToKeep + 1);
274
+ if (newHistoricBlock <= BlockNumber(1)) {
280
275
  return;
281
276
  }
282
277
  this.log.verbose(`Pruning historic blocks to ${newHistoricBlock}`);
@@ -284,13 +279,13 @@ import { WorldStateSynchronizerError } from './errors.js';
284
279
  this.log.debug(`World state summary `, status.summary);
285
280
  }
286
281
  handleChainProven(blockNumber) {
287
- this.provenBlockNumber = BigInt(blockNumber);
282
+ this.provenBlockNumber = blockNumber;
288
283
  this.log.debug(`Proven chain is now at block ${blockNumber}`);
289
284
  return Promise.resolve();
290
285
  }
291
286
  async handleChainPruned(blockNumber) {
292
287
  this.log.warn(`Chain pruned to block ${blockNumber}`);
293
- const status = await this.merkleTreeDb.unwindBlocks(BigInt(blockNumber));
288
+ const status = await this.merkleTreeDb.unwindBlocks(blockNumber);
294
289
  this.latestBlockHashQuery = undefined;
295
290
  this.provenBlockNumber = undefined;
296
291
  this.instrumentation.updateWorldStateMetrics(status);
@@ -302,16 +297,4 @@ import { WorldStateSynchronizerError } from './errors.js';
302
297
  this.currentState = newState;
303
298
  this.log.debug(`Moved to state ${WorldStateRunningState[this.currentState]}`);
304
299
  }
305
- /**
306
- * Verifies that the L1 to L2 messages hash to the block inHash.
307
- * @param l1ToL2Messages - The L1 to L2 messages for the block.
308
- * @param inHash - The inHash of the block.
309
- * @throws If the L1 to L2 messages do not hash to the block inHash.
310
- */ async verifyMessagesHashToInHash(l1ToL2Messages, inHash) {
311
- const treeCalculator = await MerkleTreeCalculator.create(L1_TO_L2_MSG_SUBTREE_HEIGHT, Buffer.alloc(32), (lhs, rhs)=>Promise.resolve(new SHA256Trunc().hash(lhs, rhs)));
312
- const root = await treeCalculator.computeTreeRoot(l1ToL2Messages.map((msg)=>msg.toBuffer()));
313
- if (!root.equals(inHash.toBuffer())) {
314
- throw new Error('Obtained L1 to L2 messages failed to be hashed to the block inHash');
315
- }
316
- }
317
300
  }
@@ -0,0 +1,11 @@
1
+ import type { Fr } from '@aztec/foundation/fields';
2
+ import type { L2BlockNew, L2BlockSource } from '@aztec/stdlib/block';
3
+ import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
4
+ /**
5
+ * Determine which blocks in the given array are the first block in a checkpoint.
6
+ * @param blocks - The candidate blocks, sorted by block number in ascending order.
7
+ * @param l2BlockSource - The L2 block source to use to fetch the checkpoints, block headers and L1->L2 messages.
8
+ * @returns A map of block numbers that begin a checkpoint to the L1->L2 messages for that checkpoint.
9
+ */
10
+ export declare function findFirstBlocksInCheckpoints(blocks: L2BlockNew[], l2BlockSource: L2BlockSource & L1ToL2MessageSource): Promise<Map<number, Fr[]>>;
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zeW5jaHJvbml6ZXIvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXJFLE9BQU8sRUFBRSxLQUFLLG1CQUFtQixFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBRXBHOzs7OztHQUtHO0FBQ0gsd0JBQXNCLDRCQUE0QixDQUNoRCxNQUFNLEVBQUUsVUFBVSxFQUFFLEVBQ3BCLGFBQWEsRUFBRSxhQUFhLEdBQUcsbUJBQW1CLEdBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FtRTVCIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/synchronizer/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,KAAK,mBAAmB,EAAmC,MAAM,yBAAyB,CAAC;AAEpG;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,UAAU,EAAE,EACpB,aAAa,EAAE,aAAa,GAAG,mBAAmB,GACjD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAmE5B"}
@@ -0,0 +1,59 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
2
+ import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
3
+ /**
4
+ * Determine which blocks in the given array are the first block in a checkpoint.
5
+ * @param blocks - The candidate blocks, sorted by block number in ascending order.
6
+ * @param l2BlockSource - The L2 block source to use to fetch the checkpoints, block headers and L1->L2 messages.
7
+ * @returns A map of block numbers that begin a checkpoint to the L1->L2 messages for that checkpoint.
8
+ */ export async function findFirstBlocksInCheckpoints(blocks, l2BlockSource) {
9
+ // Select the blocks that are the final block within each group of identical slot numbers.
10
+ let seenSlot;
11
+ const maybeLastBlocks = [
12
+ ...blocks
13
+ ].reverse().filter((b)=>{
14
+ if (b.header.globalVariables.slotNumber !== seenSlot) {
15
+ seenSlot = b.header.globalVariables.slotNumber;
16
+ return true;
17
+ }
18
+ return false;
19
+ }).reverse();
20
+ // Try to fetch the checkpoints for those blocks. If undefined (which should only occur for blocks.at(-1)),
21
+ // then the block is not the last one in a checkpoint.
22
+ // If we are not checking the inHashes below, only blocks.at(-1) would need its checkpoint header fetched.
23
+ const checkpointedBlocks = (await Promise.all(maybeLastBlocks.map(async (b)=>({
24
+ blockNumber: b.number,
25
+ // A checkpoint's archive root is the archive root of its last block.
26
+ checkpoint: await l2BlockSource.getCheckpointByArchive(b.archive.root)
27
+ })))).filter((b)=>b.checkpoint !== undefined);
28
+ // Verify that the L1->L2 messages hash to the checkpoint's inHash.
29
+ const checkpointedL1ToL2Messages = await Promise.all(checkpointedBlocks.map((b)=>l2BlockSource.getL1ToL2MessagesForCheckpoint(b.checkpoint.number)));
30
+ checkpointedBlocks.forEach((b, i)=>{
31
+ const computedInHash = computeInHashFromL1ToL2Messages(checkpointedL1ToL2Messages[i]);
32
+ const inHash = b.checkpoint.header.contentCommitment.inHash;
33
+ if (!computedInHash.equals(inHash)) {
34
+ throw new Error('Obtained L1 to L2 messages failed to be hashed to the checkpoint inHash');
35
+ }
36
+ });
37
+ // Compute the first block numbers, which should be right after each checkpointed block. Exclude blocks that haven't
38
+ // been added yet.
39
+ const firstBlockNumbers = checkpointedBlocks.map((b)=>BlockNumber(b.blockNumber + 1)).filter((n)=>n <= blocks.at(-1).number);
40
+ // Check if blocks[0] is the first block in a checkpoint.
41
+ if (blocks[0].number === 1) {
42
+ firstBlockNumbers.push(blocks[0].number);
43
+ } else {
44
+ const lastBlockHeader = await l2BlockSource.getBlockHeader(BlockNumber(blocks[0].number - 1));
45
+ if (!lastBlockHeader) {
46
+ throw new Error(`Failed to get block ${blocks[0].number - 1}`);
47
+ }
48
+ if (lastBlockHeader.globalVariables.slotNumber !== blocks[0].header.globalVariables.slotNumber) {
49
+ firstBlockNumbers.push(blocks[0].number);
50
+ }
51
+ }
52
+ // Fetch the L1->L2 messages for the first blocks and assign them to the map.
53
+ const messagesByBlockNumber = new Map();
54
+ await Promise.all(firstBlockNumbers.map(async (blockNumber)=>{
55
+ const l1ToL2Messages = await l2BlockSource.getL1ToL2Messages(blockNumber);
56
+ messagesByBlockNumber.set(blockNumber, l1ToL2Messages);
57
+ }));
58
+ return messagesByBlockNumber;
59
+ }
@@ -1,19 +1,32 @@
1
+ import { BlockNumber, type CheckpointNumber } from '@aztec/foundation/branded-types';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
- import { L2Block } from '@aztec/stdlib/block';
3
+ import { L2BlockNew } from '@aztec/stdlib/block';
4
+ import { Checkpoint } from '@aztec/stdlib/checkpoint';
3
5
  import type { MerkleTreeReadOperations, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
4
6
  import type { NativeWorldStateService } from '../native/native_world_state.js';
5
- export declare function mockBlock(blockNum: number, size: number, fork: MerkleTreeWriteOperations, maxEffects?: number | undefined): Promise<{
6
- block: L2Block;
7
+ export declare function mockBlock(blockNum: BlockNumber, size: number, fork: MerkleTreeWriteOperations, maxEffects?: number | undefined, numL1ToL2Messages?: number, isFirstBlock?: boolean): Promise<{
8
+ block: L2BlockNew;
7
9
  messages: Fr[];
8
10
  }>;
9
- export declare function mockEmptyBlock(blockNum: number, fork: MerkleTreeWriteOperations): Promise<{
10
- block: L2Block;
11
+ export declare function mockEmptyBlock(blockNum: BlockNumber, fork: MerkleTreeWriteOperations): Promise<{
12
+ block: L2BlockNew;
11
13
  messages: Fr[];
12
14
  }>;
13
- export declare function mockBlocks(from: number, count: number, numTxs: number, worldState: NativeWorldStateService): Promise<{
14
- blocks: L2Block[];
15
+ export declare function mockBlocks(from: BlockNumber, count: number, numTxs: number, worldState: NativeWorldStateService): Promise<{
16
+ blocks: L2BlockNew[];
15
17
  messages: Fr[][];
16
18
  }>;
19
+ export declare function mockL1ToL2Messages(numL1ToL2Messages: number): Fr[];
20
+ export declare function mockCheckpoint(checkpointNumber: CheckpointNumber, { startBlockNumber, numBlocks, numTxsPerBlock, numL1ToL2Messages, fork }?: {
21
+ startBlockNumber?: BlockNumber;
22
+ numBlocks?: number;
23
+ numTxsPerBlock?: number;
24
+ numL1ToL2Messages?: number;
25
+ fork?: MerkleTreeWriteOperations;
26
+ }): Promise<{
27
+ checkpoint: Checkpoint;
28
+ messages: Fr[];
29
+ }>;
17
30
  export declare function assertSameState(forkA: MerkleTreeReadOperations, forkB: MerkleTreeReadOperations): Promise<void>;
18
31
  export declare function compareChains(left: MerkleTreeReadOperations, right: MerkleTreeReadOperations): Promise<void>;
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxLQUFLLEVBRVYsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUMxQixNQUFNLGlDQUFpQyxDQUFDO0FBR3pDLE9BQU8sS0FBSyxFQUFFLHVCQUF1QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFL0Usd0JBQXNCLFNBQVMsQ0FDN0IsUUFBUSxFQUFFLE1BQU0sRUFDaEIsSUFBSSxFQUFFLE1BQU0sRUFDWixJQUFJLEVBQUUseUJBQXlCLEVBQy9CLFVBQVUsR0FBRSxNQUFNLEdBQUcsU0FBZ0I7OztHQXNEdEM7QUFFRCx3QkFBc0IsY0FBYyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLHlCQUF5Qjs7O0dBaURyRjtBQUVELHdCQUFzQixVQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLHVCQUF1Qjs7O0dBY2hIO0FBRUQsd0JBQXNCLGVBQWUsQ0FBQyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsS0FBSyxFQUFFLHdCQUF3QixpQkFRckc7QUFFRCx3QkFBc0IsYUFBYSxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsd0JBQXdCLGlCQVlsRyJ9
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFBRSxXQUFXLEVBQUUsS0FBSyxnQkFBZ0IsRUFBYyxNQUFNLGlDQUFpQyxDQUFDO0FBRWpHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sS0FBSyxFQUVWLHdCQUF3QixFQUN4Qix5QkFBeUIsRUFDMUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUl6QyxPQUFPLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRS9FLHdCQUFzQixTQUFTLENBQzdCLFFBQVEsRUFBRSxXQUFXLEVBQ3JCLElBQUksRUFBRSxNQUFNLEVBQ1osSUFBSSxFQUFFLHlCQUF5QixFQUMvQixVQUFVLEdBQUUsTUFBTSxHQUFHLFNBQWdCLEVBQ3JDLGlCQUFpQixHQUFFLE1BQTRDLEVBQy9ELFlBQVksR0FBRSxPQUFjOzs7R0F3RDdCO0FBRUQsd0JBQXNCLGNBQWMsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSx5QkFBeUI7OztHQWlEMUY7QUFFRCx3QkFBc0IsVUFBVSxDQUM5QixJQUFJLEVBQUUsV0FBVyxFQUNqQixLQUFLLEVBQUUsTUFBTSxFQUNiLE1BQU0sRUFBRSxNQUFNLEVBQ2QsVUFBVSxFQUFFLHVCQUF1Qjs7O0dBZXBDO0FBRUQsd0JBQWdCLGtCQUFrQixDQUFDLGlCQUFpQixFQUFFLE1BQU0sUUFFM0Q7QUFFRCx3QkFBc0IsY0FBYyxDQUNsQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFDbEMsRUFDRSxnQkFBaUMsRUFDakMsU0FBYSxFQUNiLGNBQWtCLEVBQ2xCLGlCQUFxQixFQUNyQixJQUFJLEVBQ0wsR0FBRTtJQUNELGdCQUFnQixDQUFDLEVBQUUsV0FBVyxDQUFDO0lBQy9CLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNuQixjQUFjLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDeEIsaUJBQWlCLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDM0IsSUFBSSxDQUFDLEVBQUUseUJBQXlCLENBQUM7Q0FDN0I7OztHQXFCUDtBQUVELHdCQUFzQixlQUFlLENBQUMsS0FBSyxFQUFFLHdCQUF3QixFQUFFLEtBQUssRUFBRSx3QkFBd0IsaUJBUXJHO0FBRUQsd0JBQXNCLGFBQWEsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUUsS0FBSyxFQUFFLHdCQUF3QixpQkFZbEcifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EAEV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,yBAAyB,EAC/B,UAAU,GAAE,MAAM,GAAG,SAAgB;;;GAsDtC;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB;;;GAiDrF;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,uBAAuB;;;GAchH;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,wBAAwB,iBAQrG;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,wBAAwB,iBAYlG"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAc,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAEV,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,yBAAyB,EAC/B,UAAU,GAAE,MAAM,GAAG,SAAgB,EACrC,iBAAiB,GAAE,MAA4C,EAC/D,YAAY,GAAE,OAAc;;;GAwD7B;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB;;;GAiD1F;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,uBAAuB;;;GAepC;AAED,wBAAgB,kBAAkB,CAAC,iBAAiB,EAAE,MAAM,QAE3D;AAED,wBAAsB,cAAc,CAClC,gBAAgB,EAAE,gBAAgB,EAClC,EACE,gBAAiC,EACjC,SAAa,EACb,cAAkB,EAClB,iBAAqB,EACrB,IAAI,EACL,GAAE;IACD,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,yBAAyB,CAAC;CAC7B;;;GAqBP;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,wBAAwB,iBAQrG;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,wBAAwB,iBAYlG"}
@@ -1,11 +1,19 @@
1
1
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
2
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
3
  import { padArrayEnd } from '@aztec/foundation/collection';
3
4
  import { Fr } from '@aztec/foundation/fields';
4
- import { L2Block } from '@aztec/stdlib/block';
5
+ import { L2BlockNew } from '@aztec/stdlib/block';
6
+ import { Checkpoint } from '@aztec/stdlib/checkpoint';
7
+ import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
5
8
  import { AppendOnlyTreeSnapshot, MerkleTreeId } from '@aztec/stdlib/trees';
6
- export async function mockBlock(blockNum, size, fork, maxEffects = 1000) {
7
- const l2Block = await L2Block.random(blockNum, size, undefined, undefined, undefined, undefined, maxEffects);
8
- const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.random);
9
+ export async function mockBlock(blockNum, size, fork, maxEffects = 1000, numL1ToL2Messages = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, isFirstBlock = true) {
10
+ const l2Block = await L2BlockNew.random(blockNum, {
11
+ txsPerBlock: size,
12
+ txOptions: {
13
+ maxEffects
14
+ }
15
+ });
16
+ const l1ToL2Messages = mockL1ToL2Messages(numL1ToL2Messages);
9
17
  {
10
18
  const insertData = async (treeId, data, subTreeHeight, fork)=>{
11
19
  for (const dataBatch of data){
@@ -15,7 +23,7 @@ export async function mockBlock(blockNum, size, fork, maxEffects = 1000) {
15
23
  const publicDataInsert = insertData(MerkleTreeId.PUBLIC_DATA_TREE, l2Block.body.txEffects.map((txEffect)=>txEffect.publicDataWrites.map((write)=>write.toBuffer())), 0, fork);
16
24
  const nullifierInsert = insertData(MerkleTreeId.NULLIFIER_TREE, l2Block.body.txEffects.map((txEffect)=>padArrayEnd(txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map((nullifier)=>nullifier.toBuffer())), NULLIFIER_SUBTREE_HEIGHT, fork);
17
25
  const noteHashesPadded = l2Block.body.txEffects.flatMap((txEffect)=>padArrayEnd(txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX));
18
- const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
26
+ const l1ToL2MessagesPadded = isFirstBlock ? padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP) : l1ToL2Messages;
19
27
  const noteHashInsert = fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashesPadded);
20
28
  const messageInsert = fork.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
21
29
  await Promise.all([
@@ -27,7 +35,7 @@ export async function mockBlock(blockNum, size, fork, maxEffects = 1000) {
27
35
  }
28
36
  const state = await fork.getStateReference();
29
37
  l2Block.header.state = state;
30
- await fork.updateArchive(l2Block.getBlockHeader());
38
+ await fork.updateArchive(l2Block.header);
31
39
  const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
32
40
  l2Block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size));
33
41
  return {
@@ -36,7 +44,7 @@ export async function mockBlock(blockNum, size, fork, maxEffects = 1000) {
36
44
  };
37
45
  }
38
46
  export async function mockEmptyBlock(blockNum, fork) {
39
- const l2Block = L2Block.empty();
47
+ const l2Block = L2BlockNew.empty();
40
48
  const l1ToL2Messages = Array(16).fill(0).map(Fr.zero);
41
49
  l2Block.header.globalVariables.blockNumber = blockNum;
42
50
  // Sync the append only trees
@@ -57,7 +65,7 @@ export async function mockEmptyBlock(blockNum, fork) {
57
65
  }
58
66
  const state = await fork.getStateReference();
59
67
  l2Block.header.state = state;
60
- await fork.updateArchive(l2Block.getBlockHeader());
68
+ await fork.updateArchive(l2Block.header);
61
69
  const archiveState = await fork.getTreeInfo(MerkleTreeId.ARCHIVE);
62
70
  l2Block.archive = new AppendOnlyTreeSnapshot(Fr.fromBuffer(archiveState.root), Number(archiveState.size));
63
71
  return {
@@ -66,11 +74,11 @@ export async function mockEmptyBlock(blockNum, fork) {
66
74
  };
67
75
  }
68
76
  export async function mockBlocks(from, count, numTxs, worldState) {
69
- const tempFork = await worldState.fork(from - 1);
77
+ const tempFork = await worldState.fork(BlockNumber(from - 1));
70
78
  const blocks = [];
71
79
  const messagesArray = [];
72
80
  for(let blockNumber = from; blockNumber < from + count; blockNumber++){
73
- const { block, messages } = await mockBlock(blockNumber, numTxs, tempFork);
81
+ const { block, messages } = await mockBlock(BlockNumber(blockNumber), numTxs, tempFork);
74
82
  blocks.push(block);
75
83
  messagesArray.push(messages);
76
84
  }
@@ -80,6 +88,39 @@ export async function mockBlocks(from, count, numTxs, worldState) {
80
88
  messages: messagesArray
81
89
  };
82
90
  }
91
+ export function mockL1ToL2Messages(numL1ToL2Messages) {
92
+ return Array(numL1ToL2Messages).fill(0).map(Fr.random);
93
+ }
94
+ export async function mockCheckpoint(checkpointNumber, { startBlockNumber = BlockNumber(1), numBlocks = 1, numTxsPerBlock = 1, numL1ToL2Messages = 1, fork } = {}) {
95
+ const slotNumber = SlotNumber(checkpointNumber * 10);
96
+ const blocksAndMessages = [];
97
+ for(let i = 0; i < numBlocks; i++){
98
+ const blockNumber = BlockNumber(startBlockNumber + i);
99
+ const { block, messages } = fork ? await mockBlock(blockNumber, numTxsPerBlock, fork, blockNumber === startBlockNumber ? numL1ToL2Messages : 0) : {
100
+ block: await L2BlockNew.random(blockNumber, {
101
+ txsPerBlock: numTxsPerBlock,
102
+ slotNumber
103
+ }),
104
+ messages: mockL1ToL2Messages(numL1ToL2Messages)
105
+ };
106
+ blocksAndMessages.push({
107
+ block,
108
+ messages
109
+ });
110
+ }
111
+ const messages = blocksAndMessages[0].messages;
112
+ const inHash = computeInHashFromL1ToL2Messages(messages);
113
+ const checkpoint = await Checkpoint.random(checkpointNumber, {
114
+ numBlocks: 0,
115
+ slotNumber,
116
+ inHash
117
+ });
118
+ checkpoint.blocks = blocksAndMessages.map(({ block })=>block);
119
+ return {
120
+ checkpoint,
121
+ messages
122
+ };
123
+ }
83
124
  export async function assertSameState(forkA, forkB) {
84
125
  const nativeStateRef = await forkA.getStateReference();
85
126
  const nativeArchive = await forkA.getTreeInfo(MerkleTreeId.ARCHIVE);
@@ -1,6 +1,7 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import type { Fr } from '@aztec/foundation/fields';
2
3
  import type { IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree';
3
- import type { L2Block, L2BlockNew } from '@aztec/stdlib/block';
4
+ import type { L2BlockNew } from '@aztec/stdlib/block';
4
5
  import type { ForkMerkleTreeOperations, MerkleTreeReadOperations } from '@aztec/stdlib/interfaces/server';
5
6
  import type { MerkleTreeId } from '@aztec/stdlib/trees';
6
7
  import type { WorldStateStatusFull, WorldStateStatusSummary } from '../native/message.js';
@@ -33,10 +34,10 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
33
34
  * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
34
35
  * @param block - The L2 block to handle.
35
36
  * @param l1ToL2Messages - The L1 to L2 messages for the block.
36
- * @param isFirstBlock - Whether the block is the first block in a checkpoint. Temporary hack to only insert l1 to l2
37
- * messages for the first block in a checkpoint. TODO(#17027) Remove this.
37
+ * @param isFirstBlock - Whether the block is the first block in a checkpoint. The messages are padded and inserted
38
+ * to the tree for the first block in a checkpoint.
38
39
  */
39
- handleL2BlockAndMessages(block: L2Block | L2BlockNew, l1ToL2Messages: Fr[], isFirstBlock?: boolean): Promise<WorldStateStatusFull>;
40
+ handleL2BlockAndMessages(block: L2BlockNew, l1ToL2Messages: Fr[], isFirstBlock: boolean): Promise<WorldStateStatusFull>;
40
41
  /**
41
42
  * Gets a handle that allows reading the latest committed state
42
43
  */
@@ -46,19 +47,19 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
46
47
  * @param toBlockNumber The block number of the new oldest historical block
47
48
  * @returns The new WorldStateStatus
48
49
  */
49
- removeHistoricalBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
50
+ removeHistoricalBlocks(toBlockNumber: BlockNumber): Promise<WorldStateStatusFull>;
50
51
  /**
51
52
  * Removes all pending blocks down to but not including the given block number
52
53
  * @param toBlockNumber The block number of the new tip of the pending chain,
53
54
  * @returns The new WorldStateStatus
54
55
  */
55
- unwindBlocks(toBlockNumber: bigint): Promise<WorldStateStatusFull>;
56
+ unwindBlocks(toBlockNumber: BlockNumber): Promise<WorldStateStatusFull>;
56
57
  /**
57
58
  * Advances the finalized block number to be the number provided
58
59
  * @param toBlockNumber The block number that is now the tip of the finalized chain
59
60
  * @returns The new WorldStateStatus
60
61
  */
61
- setFinalized(toBlockNumber: bigint): Promise<WorldStateStatusSummary>;
62
+ setFinalized(toBlockNumber: BlockNumber): Promise<WorldStateStatusSummary>;
62
63
  /**
63
64
  * Gets the current status summary of the database.
64
65
  * @returns The current WorldStateStatus.
@@ -69,4 +70,4 @@ export interface MerkleTreeAdminDatabase extends ForkMerkleTreeOperations {
69
70
  /** Deletes the db. */
70
71
  clear(): Promise<void>;
71
72
  }
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVfZGIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3JsZC1zdGF0ZS1kYi9tZXJrbGVfdHJlZV9kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNuRCxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1RSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDL0QsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRyxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV4RCxPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTFGOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsZUFBTyxNQUFNLDJCQUEyQixRQUE0QixDQUFDO0FBRXJFLGVBQU8sTUFBTSw2QkFBNkIsUUFBbUQsQ0FBQztBQUU5RixNQUFNLE1BQU0sYUFBYSxHQUFHO0lBQzFCLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQ25ELENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNoRCxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQ3JELENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztDQUMxQyxDQUFDO0FBRUYsTUFBTSxXQUFXLHVCQUF3QixTQUFRLHdCQUF3QjtJQUN2RTs7Ozs7O09BTUc7SUFDSCx3QkFBd0IsQ0FDdEIsS0FBSyxFQUFFLE9BQU8sR0FBRyxVQUFVLEVBQzNCLGNBQWMsRUFBRSxFQUFFLEVBQUUsRUFDcEIsWUFBWSxDQUFDLEVBQUUsT0FBTyxHQUNyQixPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUVqQzs7T0FFRztJQUNILFlBQVksSUFBSSx3QkFBd0IsQ0FBQztJQUV6Qzs7OztPQUlHO0lBQ0gsc0JBQXNCLENBQUMsYUFBYSxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUU3RTs7OztPQUlHO0lBQ0gsWUFBWSxDQUFDLGFBQWEsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFFbkU7Ozs7T0FJRztJQUNILFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBRXRFOzs7T0FHRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBRXJELHlCQUF5QjtJQUN6QixLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXZCLHNCQUFzQjtJQUN0QixLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ3hCIn0=
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVya2xlX3RyZWVfZGIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3JsZC1zdGF0ZS1kYi9tZXJrbGVfdHJlZV9kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRyxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV4RCxPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTFGOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsZUFBTyxNQUFNLDJCQUEyQixRQUE0QixDQUFDO0FBRXJFLGVBQU8sTUFBTSw2QkFBNkIsUUFBbUQsQ0FBQztBQUU5RixNQUFNLE1BQU0sYUFBYSxHQUFHO0lBQzFCLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQ25ELENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNoRCxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQ3JELENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztDQUMxQyxDQUFDO0FBRUYsTUFBTSxXQUFXLHVCQUF3QixTQUFRLHdCQUF3QjtJQUN2RTs7Ozs7O09BTUc7SUFDSCx3QkFBd0IsQ0FDdEIsS0FBSyxFQUFFLFVBQVUsRUFDakIsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQixZQUFZLEVBQUUsT0FBTyxHQUNwQixPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUVqQzs7T0FFRztJQUNILFlBQVksSUFBSSx3QkFBd0IsQ0FBQztJQUV6Qzs7OztPQUlHO0lBQ0gsc0JBQXNCLENBQUMsYUFBYSxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUVsRjs7OztPQUlHO0lBQ0gsWUFBWSxDQUFDLGFBQWEsRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFFeEU7Ozs7T0FJRztJQUNILFlBQVksQ0FBQyxhQUFhLEVBQUUsV0FBVyxHQUFHLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBRTNFOzs7T0FHRztJQUNILGdCQUFnQixJQUFJLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBRXJELHlCQUF5QjtJQUN6QixLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXZCLHNCQUFzQjtJQUN0QixLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0NBQ3hCIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"merkle_tree_db.d.ts","sourceRoot":"","sources":["../../src/world-state-db/merkle_tree_db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC1G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE1F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,QAA4B,CAAC;AAErE,eAAO,MAAM,6BAA6B,QAAmD,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACnD,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IACrD,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE;;;;;;OAMG;IACH,wBAAwB,CACtB,KAAK,EAAE,OAAO,GAAG,UAAU,EAC3B,cAAc,EAAE,EAAE,EAAE,EACpB,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;OAEG;IACH,YAAY,IAAI,wBAAwB,CAAC;IAEzC;;;;OAIG;IACH,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAE7E;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEnE;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAEtE;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAErD,yBAAyB;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,sBAAsB;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
1
+ {"version":3,"file":"merkle_tree_db.d.ts","sourceRoot":"","sources":["../../src/world-state-db/merkle_tree_db.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC1G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE1F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,QAA4B,CAAC;AAErE,eAAO,MAAM,6BAA6B,QAAmD,CAAC;AAE9F,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACnD,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IACrD,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE;;;;;;OAMG;IACH,wBAAwB,CACtB,KAAK,EAAE,UAAU,EACjB,cAAc,EAAE,EAAE,EAAE,EACpB,YAAY,EAAE,OAAO,GACpB,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;OAEG;IACH,YAAY,IAAI,wBAAwB,CAAC;IAEzC;;;;OAIG;IACH,sBAAsB,CAAC,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAElF;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAExE;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAE3E;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAErD,yBAAyB;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,sBAAsB;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/world-state",
3
- "version": "0.0.1-commit.9b94fc1",
3
+ "version": "0.0.1-commit.d3ec352c",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -18,8 +18,8 @@
18
18
  "tsconfig": "./tsconfig.json"
19
19
  },
20
20
  "scripts": {
21
- "build": "yarn clean && tsgo -b",
22
- "build:dev": "tsgo -b --watch",
21
+ "build": "yarn clean && ../scripts/tsc.sh",
22
+ "build:dev": "../scripts/tsc.sh --watch",
23
23
  "clean": "rm -rf ./dest .tsbuildinfo",
24
24
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
25
25
  },
@@ -64,19 +64,19 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "0.0.1-commit.9b94fc1",
68
- "@aztec/foundation": "0.0.1-commit.9b94fc1",
69
- "@aztec/kv-store": "0.0.1-commit.9b94fc1",
70
- "@aztec/merkle-tree": "0.0.1-commit.9b94fc1",
71
- "@aztec/native": "0.0.1-commit.9b94fc1",
72
- "@aztec/protocol-contracts": "0.0.1-commit.9b94fc1",
73
- "@aztec/stdlib": "0.0.1-commit.9b94fc1",
74
- "@aztec/telemetry-client": "0.0.1-commit.9b94fc1",
67
+ "@aztec/constants": "0.0.1-commit.d3ec352c",
68
+ "@aztec/foundation": "0.0.1-commit.d3ec352c",
69
+ "@aztec/kv-store": "0.0.1-commit.d3ec352c",
70
+ "@aztec/merkle-tree": "0.0.1-commit.d3ec352c",
71
+ "@aztec/native": "0.0.1-commit.d3ec352c",
72
+ "@aztec/protocol-contracts": "0.0.1-commit.d3ec352c",
73
+ "@aztec/stdlib": "0.0.1-commit.d3ec352c",
74
+ "@aztec/telemetry-client": "0.0.1-commit.d3ec352c",
75
75
  "tslib": "^2.4.0",
76
76
  "zod": "^3.23.8"
77
77
  },
78
78
  "devDependencies": {
79
- "@aztec/archiver": "0.0.1-commit.9b94fc1",
79
+ "@aztec/archiver": "0.0.1-commit.d3ec352c",
80
80
  "@jest/globals": "^30.0.0",
81
81
  "@types/jest": "^30.0.0",
82
82
  "@types/node": "^22.15.17",
@@ -1,3 +1,4 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import { Fr } from '@aztec/foundation/fields';
2
3
  import { serializeToBuffer } from '@aztec/foundation/serialize';
3
4
  import { type IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
@@ -191,14 +192,14 @@ export class MerkleTreesFacade implements MerkleTreeReadOperations {
191
192
  async getBlockNumbersForLeafIndices<ID extends MerkleTreeId>(
192
193
  treeId: ID,
193
194
  leafIndices: bigint[],
194
- ): Promise<(bigint | undefined)[]> {
195
+ ): Promise<(BlockNumber | undefined)[]> {
195
196
  const response = await this.instance.call(WorldStateMessageType.GET_BLOCK_NUMBERS_FOR_LEAF_INDICES, {
196
197
  treeId,
197
198
  revision: this.revision,
198
199
  leafIndices,
199
200
  });
200
201
 
201
- return response.blockNumbers.map(x => (x === undefined || x === null ? undefined : BigInt(x)));
202
+ return response.blockNumbers.map(x => (x === undefined || x === null ? undefined : BlockNumber(Number(x))));
202
203
  }
203
204
  }
204
205