@aztec/archiver 4.0.0-nightly.20260113 → 4.0.0-nightly.20260114
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.
- package/README.md +139 -22
- package/dest/archiver/archive_source_base.d.ts +75 -0
- package/dest/archiver/archive_source_base.d.ts.map +1 -0
- package/dest/archiver/archive_source_base.js +202 -0
- package/dest/archiver/archiver.d.ts +28 -167
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +46 -601
- package/dest/archiver/archiver_store_updates.d.ts +38 -0
- package/dest/archiver/archiver_store_updates.d.ts.map +1 -0
- package/dest/archiver/archiver_store_updates.js +212 -0
- package/dest/archiver/index.d.ts +3 -2
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +2 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +169 -9
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +157 -49
- package/dest/archiver/l1/data_retrieval.d.ts +9 -11
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/l1/data_retrieval.js +32 -51
- package/dest/archiver/test/fake_l1_state.d.ts +173 -0
- package/dest/archiver/test/fake_l1_state.d.ts.map +1 -0
- package/dest/archiver/test/fake_l1_state.js +364 -0
- package/package.json +13 -13
- package/src/archiver/archive_source_base.ts +339 -0
- package/src/archiver/archiver.ts +62 -808
- package/src/archiver/archiver_store_updates.ts +321 -0
- package/src/archiver/index.ts +2 -1
- package/src/archiver/kv_archiver_store/block_store.ts +1 -1
- package/src/archiver/kv_archiver_store/contract_class_store.ts +1 -1
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +1 -1
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +170 -8
- package/src/archiver/l1/data_retrieval.ts +51 -68
- package/src/archiver/test/fake_l1_state.ts +561 -0
- package/dest/archiver/archiver_store.d.ts +0 -315
- package/dest/archiver/archiver_store.d.ts.map +0 -1
- package/dest/archiver/archiver_store.js +0 -4
- package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
- package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
- package/dest/archiver/archiver_store_test_suite.js +0 -2770
- package/src/archiver/archiver_store.ts +0 -380
- package/src/archiver/archiver_store_test_suite.ts +0 -2842
|
@@ -23,7 +23,6 @@ import type { UInt64 } from '@aztec/stdlib/types';
|
|
|
23
23
|
|
|
24
24
|
import { join } from 'path';
|
|
25
25
|
|
|
26
|
-
import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
27
26
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
28
27
|
import { BlockStore, type CheckpointData } from './block_store.js';
|
|
29
28
|
import { ContractClassStore } from './contract_class_store.js';
|
|
@@ -36,9 +35,20 @@ export const MAX_FUNCTION_SIGNATURES = 1000;
|
|
|
36
35
|
export const MAX_FUNCTION_NAME_LEN = 256;
|
|
37
36
|
|
|
38
37
|
/**
|
|
39
|
-
*
|
|
38
|
+
* Represents the latest L1 block processed by the archiver for various objects in L2.
|
|
40
39
|
*/
|
|
41
|
-
export
|
|
40
|
+
export type ArchiverL1SynchPoint = {
|
|
41
|
+
/** Number of the last L1 block that added a new L2 checkpoint metadata. */
|
|
42
|
+
blocksSynchedTo?: bigint;
|
|
43
|
+
/** Last L1 block checked for L1 to L2 messages. */
|
|
44
|
+
messagesSynchedTo?: L1BlockId;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* LMDB-based data store for the archiver.
|
|
49
|
+
* Stores all archiver data including blocks, logs, contract classes/instances, and L1 to L2 messages.
|
|
50
|
+
*/
|
|
51
|
+
export class KVArchiverDataStore implements ContractDataSource {
|
|
42
52
|
public static readonly SCHEMA_VERSION = ARCHIVER_DB_VERSION;
|
|
43
53
|
|
|
44
54
|
#blockStore: BlockStore;
|
|
@@ -62,6 +72,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
62
72
|
this.#contractInstanceStore = new ContractInstanceStore(db);
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
/** Opens a new transaction to the underlying store and runs all operations within it. */
|
|
65
76
|
public transactionAsync<T>(callback: () => Promise<T>): Promise<T> {
|
|
66
77
|
return this.db.transactionAsync(callback);
|
|
67
78
|
}
|
|
@@ -79,19 +90,23 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
79
90
|
return this.getContractInstance(address, timestamp);
|
|
80
91
|
}
|
|
81
92
|
|
|
93
|
+
/** Backups the archiver db to the target folder. Returns the path to the db file. */
|
|
82
94
|
public async backupTo(path: string, compress = true): Promise<string> {
|
|
83
95
|
await this.db.backupTo(path, compress);
|
|
84
96
|
return join(path, 'data.mdb');
|
|
85
97
|
}
|
|
86
98
|
|
|
99
|
+
/** Closes the underlying data store. */
|
|
87
100
|
public close() {
|
|
88
101
|
return this.db.close();
|
|
89
102
|
}
|
|
90
103
|
|
|
104
|
+
/** Looks up a public function name given a selector. */
|
|
91
105
|
getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
92
106
|
return Promise.resolve(this.functionNames.get(selector.toString()));
|
|
93
107
|
}
|
|
94
108
|
|
|
109
|
+
/** Register a public function signature, so it can be looked up by selector. */
|
|
95
110
|
async registerContractFunctionSignatures(signatures: string[]): Promise<void> {
|
|
96
111
|
for (const sig of signatures) {
|
|
97
112
|
if (this.functionNames.size > MAX_FUNCTION_SIGNATURES) {
|
|
@@ -106,14 +121,25 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
106
121
|
}
|
|
107
122
|
}
|
|
108
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Returns a contract class given its id, or undefined if not exists.
|
|
126
|
+
* @param id - Id of the contract class.
|
|
127
|
+
*/
|
|
109
128
|
getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
|
|
110
129
|
return this.#contractClassStore.getContractClass(id);
|
|
111
130
|
}
|
|
112
131
|
|
|
132
|
+
/** Returns the list of all class ids known by the archiver. */
|
|
113
133
|
getContractClassIds(): Promise<Fr[]> {
|
|
114
134
|
return this.#contractClassStore.getContractClassIds();
|
|
115
135
|
}
|
|
116
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Returns a contract instance given its address and the given timestamp, or undefined if not exists.
|
|
139
|
+
* @param address - Address of the contract.
|
|
140
|
+
* @param timestamp - Timestamp to get the contract instance at. Contract updates might change the instance.
|
|
141
|
+
* @returns The contract instance or undefined if not found.
|
|
142
|
+
*/
|
|
117
143
|
getContractInstance(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
118
144
|
return this.#contractInstanceStore.getContractInstance(address, timestamp);
|
|
119
145
|
}
|
|
@@ -122,6 +148,13 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
122
148
|
return this.#contractInstanceStore.getContractInstanceDeploymentBlockNumber(address);
|
|
123
149
|
}
|
|
124
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Add new contract classes from an L2 block to the store's list.
|
|
153
|
+
* @param data - List of contract classes to be added.
|
|
154
|
+
* @param bytecodeCommitments - Bytecode commitments for the contract classes.
|
|
155
|
+
* @param blockNumber - Number of the L2 block the contracts were registered in.
|
|
156
|
+
* @returns True if the operation is successful.
|
|
157
|
+
*/
|
|
125
158
|
async addContractClasses(
|
|
126
159
|
data: ContractClassPublic[],
|
|
127
160
|
bytecodeCommitments: Fr[],
|
|
@@ -144,6 +177,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
144
177
|
return this.#contractClassStore.getBytecodeCommitment(contractClassId);
|
|
145
178
|
}
|
|
146
179
|
|
|
180
|
+
/** Adds private functions to a contract class. */
|
|
147
181
|
addFunctions(
|
|
148
182
|
contractClassId: Fr,
|
|
149
183
|
privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
@@ -152,6 +186,12 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
152
186
|
return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
|
|
153
187
|
}
|
|
154
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Add new contract instances from an L2 block to the store's list.
|
|
191
|
+
* @param data - List of contract instances to be added.
|
|
192
|
+
* @param blockNumber - Number of the L2 block the instances were deployed in.
|
|
193
|
+
* @returns True if the operation is successful.
|
|
194
|
+
*/
|
|
155
195
|
async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: BlockNumber): Promise<boolean> {
|
|
156
196
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(
|
|
157
197
|
Boolean,
|
|
@@ -162,6 +202,12 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
162
202
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
|
|
163
203
|
}
|
|
164
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Add new contract instance updates
|
|
207
|
+
* @param data - List of contract updates to be added.
|
|
208
|
+
* @param timestamp - Timestamp at which the updates were scheduled.
|
|
209
|
+
* @returns True if the operation is successful.
|
|
210
|
+
*/
|
|
165
211
|
async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
|
|
166
212
|
return (
|
|
167
213
|
await Promise.all(
|
|
@@ -190,9 +236,19 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
190
236
|
return this.#blockStore.addBlocks(blocks, opts);
|
|
191
237
|
}
|
|
192
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Returns an array of checkpoint objects
|
|
241
|
+
* @param from The first checkpoint number to be retrieved
|
|
242
|
+
* @param limit The maximum number of checkpoints to retrieve
|
|
243
|
+
* @returns The array of requested checkpoint data objects
|
|
244
|
+
*/
|
|
193
245
|
getRangeOfCheckpoints(from: CheckpointNumber, limit: number): Promise<CheckpointData[]> {
|
|
194
246
|
return this.#blockStore.getRangeOfCheckpoints(from, limit);
|
|
195
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Returns the number of the latest block
|
|
250
|
+
* @returns The number of the latest block
|
|
251
|
+
*/
|
|
196
252
|
getLatestBlockNumber(): Promise<BlockNumber> {
|
|
197
253
|
return this.#blockStore.getLatestBlockNumber();
|
|
198
254
|
}
|
|
@@ -208,51 +264,100 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
208
264
|
return this.#blockStore.unwindCheckpoints(from, checkpointsToUnwind);
|
|
209
265
|
}
|
|
210
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Appends new checkpoints, and their blocks to the store's collection
|
|
269
|
+
* @param checkpoints The collection of checkpoints to be added
|
|
270
|
+
* @returns True if the operation is successful
|
|
271
|
+
*/
|
|
211
272
|
addCheckpoints(checkpoints: PublishedCheckpoint[]): Promise<boolean> {
|
|
212
273
|
return this.#blockStore.addCheckpoints(checkpoints);
|
|
213
274
|
}
|
|
214
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Returns the block for the given number, or undefined if not exists.
|
|
278
|
+
* @param number - The block number to return.
|
|
279
|
+
*/
|
|
215
280
|
getCheckpointedBlock(number: BlockNumber): Promise<CheckpointedL2Block | undefined> {
|
|
216
281
|
return this.#blockStore.getCheckpointedBlock(number);
|
|
217
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Returns the block for the given hash, or undefined if not exists.
|
|
285
|
+
* @param blockHash - The block hash to return.
|
|
286
|
+
*/
|
|
218
287
|
getCheckpointedBlockByHash(blockHash: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
219
288
|
return this.#blockStore.getCheckpointedBlockByHash(blockHash);
|
|
220
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Returns the block for the given archive root, or undefined if not exists.
|
|
292
|
+
* @param archive - The archive root to return.
|
|
293
|
+
*/
|
|
221
294
|
getCheckpointedBlockByArchive(archive: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
222
295
|
return this.#blockStore.getCheckpointedBlockByArchive(archive);
|
|
223
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Returns the block for the given number, or undefined if not exists.
|
|
299
|
+
* @param number - The block number to return.
|
|
300
|
+
*/
|
|
224
301
|
getBlock(number: BlockNumber): Promise<L2BlockNew | undefined> {
|
|
225
302
|
return this.#blockStore.getBlock(number);
|
|
226
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Returns the block for the given hash, or undefined if not exists.
|
|
306
|
+
* @param blockHash - The block hash to return.
|
|
307
|
+
*/
|
|
227
308
|
getBlockByHash(blockHash: Fr): Promise<L2BlockNew | undefined> {
|
|
228
309
|
return this.#blockStore.getBlockByHash(L2BlockHash.fromField(blockHash));
|
|
229
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns the block for the given archive root, or undefined if not exists.
|
|
313
|
+
* @param archive - The archive root to return.
|
|
314
|
+
*/
|
|
230
315
|
getBlockByArchive(archive: Fr): Promise<L2BlockNew | undefined> {
|
|
231
316
|
return this.#blockStore.getBlockByArchive(archive);
|
|
232
317
|
}
|
|
233
|
-
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Gets up to `limit` amount of published L2 blocks starting from `from`.
|
|
321
|
+
* @param from - Number of the first block to return (inclusive).
|
|
322
|
+
* @param limit - The number of blocks to return.
|
|
323
|
+
* @returns The requested L2 blocks.
|
|
324
|
+
*/
|
|
325
|
+
getBlocks(from: BlockNumber, limit: number): Promise<L2BlockNew[]> {
|
|
234
326
|
return toArray(this.#blockStore.getBlocks(from, limit));
|
|
235
327
|
}
|
|
236
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Gets up to `limit` amount of checkpointed L2 blocks starting from `from`.
|
|
331
|
+
* @param from - Number of the first block to return (inclusive).
|
|
332
|
+
* @param limit - The number of blocks to return.
|
|
333
|
+
* @returns The requested checkpointed L2 blocks.
|
|
334
|
+
*/
|
|
237
335
|
getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
|
|
238
336
|
return toArray(this.#blockStore.getCheckpointedBlocks(from, limit));
|
|
239
337
|
}
|
|
240
338
|
|
|
241
339
|
/**
|
|
242
|
-
* Gets up to `limit` amount of L2
|
|
243
|
-
*
|
|
340
|
+
* Gets up to `limit` amount of L2 block headers starting from `from`.
|
|
244
341
|
* @param start - Number of the first block to return (inclusive).
|
|
245
342
|
* @param limit - The number of blocks to return.
|
|
246
|
-
* @returns The requested L2
|
|
343
|
+
* @returns The requested L2 block headers.
|
|
247
344
|
*/
|
|
248
345
|
getBlockHeaders(start: BlockNumber, limit: number): Promise<BlockHeader[]> {
|
|
249
346
|
return toArray(this.#blockStore.getBlockHeaders(start, limit));
|
|
250
347
|
}
|
|
251
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Returns the block header for the given hash, or undefined if not exists.
|
|
351
|
+
* @param blockHash - The block hash to return.
|
|
352
|
+
*/
|
|
252
353
|
getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
253
354
|
return this.#blockStore.getBlockHeaderByHash(L2BlockHash.fromField(blockHash));
|
|
254
355
|
}
|
|
255
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Returns the block header for the given archive root, or undefined if not exists.
|
|
359
|
+
* @param archive - The archive root to return.
|
|
360
|
+
*/
|
|
256
361
|
getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
257
362
|
return this.#blockStore.getBlockHeaderByArchive(archive);
|
|
258
363
|
}
|
|
@@ -288,10 +393,15 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
288
393
|
return this.#logStore.deleteLogs(blocks);
|
|
289
394
|
}
|
|
290
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Get the total number of L1 to L2 messages
|
|
398
|
+
* @returns The number of L1 to L2 messages in the store
|
|
399
|
+
*/
|
|
291
400
|
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
292
401
|
return this.#messageStore.getTotalL1ToL2MessageCount();
|
|
293
402
|
}
|
|
294
403
|
|
|
404
|
+
/** Returns the last L1 to L2 message stored. */
|
|
295
405
|
getLastL1ToL2Message(): Promise<InboxMessage | undefined> {
|
|
296
406
|
return this.#messageStore.getLastMessage();
|
|
297
407
|
}
|
|
@@ -299,6 +409,7 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
299
409
|
/**
|
|
300
410
|
* Append L1 to L2 messages to the store.
|
|
301
411
|
* @param messages - The L1 to L2 messages to be added to the store.
|
|
412
|
+
* @returns True if the operation is successful.
|
|
302
413
|
*/
|
|
303
414
|
addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
|
|
304
415
|
return this.#messageStore.addL1ToL2Messages(messages);
|
|
@@ -322,6 +433,10 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
322
433
|
return this.#messageStore.getL1ToL2Messages(checkpointNumber);
|
|
323
434
|
}
|
|
324
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Gets all private logs that match any of the `tags`. For each tag, an array of matching logs is returned. An empty
|
|
438
|
+
* array implies no logs match that tag.
|
|
439
|
+
*/
|
|
325
440
|
getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
|
|
326
441
|
try {
|
|
327
442
|
return this.#logStore.getPrivateLogsByTags(tags);
|
|
@@ -330,6 +445,10 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
330
445
|
}
|
|
331
446
|
}
|
|
332
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Gets all public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
|
|
450
|
+
* logs is returned. An empty array implies no logs match that tag.
|
|
451
|
+
*/
|
|
333
452
|
getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
|
|
334
453
|
try {
|
|
335
454
|
return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
@@ -364,10 +483,18 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
364
483
|
}
|
|
365
484
|
}
|
|
366
485
|
|
|
486
|
+
/**
|
|
487
|
+
* Gets the number of the latest proven checkpoint processed.
|
|
488
|
+
* @returns The number of the latest proven checkpoint processed.
|
|
489
|
+
*/
|
|
367
490
|
getProvenCheckpointNumber(): Promise<CheckpointNumber> {
|
|
368
491
|
return this.#blockStore.getProvenCheckpointNumber();
|
|
369
492
|
}
|
|
370
493
|
|
|
494
|
+
/**
|
|
495
|
+
* Stores the number of the latest proven checkpoint processed.
|
|
496
|
+
* @param checkpointNumber - The number of the latest proven checkpoint processed.
|
|
497
|
+
*/
|
|
371
498
|
async setProvenCheckpointNumber(checkpointNumber: CheckpointNumber) {
|
|
372
499
|
await this.#blockStore.setProvenCheckpointNumber(checkpointNumber);
|
|
373
500
|
}
|
|
@@ -376,16 +503,23 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
376
503
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
377
504
|
}
|
|
378
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Stores the l1 block that messages have been synched until
|
|
508
|
+
*/
|
|
379
509
|
async setMessageSynchedL1Block(l1Block: L1BlockId) {
|
|
380
510
|
await this.#messageStore.setSynchedL1Block(l1Block);
|
|
381
511
|
}
|
|
382
512
|
|
|
513
|
+
/**
|
|
514
|
+
* Returns the number of the most recent proven block
|
|
515
|
+
* @returns The number of the most recent proven block
|
|
516
|
+
*/
|
|
383
517
|
getProvenBlockNumber(): Promise<BlockNumber> {
|
|
384
518
|
return this.#blockStore.getProvenBlockNumber();
|
|
385
519
|
}
|
|
386
520
|
|
|
387
521
|
/**
|
|
388
|
-
* Gets the
|
|
522
|
+
* Gets the synch point of the archiver
|
|
389
523
|
*/
|
|
390
524
|
async getSynchPoint(): Promise<ArchiverL1SynchPoint> {
|
|
391
525
|
const [blocksSynchedTo, messagesSynchedTo] = await Promise.all([
|
|
@@ -398,44 +532,72 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
398
532
|
};
|
|
399
533
|
}
|
|
400
534
|
|
|
535
|
+
/** Estimates the size of the store in bytes. */
|
|
401
536
|
public estimateSize(): Promise<StoreSize> {
|
|
402
537
|
return this.db.estimateSize();
|
|
403
538
|
}
|
|
404
539
|
|
|
540
|
+
/** Deletes all L1 to L2 messages up until (excluding) the target checkpoint number. */
|
|
405
541
|
public rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber: CheckpointNumber): Promise<void> {
|
|
406
542
|
return this.#messageStore.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
407
543
|
}
|
|
408
544
|
|
|
545
|
+
/** Returns an async iterator to all L1 to L2 messages on the range. */
|
|
409
546
|
public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
|
|
410
547
|
return this.#messageStore.iterateL1ToL2Messages(range);
|
|
411
548
|
}
|
|
412
549
|
|
|
550
|
+
/** Removes all L1 to L2 messages starting from the given index (inclusive). */
|
|
413
551
|
public removeL1ToL2Messages(startIndex: bigint): Promise<void> {
|
|
414
552
|
return this.#messageStore.removeL1ToL2Messages(startIndex);
|
|
415
553
|
}
|
|
416
554
|
|
|
555
|
+
/** Returns the last synced validation status of the pending chain. */
|
|
417
556
|
public getPendingChainValidationStatus(): Promise<ValidateCheckpointResult | undefined> {
|
|
418
557
|
return this.#blockStore.getPendingChainValidationStatus();
|
|
419
558
|
}
|
|
420
559
|
|
|
560
|
+
/** Sets the last synced validation status of the pending chain. */
|
|
421
561
|
public setPendingChainValidationStatus(status: ValidateCheckpointResult | undefined): Promise<void> {
|
|
422
562
|
return this.#blockStore.setPendingChainValidationStatus(status);
|
|
423
563
|
}
|
|
424
564
|
|
|
565
|
+
/**
|
|
566
|
+
* Gets the number of the latest L2 block processed.
|
|
567
|
+
* @returns The number of the latest L2 block processed.
|
|
568
|
+
*/
|
|
425
569
|
public getCheckpointedL2BlockNumber(): Promise<BlockNumber> {
|
|
426
570
|
return this.#blockStore.getCheckpointedL2BlockNumber();
|
|
427
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Gets the number of the latest published checkpoint processed.
|
|
574
|
+
* @returns The number of the latest published checkpoint processed
|
|
575
|
+
*/
|
|
428
576
|
public getSynchedCheckpointNumber(): Promise<CheckpointNumber> {
|
|
429
577
|
return this.#blockStore.getLatestCheckpointNumber();
|
|
430
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* Stores the l1 block number that checkpoints have been synched until
|
|
581
|
+
* @param l1BlockNumber - The l1 block number
|
|
582
|
+
*/
|
|
431
583
|
async setCheckpointSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<void> {
|
|
432
584
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
433
585
|
}
|
|
434
586
|
|
|
587
|
+
/**
|
|
588
|
+
* Retrieves all blocks for the requested checkpoint
|
|
589
|
+
* @param checkpointNumber Retrieves all blocks for the given checkpoint
|
|
590
|
+
* @returns The collection of blocks for the requested checkpoint if available (undefined otherwise)
|
|
591
|
+
*/
|
|
435
592
|
getBlocksForCheckpoint(checkpointNumber: CheckpointNumber): Promise<L2BlockNew[] | undefined> {
|
|
436
593
|
return this.#blockStore.getBlocksForCheckpoint(checkpointNumber);
|
|
437
594
|
}
|
|
438
595
|
|
|
596
|
+
/**
|
|
597
|
+
* Returns checkpoint data for the requested checkpoint number
|
|
598
|
+
* @param checkpointNumber - The checkpoint requested
|
|
599
|
+
* @returns The checkpoint data or undefined if not found
|
|
600
|
+
*/
|
|
439
601
|
getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined> {
|
|
440
602
|
return this.#blockStore.getCheckpointData(checkpointNumber);
|
|
441
603
|
}
|
|
@@ -6,15 +6,20 @@ import {
|
|
|
6
6
|
decodeCheckpointBlobDataFromBlobs,
|
|
7
7
|
encodeBlockBlobData,
|
|
8
8
|
} from '@aztec/blob-lib';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
9
|
+
import type {
|
|
10
|
+
CheckpointProposedLog,
|
|
11
|
+
EpochProofPublicInputArgs,
|
|
12
|
+
InboxContract,
|
|
13
|
+
MessageSentLog,
|
|
14
|
+
RollupContract,
|
|
15
|
+
} from '@aztec/ethereum/contracts';
|
|
16
|
+
import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
11
17
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
12
18
|
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
13
|
-
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
14
19
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
15
20
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
21
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
17
|
-
import {
|
|
22
|
+
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
18
23
|
import { Body, CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
|
|
19
24
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
20
25
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
@@ -22,14 +27,7 @@ import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
|
22
27
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
23
28
|
import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
24
29
|
|
|
25
|
-
import {
|
|
26
|
-
type GetContractEventsReturnType,
|
|
27
|
-
type GetContractReturnType,
|
|
28
|
-
type Hex,
|
|
29
|
-
decodeFunctionData,
|
|
30
|
-
getAbiItem,
|
|
31
|
-
hexToBytes,
|
|
32
|
-
} from 'viem';
|
|
30
|
+
import { type Hex, decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
|
|
33
31
|
|
|
34
32
|
import { NoBlobBodiesFoundError } from '../errors.js';
|
|
35
33
|
import type { ArchiverInstrumentation } from '../instrumentation.js';
|
|
@@ -137,7 +135,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
137
135
|
|
|
138
136
|
/**
|
|
139
137
|
* Fetches new checkpoints.
|
|
140
|
-
* @param rollup - The rollup contract
|
|
138
|
+
* @param rollup - The rollup contract wrapper.
|
|
141
139
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
142
140
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
143
141
|
* @param blobClient - The blob client client for fetching blob data.
|
|
@@ -150,7 +148,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
150
148
|
* @returns An array of retrieved checkpoints.
|
|
151
149
|
*/
|
|
152
150
|
export async function retrieveCheckpointsFromRollup(
|
|
153
|
-
rollup:
|
|
151
|
+
rollup: RollupContract,
|
|
154
152
|
publicClient: ViemPublicClient,
|
|
155
153
|
debugClient: ViemPublicDebugClient,
|
|
156
154
|
blobClient: BlobClientInterface,
|
|
@@ -173,15 +171,7 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
173
171
|
if (searchStartBlock > searchEndBlock) {
|
|
174
172
|
break;
|
|
175
173
|
}
|
|
176
|
-
const checkpointProposedLogs = (
|
|
177
|
-
await rollup.getEvents.CheckpointProposed(
|
|
178
|
-
{},
|
|
179
|
-
{
|
|
180
|
-
fromBlock: searchStartBlock,
|
|
181
|
-
toBlock: searchEndBlock,
|
|
182
|
-
},
|
|
183
|
-
)
|
|
184
|
-
).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
|
|
174
|
+
const checkpointProposedLogs = await rollup.getCheckpointProposedEvents(searchStartBlock, searchEndBlock);
|
|
185
175
|
|
|
186
176
|
if (checkpointProposedLogs.length === 0) {
|
|
187
177
|
break;
|
|
@@ -189,19 +179,19 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
189
179
|
|
|
190
180
|
const lastLog = checkpointProposedLogs.at(-1)!;
|
|
191
181
|
logger.debug(
|
|
192
|
-
`Got ${checkpointProposedLogs.length} processed logs for checkpoints
|
|
182
|
+
`Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
|
|
193
183
|
);
|
|
194
184
|
|
|
195
185
|
if (rollupConstants === undefined) {
|
|
196
186
|
const [chainId, version, targetCommitteeSize] = await Promise.all([
|
|
197
187
|
publicClient.getChainId(),
|
|
198
|
-
rollup.
|
|
199
|
-
rollup.
|
|
188
|
+
rollup.getVersion(),
|
|
189
|
+
rollup.getTargetCommitteeSize(),
|
|
200
190
|
]);
|
|
201
191
|
rollupConstants = {
|
|
202
192
|
chainId: new Fr(chainId),
|
|
203
193
|
version: new Fr(version),
|
|
204
|
-
targetCommitteeSize
|
|
194
|
+
targetCommitteeSize,
|
|
205
195
|
};
|
|
206
196
|
}
|
|
207
197
|
|
|
@@ -218,7 +208,7 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
218
208
|
isHistoricalSync,
|
|
219
209
|
);
|
|
220
210
|
retrievedCheckpoints.push(...newCheckpoints);
|
|
221
|
-
searchStartBlock = lastLog.
|
|
211
|
+
searchStartBlock = lastLog.l1BlockNumber + 1n;
|
|
222
212
|
} while (searchStartBlock <= searchEndBlock);
|
|
223
213
|
|
|
224
214
|
// The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
|
|
@@ -227,7 +217,7 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
227
217
|
|
|
228
218
|
/**
|
|
229
219
|
* Processes newly received CheckpointProposed logs.
|
|
230
|
-
* @param rollup - The rollup contract
|
|
220
|
+
* @param rollup - The rollup contract wrapper.
|
|
231
221
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
232
222
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
233
223
|
* @param blobClient - The blob client client for fetching blob data.
|
|
@@ -240,11 +230,11 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
240
230
|
* @returns An array of retrieved checkpoints.
|
|
241
231
|
*/
|
|
242
232
|
async function processCheckpointProposedLogs(
|
|
243
|
-
rollup:
|
|
233
|
+
rollup: RollupContract,
|
|
244
234
|
publicClient: ViemPublicClient,
|
|
245
235
|
debugClient: ViemPublicDebugClient,
|
|
246
236
|
blobClient: BlobClientInterface,
|
|
247
|
-
logs:
|
|
237
|
+
logs: CheckpointProposedLog[],
|
|
248
238
|
{ chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
|
|
249
239
|
contractAddresses: {
|
|
250
240
|
governanceProposerAddress: EthAddress;
|
|
@@ -266,21 +256,21 @@ async function processCheckpointProposedLogs(
|
|
|
266
256
|
);
|
|
267
257
|
|
|
268
258
|
await asyncPool(10, logs, async log => {
|
|
269
|
-
const checkpointNumber =
|
|
270
|
-
const archive = log.args.archive
|
|
271
|
-
const archiveFromChain = await rollup.
|
|
272
|
-
const blobHashes = log.args.versionedBlobHashes
|
|
259
|
+
const checkpointNumber = log.args.checkpointNumber;
|
|
260
|
+
const archive = log.args.archive;
|
|
261
|
+
const archiveFromChain = await rollup.archiveAt(checkpointNumber);
|
|
262
|
+
const blobHashes = log.args.versionedBlobHashes;
|
|
273
263
|
|
|
274
264
|
// The value from the event and contract will match only if the checkpoint is in the chain.
|
|
275
|
-
if (archive
|
|
265
|
+
if (archive.equals(archiveFromChain)) {
|
|
276
266
|
// Build expected hashes object (fields may be undefined for backwards compatibility with older events)
|
|
277
267
|
const expectedHashes = {
|
|
278
|
-
attestationsHash: log.args.attestationsHash,
|
|
279
|
-
payloadDigest: log.args.payloadDigest,
|
|
268
|
+
attestationsHash: log.args.attestationsHash?.toString(),
|
|
269
|
+
payloadDigest: log.args.payloadDigest?.toString(),
|
|
280
270
|
};
|
|
281
271
|
|
|
282
272
|
const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(
|
|
283
|
-
log.
|
|
273
|
+
log.l1TransactionHash,
|
|
284
274
|
blobHashes,
|
|
285
275
|
checkpointNumber,
|
|
286
276
|
expectedHashes,
|
|
@@ -295,22 +285,22 @@ async function processCheckpointProposedLogs(
|
|
|
295
285
|
);
|
|
296
286
|
|
|
297
287
|
const l1 = new L1PublishedData(
|
|
298
|
-
log.
|
|
299
|
-
await getL1BlockTime(publicClient, log.
|
|
300
|
-
log.
|
|
288
|
+
log.l1BlockNumber,
|
|
289
|
+
await getL1BlockTime(publicClient, log.l1BlockNumber),
|
|
290
|
+
log.l1BlockHash.toString(),
|
|
301
291
|
);
|
|
302
292
|
|
|
303
293
|
retrievedCheckpoints.push({ ...checkpoint, checkpointBlobData, l1, chainId, version });
|
|
304
|
-
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.
|
|
305
|
-
l1BlockNumber: log.
|
|
294
|
+
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
|
|
295
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
306
296
|
checkpointNumber,
|
|
307
297
|
archive: archive.toString(),
|
|
308
298
|
attestations: checkpoint.attestations,
|
|
309
299
|
});
|
|
310
300
|
} else {
|
|
311
301
|
logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
|
|
312
|
-
actual: archive,
|
|
313
|
-
expected: archiveFromChain,
|
|
302
|
+
actual: archive.toString(),
|
|
303
|
+
expected: archiveFromChain.toString(),
|
|
314
304
|
});
|
|
315
305
|
}
|
|
316
306
|
});
|
|
@@ -355,12 +345,12 @@ export async function getCheckpointBlobDataFromBlobs(
|
|
|
355
345
|
|
|
356
346
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
|
357
347
|
export async function retrieveL1ToL2Message(
|
|
358
|
-
inbox:
|
|
348
|
+
inbox: InboxContract,
|
|
359
349
|
leaf: Fr,
|
|
360
350
|
fromBlock: bigint,
|
|
361
351
|
toBlock: bigint,
|
|
362
352
|
): Promise<InboxMessage | undefined> {
|
|
363
|
-
const logs = await inbox.
|
|
353
|
+
const logs = await inbox.getMessageSentEventByHash(leaf.toString(), fromBlock, toBlock);
|
|
364
354
|
|
|
365
355
|
const messages = mapLogsInboxMessage(logs);
|
|
366
356
|
return messages.length > 0 ? messages[0] : undefined;
|
|
@@ -368,47 +358,40 @@ export async function retrieveL1ToL2Message(
|
|
|
368
358
|
|
|
369
359
|
/**
|
|
370
360
|
* Fetch L1 to L2 messages.
|
|
371
|
-
* @param
|
|
372
|
-
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
373
|
-
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
361
|
+
* @param inbox - The inbox contract wrapper.
|
|
374
362
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
375
363
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
376
364
|
* @returns An array of InboxLeaf and next eth block to search from.
|
|
377
365
|
*/
|
|
378
366
|
export async function retrieveL1ToL2Messages(
|
|
379
|
-
inbox:
|
|
367
|
+
inbox: InboxContract,
|
|
380
368
|
searchStartBlock: bigint,
|
|
381
369
|
searchEndBlock: bigint,
|
|
382
370
|
): Promise<InboxMessage[]> {
|
|
383
371
|
const retrievedL1ToL2Messages: InboxMessage[] = [];
|
|
384
372
|
while (searchStartBlock <= searchEndBlock) {
|
|
385
|
-
const messageSentLogs = (
|
|
386
|
-
await inbox.getEvents.MessageSent({}, { fromBlock: searchStartBlock, toBlock: searchEndBlock })
|
|
387
|
-
).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
|
|
373
|
+
const messageSentLogs = await inbox.getMessageSentEvents(searchStartBlock, searchEndBlock);
|
|
388
374
|
|
|
389
375
|
if (messageSentLogs.length === 0) {
|
|
390
376
|
break;
|
|
391
377
|
}
|
|
392
378
|
|
|
393
379
|
retrievedL1ToL2Messages.push(...mapLogsInboxMessage(messageSentLogs));
|
|
394
|
-
searchStartBlock = messageSentLogs.at(-1)!.
|
|
380
|
+
searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
|
|
395
381
|
}
|
|
396
382
|
|
|
397
383
|
return retrievedL1ToL2Messages;
|
|
398
384
|
}
|
|
399
385
|
|
|
400
|
-
function mapLogsInboxMessage(logs:
|
|
401
|
-
return logs.map(log => {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
rollingHash: Buffer16.fromString(rollingHash!),
|
|
410
|
-
};
|
|
411
|
-
});
|
|
386
|
+
function mapLogsInboxMessage(logs: MessageSentLog[]): InboxMessage[] {
|
|
387
|
+
return logs.map(log => ({
|
|
388
|
+
index: log.args.index,
|
|
389
|
+
leaf: log.args.leaf,
|
|
390
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
391
|
+
l1BlockHash: log.l1BlockHash,
|
|
392
|
+
checkpointNumber: log.args.checkpointNumber,
|
|
393
|
+
rollingHash: log.args.rollingHash,
|
|
394
|
+
}));
|
|
412
395
|
}
|
|
413
396
|
|
|
414
397
|
/** Retrieves L2ProofVerified events from the rollup contract. */
|