@aztec/archiver 0.0.1-commit.87a0206 → 0.0.1-commit.88e6f9396
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/dest/archiver.d.ts +7 -5
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +62 -111
- package/dest/config.d.ts +3 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -1
- package/dest/errors.d.ts +21 -9
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +27 -14
- package/dest/factory.d.ts +3 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +24 -20
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/l1/bin/retrieve-calldata.js +32 -28
- package/dest/l1/calldata_retriever.d.ts +73 -50
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +190 -259
- package/dest/l1/data_retrieval.d.ts +9 -9
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +21 -19
- package/dest/l1/spire_proposer.d.ts +5 -5
- package/dest/l1/spire_proposer.d.ts.map +1 -1
- package/dest/l1/spire_proposer.js +9 -17
- package/dest/modules/data_source_base.d.ts +12 -7
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +33 -77
- package/dest/modules/data_store_updater.d.ts +22 -7
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +70 -30
- package/dest/modules/instrumentation.d.ts +15 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +19 -2
- package/dest/modules/l1_synchronizer.d.ts +5 -8
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +50 -15
- package/dest/store/block_store.d.ts +29 -26
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +130 -78
- package/dest/store/kv_archiver_store.d.ts +40 -13
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +48 -13
- package/dest/store/l2_tips_cache.d.ts +19 -0
- package/dest/store/l2_tips_cache.d.ts.map +1 -0
- package/dest/store/l2_tips_cache.js +89 -0
- package/dest/store/log_store.d.ts +6 -3
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +93 -16
- package/dest/store/message_store.d.ts +5 -1
- package/dest/store/message_store.d.ts.map +1 -1
- package/dest/store/message_store.js +14 -1
- package/dest/test/fake_l1_state.d.ts +13 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +95 -23
- package/dest/test/mock_archiver.d.ts +1 -1
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +3 -2
- package/dest/test/mock_l2_block_source.d.ts +21 -5
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +132 -86
- package/dest/test/mock_structs.d.ts +4 -1
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +13 -1
- package/dest/test/noop_l1_archiver.d.ts +4 -1
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +5 -1
- package/package.json +13 -13
- package/src/archiver.ts +74 -131
- package/src/config.ts +8 -1
- package/src/errors.ts +40 -24
- package/src/factory.ts +34 -17
- package/src/index.ts +1 -0
- package/src/l1/README.md +25 -68
- package/src/l1/bin/retrieve-calldata.ts +40 -27
- package/src/l1/calldata_retriever.ts +249 -379
- package/src/l1/data_retrieval.ts +23 -25
- package/src/l1/spire_proposer.ts +7 -15
- package/src/modules/data_source_base.ts +64 -98
- package/src/modules/data_store_updater.ts +72 -31
- package/src/modules/instrumentation.ts +29 -2
- package/src/modules/l1_synchronizer.ts +61 -24
- package/src/store/block_store.ts +157 -105
- package/src/store/kv_archiver_store.ts +73 -15
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +126 -27
- package/src/store/message_store.ts +20 -1
- package/src/test/fake_l1_state.ts +125 -26
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +173 -81
- package/src/test/mock_structs.ts +20 -6
- package/src/test/noop_l1_archiver.ts +7 -1
package/dest/store/log_store.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
-
import { filterAsync } from '@aztec/foundation/collection';
|
|
3
|
+
import { compactArray, filterAsync } from '@aztec/foundation/collection';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
|
|
@@ -8,6 +8,7 @@ import { BlockHash } from '@aztec/stdlib/block';
|
|
|
8
8
|
import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
|
|
9
9
|
import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
10
10
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
11
|
+
import { OutOfOrderLogInsertionError } from '../errors.js';
|
|
11
12
|
/**
|
|
12
13
|
* A store for logs
|
|
13
14
|
*/ export class LogStore {
|
|
@@ -108,7 +109,16 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
108
109
|
})));
|
|
109
110
|
for (const taggedLogBuffer of currentPrivateTaggedLogs){
|
|
110
111
|
if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
|
|
111
|
-
|
|
112
|
+
const newLogs = privateTaggedLogs.get(taggedLogBuffer.tag);
|
|
113
|
+
if (newLogs.length === 0) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1));
|
|
117
|
+
const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
|
|
118
|
+
if (lastExisting.blockNumber > firstNew.blockNumber) {
|
|
119
|
+
throw new OutOfOrderLogInsertionError('private', taggedLogBuffer.tag, lastExisting.blockNumber, firstNew.blockNumber);
|
|
120
|
+
}
|
|
121
|
+
privateTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
124
|
for (const block of newBlocks){
|
|
@@ -130,7 +140,16 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
130
140
|
})));
|
|
131
141
|
for (const taggedLogBuffer of currentPublicTaggedLogs){
|
|
132
142
|
if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
|
|
133
|
-
|
|
143
|
+
const newLogs = publicTaggedLogs.get(taggedLogBuffer.tag);
|
|
144
|
+
if (newLogs.length === 0) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1));
|
|
148
|
+
const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
|
|
149
|
+
if (lastExisting.blockNumber > firstNew.blockNumber) {
|
|
150
|
+
throw new OutOfOrderLogInsertionError('public', taggedLogBuffer.tag, lastExisting.blockNumber, firstNew.blockNumber);
|
|
151
|
+
}
|
|
152
|
+
publicTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
|
|
134
153
|
}
|
|
135
154
|
}
|
|
136
155
|
for (const block of newBlocks){
|
|
@@ -192,14 +211,34 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
192
211
|
}
|
|
193
212
|
deleteLogs(blocks) {
|
|
194
213
|
return this.db.transactionAsync(async ()=>{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
214
|
+
const blockNumbers = new Set(blocks.map((block)=>block.number));
|
|
215
|
+
const firstBlockToDelete = Math.min(...blockNumbers);
|
|
216
|
+
// Collect all unique private tags across all blocks being deleted
|
|
217
|
+
const allPrivateTags = new Set(compactArray(await Promise.all(blocks.map((block)=>this.#privateLogKeysByBlock.getAsync(block.number)))).flat());
|
|
218
|
+
// Trim private logs: for each tag, delete all instances including and after the first block being deleted.
|
|
219
|
+
// This hinges on the invariant that logs for a given tag are always inserted in order of block number, which is enforced in #addPrivateLogs.
|
|
220
|
+
for (const tag of allPrivateTags){
|
|
221
|
+
const existing = await this.#privateLogsByTag.getAsync(tag);
|
|
222
|
+
if (existing === undefined || existing.length === 0) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const lastIndexToKeep = existing.findLastIndex((buf)=>TxScopedL2Log.getBlockNumberFromBuffer(buf) < firstBlockToDelete);
|
|
226
|
+
const remaining = existing.slice(0, lastIndexToKeep + 1);
|
|
227
|
+
await (remaining.length > 0 ? this.#privateLogsByTag.set(tag, remaining) : this.#privateLogsByTag.delete(tag));
|
|
228
|
+
}
|
|
229
|
+
// Collect all unique public keys across all blocks being deleted
|
|
230
|
+
const allPublicKeys = new Set(compactArray(await Promise.all(blocks.map((block)=>this.#publicLogKeysByBlock.getAsync(block.number)))).flat());
|
|
231
|
+
// And do the same as we did with private logs
|
|
232
|
+
for (const key of allPublicKeys){
|
|
233
|
+
const existing = await this.#publicLogsByContractAndTag.getAsync(key);
|
|
234
|
+
if (existing === undefined || existing.length === 0) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const lastIndexToKeep = existing.findLastIndex((buf)=>TxScopedL2Log.getBlockNumberFromBuffer(buf) < firstBlockToDelete);
|
|
238
|
+
const remaining = existing.slice(0, lastIndexToKeep + 1);
|
|
239
|
+
await (remaining.length > 0 ? this.#publicLogsByContractAndTag.set(key, remaining) : this.#publicLogsByContractAndTag.delete(key));
|
|
240
|
+
}
|
|
241
|
+
// After trimming the tagged logs, we can delete the block-level keys that track which tags are in which blocks.
|
|
203
242
|
await Promise.all(blocks.map((block)=>Promise.all([
|
|
204
243
|
this.#publicLogsByBlock.delete(block.number),
|
|
205
244
|
this.#privateLogKeysByBlock.delete(block.number),
|
|
@@ -214,13 +253,23 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
214
253
|
* array implies no logs match that tag.
|
|
215
254
|
* @param tags - The tags to search for.
|
|
216
255
|
* @param page - The page number (0-indexed) for pagination.
|
|
256
|
+
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
217
257
|
* @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
|
|
218
258
|
* MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
|
|
219
|
-
*/ async getPrivateLogsByTags(tags, page = 0) {
|
|
259
|
+
*/ async getPrivateLogsByTags(tags, page = 0, upToBlockNumber) {
|
|
220
260
|
const logs = await Promise.all(tags.map((tag)=>this.#privateLogsByTag.getAsync(tag.toString())));
|
|
221
261
|
const start = page * MAX_LOGS_PER_TAG;
|
|
222
262
|
const end = start + MAX_LOGS_PER_TAG;
|
|
223
|
-
return logs.map((logBuffers)=>
|
|
263
|
+
return logs.map((logBuffers)=>{
|
|
264
|
+
const deserialized = logBuffers?.slice(start, end).map((buf)=>TxScopedL2Log.fromBuffer(buf)) ?? [];
|
|
265
|
+
if (upToBlockNumber !== undefined) {
|
|
266
|
+
const cutoff = deserialized.findIndex((log)=>log.blockNumber > upToBlockNumber);
|
|
267
|
+
if (cutoff !== -1) {
|
|
268
|
+
return deserialized.slice(0, cutoff);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return deserialized;
|
|
272
|
+
});
|
|
224
273
|
}
|
|
225
274
|
/**
|
|
226
275
|
* Gets public logs that match any of the `tags` from the specified contract. For each tag, an array of matching
|
|
@@ -228,16 +277,26 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
228
277
|
* @param contractAddress - The contract address to search logs for.
|
|
229
278
|
* @param tags - The tags to search for.
|
|
230
279
|
* @param page - The page number (0-indexed) for pagination.
|
|
280
|
+
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
231
281
|
* @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
|
|
232
282
|
* MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
|
|
233
|
-
*/ async getPublicLogsByTagsFromContract(contractAddress, tags, page = 0) {
|
|
283
|
+
*/ async getPublicLogsByTagsFromContract(contractAddress, tags, page = 0, upToBlockNumber) {
|
|
234
284
|
const logs = await Promise.all(tags.map((tag)=>{
|
|
235
285
|
const key = `${contractAddress.toString()}_${tag.value.toString()}`;
|
|
236
286
|
return this.#publicLogsByContractAndTag.getAsync(key);
|
|
237
287
|
}));
|
|
238
288
|
const start = page * MAX_LOGS_PER_TAG;
|
|
239
289
|
const end = start + MAX_LOGS_PER_TAG;
|
|
240
|
-
return logs.map((logBuffers)=>
|
|
290
|
+
return logs.map((logBuffers)=>{
|
|
291
|
+
const deserialized = logBuffers?.slice(start, end).map((buf)=>TxScopedL2Log.fromBuffer(buf)) ?? [];
|
|
292
|
+
if (upToBlockNumber !== undefined) {
|
|
293
|
+
const cutoff = deserialized.findIndex((log)=>log.blockNumber > upToBlockNumber);
|
|
294
|
+
if (cutoff !== -1) {
|
|
295
|
+
return deserialized.slice(0, cutoff);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return deserialized;
|
|
299
|
+
});
|
|
241
300
|
}
|
|
242
301
|
/**
|
|
243
302
|
* Gets public logs based on the provided filter.
|
|
@@ -424,11 +483,20 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
424
483
|
};
|
|
425
484
|
}
|
|
426
485
|
#accumulatePublicLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
|
|
486
|
+
if (filter.fromBlock && blockNumber < filter.fromBlock) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
if (filter.toBlock && blockNumber >= filter.toBlock) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
if (filter.txHash && !txHash.equals(filter.txHash)) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
427
495
|
let maxLogsHit = false;
|
|
428
496
|
let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
|
|
429
497
|
for(; logIndex < txLogs.length; logIndex++){
|
|
430
498
|
const log = txLogs[logIndex];
|
|
431
|
-
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
499
|
+
if ((!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) && (!filter.tag || log.fields[0]?.equals(filter.tag))) {
|
|
432
500
|
results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log));
|
|
433
501
|
if (results.length >= this.#logsMaxPageSize) {
|
|
434
502
|
maxLogsHit = true;
|
|
@@ -439,6 +507,15 @@ import { TxHash } from '@aztec/stdlib/tx';
|
|
|
439
507
|
return maxLogsHit;
|
|
440
508
|
}
|
|
441
509
|
#accumulateContractClassLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
|
|
510
|
+
if (filter.fromBlock && blockNumber < filter.fromBlock) {
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
if (filter.toBlock && blockNumber >= filter.toBlock) {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
if (filter.txHash && !txHash.equals(filter.txHash)) {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
442
519
|
let maxLogsHit = false;
|
|
443
520
|
let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
|
|
444
521
|
for(; logIndex < txLogs.length; logIndex++){
|
|
@@ -29,6 +29,10 @@ export declare class MessageStore {
|
|
|
29
29
|
*/
|
|
30
30
|
getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined>;
|
|
31
31
|
getLastMessage(): Promise<InboxMessage | undefined>;
|
|
32
|
+
/** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */
|
|
33
|
+
getInboxTreeInProgress(): Promise<bigint | undefined>;
|
|
34
|
+
/** Persists the inbox tree-in-progress checkpoint number from L1 state. */
|
|
35
|
+
setInboxTreeInProgress(value: bigint): Promise<void>;
|
|
32
36
|
getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]>;
|
|
33
37
|
iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
|
|
34
38
|
removeL1ToL2Messages(startIndex: bigint): Promise<void>;
|
|
@@ -37,4 +41,4 @@ export declare class MessageStore {
|
|
|
37
41
|
private leafToIndexKey;
|
|
38
42
|
private increaseTotalMessageCount;
|
|
39
43
|
}
|
|
40
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZV9zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0b3JlL21lc3NhZ2Vfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFbkUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sRUFDTCxLQUFLLGlCQUFpQixFQUd0QixLQUFLLFdBQVcsRUFFakIsTUFBTSxpQkFBaUIsQ0FBQztBQUl6QixPQUFPLEVBQ0wsS0FBSyxZQUFZLEVBSWxCLE1BQU0sNkJBQTZCLENBQUM7QUFFckMscUJBQWEsaUJBQWtCLFNBQVEsS0FBSzthQUd4QixZQUFZLEVBQUUsWUFBWTtJQUY1QyxZQUNFLE9BQU8sRUFBRSxNQUFNLEVBQ0MsWUFBWSxFQUFFLFlBQVksRUFJM0M7Q0FDRjtBQUVELHFCQUFhLFlBQVk7O0lBY1gsT0FBTyxDQUFDLEVBQUU7SUFBdEIsWUFBb0IsRUFBRSxFQUFFLGlCQUFpQixFQU14QztJQUVZLDBCQUEwQixJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFekQ7SUFFRCxxQ0FBcUM7SUFDeEIsaUJBQWlCLElBQUksT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FRL0Q7SUFFRCxvQ0FBb0M7SUFDdkIsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBR2hFO0lBRUQ7Ozs7T0FJRztJQUNJLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBNkZoRTtJQUVEOzs7O09BSUc7SUFDSSxxQkFBcUIsQ0FBQyxhQUFhLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNFO0lBRVksY0FBYyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLENBRy9EO0lBRUQsaUdBQWlHO0lBQzFGLHNCQUFzQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLENBRTNEO0lBRUQsMkVBQTJFO0lBQzlELHNCQUFzQixDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUVoRTtJQUVZLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQTRCaEY7SUFFYSxxQkFBcUIsQ0FBQyxLQUFLLEdBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBTSxHQUFHLHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUt4RztJQUVNLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWdCN0Q7SUFFTSxrQ0FBa0MsQ0FBQyxzQkFBc0IsRUFBRSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWpHO0lBRUQsT0FBTyxDQUFDLFVBQVU7SUFJbEIsT0FBTyxDQUFDLGNBQWM7WUFJUix5QkFBeUI7Q0FTeEMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_store.d.ts","sourceRoot":"","sources":["../../src/store/message_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,EACL,KAAK,iBAAiB,EAGtB,KAAK,WAAW,EAEjB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"message_store.d.ts","sourceRoot":"","sources":["../../src/store/message_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,EACL,KAAK,iBAAiB,EAGtB,KAAK,WAAW,EAEjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,6BAA6B,CAAC;AAErC,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,YAAY,EAAE,YAAY;IAF5C,YACE,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,YAAY,EAI3C;CACF;AAED,qBAAa,YAAY;;IAcX,OAAO,CAAC,EAAE;IAAtB,YAAoB,EAAE,EAAE,iBAAiB,EAMxC;IAEY,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC,CAEzD;IAED,qCAAqC;IACxB,iBAAiB,IAAI,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAQ/D;IAED,oCAAoC;IACvB,iBAAiB,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhE;IAED;;;;OAIG;IACI,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6FhE;IAED;;;;OAIG;IACI,qBAAqB,CAAC,aAAa,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3E;IAEY,cAAc,IAAI,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAG/D;IAED,iGAAiG;IAC1F,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3D;IAED,2EAA2E;IAC9D,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;IAEY,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CA4BhF;IAEa,qBAAqB,CAAC,KAAK,GAAE,WAAW,CAAC,MAAM,CAAM,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAKxG;IAEM,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7D;IAEM,kCAAkC,CAAC,sBAAsB,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG;IAED,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,cAAc;YAIR,yBAAyB;CASxC"}
|
|
@@ -5,6 +5,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
5
5
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
6
6
|
import { mapRange } from '@aztec/kv-store';
|
|
7
7
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
8
|
+
import { L1ToL2MessagesNotReadyError } from '../errors.js';
|
|
8
9
|
import { deserializeInboxMessage, serializeInboxMessage, updateRollingHash } from '../structs/inbox_message.js';
|
|
9
10
|
export class MessageStoreError extends Error {
|
|
10
11
|
inboxMessage;
|
|
@@ -19,6 +20,7 @@ export class MessageStore {
|
|
|
19
20
|
/** Maps from hex-stringified message leaf to its index */ #l1ToL2MessageIndices;
|
|
20
21
|
/** Stores L1 block number and hash of the L1 synchpoint */ #lastSynchedL1Block;
|
|
21
22
|
/** Stores total messages stored */ #totalMessageCount;
|
|
23
|
+
/** Stores the checkpoint number whose message tree is currently being filled on L1. */ #inboxTreeInProgress;
|
|
22
24
|
#log;
|
|
23
25
|
constructor(db){
|
|
24
26
|
this.db = db;
|
|
@@ -27,6 +29,7 @@ export class MessageStore {
|
|
|
27
29
|
this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
|
|
28
30
|
this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_id');
|
|
29
31
|
this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count');
|
|
32
|
+
this.#inboxTreeInProgress = db.openSingleton('archiver_inbox_tree_in_progress');
|
|
30
33
|
}
|
|
31
34
|
async getTotalL1ToL2MessageCount() {
|
|
32
35
|
return await this.#totalMessageCount.getAsync() ?? 0n;
|
|
@@ -87,7 +90,7 @@ export class MessageStore {
|
|
|
87
90
|
if (lastMessage && message.checkpointNumber === lastMessage.checkpointNumber && message.index !== lastMessage.index + 1n) {
|
|
88
91
|
throw new MessageStoreError(`Missing prior message for incoming L1 to L2 message ${message.leaf.toString()} ` + `with index ${message.index}`, message);
|
|
89
92
|
}
|
|
90
|
-
// Check the first message in a
|
|
93
|
+
// Check the first message in a checkpoint has the correct index.
|
|
91
94
|
if ((!lastMessage || message.checkpointNumber > lastMessage.checkpointNumber) && message.index !== expectedStart) {
|
|
92
95
|
throw new MessageStoreError(`Message ${message.leaf.toString()} for checkpoint ${message.checkpointNumber} has wrong index ` + `${message.index} (expected ${expectedStart})`, message);
|
|
93
96
|
}
|
|
@@ -124,7 +127,17 @@ export class MessageStore {
|
|
|
124
127
|
}));
|
|
125
128
|
return msg ? deserializeInboxMessage(msg) : undefined;
|
|
126
129
|
}
|
|
130
|
+
/** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */ getInboxTreeInProgress() {
|
|
131
|
+
return this.#inboxTreeInProgress.getAsync();
|
|
132
|
+
}
|
|
133
|
+
/** Persists the inbox tree-in-progress checkpoint number from L1 state. */ async setInboxTreeInProgress(value) {
|
|
134
|
+
await this.#inboxTreeInProgress.set(value);
|
|
135
|
+
}
|
|
127
136
|
async getL1ToL2Messages(checkpointNumber) {
|
|
137
|
+
const treeInProgress = await this.#inboxTreeInProgress.getAsync();
|
|
138
|
+
if (treeInProgress !== undefined && BigInt(checkpointNumber) >= treeInProgress) {
|
|
139
|
+
throw new L1ToL2MessagesNotReadyError(checkpointNumber, treeInProgress);
|
|
140
|
+
}
|
|
128
141
|
const messages = [];
|
|
129
142
|
const [startIndex, endIndex] = InboxLeaf.indexRangeForCheckpoint(checkpointNumber);
|
|
130
143
|
let lastIndex = startIndex - 1n;
|
|
@@ -91,7 +91,9 @@ export declare class FakeL1State {
|
|
|
91
91
|
private provenCheckpointNumber;
|
|
92
92
|
private targetCommitteeSize;
|
|
93
93
|
private version;
|
|
94
|
+
private canPruneResult;
|
|
94
95
|
private pendingCheckpointNumber;
|
|
96
|
+
private finalizedL1BlockNumber;
|
|
95
97
|
constructor(config: FakeL1StateConfig);
|
|
96
98
|
/**
|
|
97
99
|
* Adds messages for a checkpoint. Returns the message leaves.
|
|
@@ -124,10 +126,18 @@ export declare class FakeL1State {
|
|
|
124
126
|
* Auto-updates pending checkpoint number based on visible checkpoints.
|
|
125
127
|
*/
|
|
126
128
|
setL1BlockNumber(blockNumber: bigint): void;
|
|
129
|
+
/** Sets the L1 block number that will be reported as "finalized". */
|
|
130
|
+
setFinalizedL1BlockNumber(blockNumber: bigint): void;
|
|
127
131
|
/** Marks a checkpoint as proven. Updates provenCheckpointNumber. */
|
|
128
132
|
markCheckpointAsProven(checkpointNumber: CheckpointNumber): void;
|
|
133
|
+
/**
|
|
134
|
+
* Simulates what `rollup.getProvenCheckpointNumber({ blockNumber: atL1Block })` would return.
|
|
135
|
+
*/
|
|
136
|
+
getProvenCheckpointNumberAtL1Block(atL1Block: bigint): CheckpointNumber;
|
|
129
137
|
/** Sets the target committee size for attestation validation. */
|
|
130
138
|
setTargetCommitteeSize(size: number): void;
|
|
139
|
+
/** Sets whether the rollup contract would allow pruning at the next block. */
|
|
140
|
+
setCanPrune(value: boolean): void;
|
|
131
141
|
/**
|
|
132
142
|
* Removes all entries for a checkpoint number (simulates L1 reorg or prune).
|
|
133
143
|
* Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
|
|
@@ -183,8 +193,10 @@ export declare class FakeL1State {
|
|
|
183
193
|
private getCheckpointProposedLogs;
|
|
184
194
|
private getMessageSentLogs;
|
|
185
195
|
private makeRollupTx;
|
|
196
|
+
/** Extracts the CommitteeAttestations struct definition from RollupAbi for hash computation. */
|
|
197
|
+
private getCommitteeAttestationsStructDef;
|
|
186
198
|
private makeVersionedBlobHashes;
|
|
187
199
|
private makeBlobsFromCheckpoint;
|
|
188
200
|
}
|
|
189
201
|
export {};
|
|
190
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
202
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFrZV9sMV9zdGF0ZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvZmFrZV9sMV9zdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBcUQsTUFBTSxpQkFBaUIsQ0FBQztBQUUvRixPQUFPLEtBQUssRUFBeUIsYUFBYSxFQUFrQixjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV0SCxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBb0IsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFHM0QsT0FBTyxFQUF5RCxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFTdEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFN0QsT0FBTyxFQUFFLEtBQUssU0FBUyxFQUFRLE1BQU0sb0JBQW9CLENBQUM7QUFjMUQsMkNBQTJDO0FBQzNDLE1BQU0sTUFBTSxpQkFBaUIsR0FBRztJQUM5Qiw0QkFBNEI7SUFDNUIsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQ3ZCLDZCQUE2QjtJQUM3QixZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGtDQUFrQztJQUNsQyxhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLHlDQUF5QztJQUN6QyxvQkFBb0IsRUFBRSxNQUFNLENBQUM7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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake_l1_state.d.ts","sourceRoot":"","sources":["../../src/test/fake_l1_state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,IAAI,EAAqD,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"fake_l1_state.d.ts","sourceRoot":"","sources":["../../src/test/fake_l1_state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,IAAI,EAAqD,MAAM,iBAAiB,CAAC;AAE/F,OAAO,KAAK,EAAyB,aAAa,EAAkB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAoB,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAyD,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAStD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,oBAAoB,CAAC;AAc1D,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4BAA4B;IAC5B,kBAAkB,EAAE,EAAE,CAAC;IACvB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,aAAa,EAAE,UAAU,CAAC;IAC1B,wCAAwC;IACxC,YAAY,EAAE,UAAU,CAAC;IACzB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,uCAAuC;AACvC,KAAK,oBAAoB,GAAG;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,4BAA4B;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,iCAAiC;IACjC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,uCAAuC;AACvC,KAAK,mBAAmB,GAAG;IACzB,uCAAuC;IACvC,UAAU,EAAE,UAAU,CAAC;IACvB,iDAAiD;IACjD,QAAQ,EAAE,EAAE,EAAE,CAAC;CAChB,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,WAAW;IAkBV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAjBnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyC;IAC7D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,sBAAsB,CAAyC;IACvE,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,cAAc,CAAkB;IAGxC,OAAO,CAAC,uBAAuB,CAAyC;IAGxE,OAAO,CAAC,sBAAsB,CAAS;IAEvC,YAA6B,MAAM,EAAE,iBAAiB,EAIrD;IAED;;;;;;OAMG;IACH,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,IAAI,CAahG;IAED;;;;OAIG;IACU,UAAU,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,sBAEjG;IAED;;;;OAIG;IACU,aAAa,CACxB,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAuC9B;IAED,yEAAyE;IACzE,OAAO,CAAC,yBAAyB;IA0BjC,mFAAmF;IAC5E,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAG3D;IAED,qFAAqF;IAC9E,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAG1D;IAED;;;OAGG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAG1C;IAED,qEAAqE;IACrE,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAEnD;IAED,oEAAoE;IACpE,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAE/D;IAED;;OAEG;IACH,kCAAkC,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAStE;IAED,iEAAiE;IACjE,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzC;IAED,8EAA8E;IAC9E,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEhC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAGzD;IAED;;;OAGG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAI5C;IAED;;;;OAIG;IACH,sBAAsB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAO/D;IAED;;;OAGG;IACH,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAMlE;IAED;;OAEG;IACH,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIlE;IAED,kCAAkC;IAClC,eAAe,IAAI;QACjB,sBAAsB,EAAE,gBAAgB,CAAC;QACzC,uBAAuB,EAAE,gBAAgB,CAAC;QAC1C,aAAa,EAAE,EAAE,CAAC;QAClB,cAAc,EAAE,EAAE,CAAC;KACpB,CAOA;IAED,6DAA6D;IAC7D,cAAc,IAAI,sBAAsB,CAEvC;IAED,+EAA+E;IAC/E,aAAa,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,UAAU,GAAG,SAAS,CAExE;IAED,sCAAsC;IACtC,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,EAAE,EAAE,CAEpD;IAED,uCAAuC;IACvC,kBAAkB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,EAAE,CAE7D;IAED,mEAAmE;IACnE,wBAAwB,CAAC,aAAa,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,cAAc,CAAC,CAgC9F;IAED,kEAAkE;IAClE,uBAAuB,CAAC,aAAa,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,aAAa,CAAC,CA8B5F;IAED,iEAAiE;IACjE,sBAAsB,IAAI,SAAS,CAAC,gBAAgB,CAAC,CA4BpD;IAED,+DAA+D;IAC/D,oBAAoB,IAAI,SAAS,CAAC,mBAAmB,CAAC,CAarD;IAED,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,kBAAkB;YAqBZ,YAAY;IAyE1B,gGAAgG;IAChG,OAAO,CAAC,iCAAiC;YAkB3B,uBAAuB;YAMvB,uBAAuB;CAGtC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
|
|
2
|
+
import { INITIAL_CHECKPOINT_NUMBER } from '@aztec/constants';
|
|
2
3
|
import { MULTI_CALL_3_ADDRESS } from '@aztec/ethereum/contracts';
|
|
3
4
|
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
4
5
|
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
@@ -7,10 +8,11 @@ import { RollupAbi } from '@aztec/l1-artifacts';
|
|
|
7
8
|
import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
8
9
|
import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
9
10
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
11
|
+
import { ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
|
|
10
12
|
import { makeAndSignCommitteeAttestationsAndSigners, makeCheckpointAttestationFromCheckpoint, mockCheckpointAndMessages } from '@aztec/stdlib/testing';
|
|
11
13
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
12
14
|
import { mock } from 'jest-mock-extended';
|
|
13
|
-
import { encodeFunctionData, multicall3Abi, toHex } from 'viem';
|
|
15
|
+
import { encodeAbiParameters, encodeFunctionData, keccak256, multicall3Abi, toHex } from 'viem';
|
|
14
16
|
import { updateRollingHash } from '../structs/inbox_message.js';
|
|
15
17
|
/**
|
|
16
18
|
* Stateful fake for L1 data used by the archiver.
|
|
@@ -43,8 +45,11 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
43
45
|
provenCheckpointNumber;
|
|
44
46
|
targetCommitteeSize;
|
|
45
47
|
version;
|
|
48
|
+
canPruneResult;
|
|
46
49
|
// Computed from checkpoints based on L1 block visibility
|
|
47
50
|
pendingCheckpointNumber;
|
|
51
|
+
// The L1 block number reported as "finalized" (defaults to the start block)
|
|
52
|
+
finalizedL1BlockNumber;
|
|
48
53
|
constructor(config){
|
|
49
54
|
this.config = config;
|
|
50
55
|
this.log = createLogger('archiver:test:fake-l1');
|
|
@@ -54,8 +59,10 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
54
59
|
this.provenCheckpointNumber = CheckpointNumber(0);
|
|
55
60
|
this.targetCommitteeSize = 0;
|
|
56
61
|
this.version = 1n;
|
|
62
|
+
this.canPruneResult = false;
|
|
57
63
|
this.pendingCheckpointNumber = CheckpointNumber(0);
|
|
58
64
|
this.l1BlockNumber = config.l1StartBlock;
|
|
65
|
+
this.finalizedL1BlockNumber = config.l1StartBlock;
|
|
59
66
|
this.lastArchive = new AppendOnlyTreeSnapshot(config.genesisArchiveRoot, 1);
|
|
60
67
|
}
|
|
61
68
|
/**
|
|
@@ -98,10 +105,10 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
98
105
|
});
|
|
99
106
|
// Store the messages internally so they match the checkpoint's inHash
|
|
100
107
|
this.addMessages(checkpointNumber, messagesL1BlockNumber, messages);
|
|
101
|
-
// Create the transaction and
|
|
102
|
-
const tx = this.makeRollupTx(checkpoint, signers);
|
|
103
|
-
const blobHashes = this.makeVersionedBlobHashes(checkpoint);
|
|
104
|
-
const blobs = this.makeBlobsFromCheckpoint(checkpoint);
|
|
108
|
+
// Create the transaction, blobs, and event hashes
|
|
109
|
+
const { tx, attestationsHash, payloadDigest } = await this.makeRollupTx(checkpoint, signers);
|
|
110
|
+
const blobHashes = await this.makeVersionedBlobHashes(checkpoint);
|
|
111
|
+
const blobs = await this.makeBlobsFromCheckpoint(checkpoint);
|
|
105
112
|
// Store the checkpoint data
|
|
106
113
|
this.checkpoints.push({
|
|
107
114
|
checkpointNumber,
|
|
@@ -110,7 +117,9 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
110
117
|
tx,
|
|
111
118
|
blobHashes,
|
|
112
119
|
blobs,
|
|
113
|
-
signers
|
|
120
|
+
signers,
|
|
121
|
+
attestationsHash,
|
|
122
|
+
payloadDigest
|
|
114
123
|
});
|
|
115
124
|
// Update last archive for auto-chaining
|
|
116
125
|
this.lastArchive = lastArchive ?? checkpoint.blocks.at(-1).archive;
|
|
@@ -152,12 +161,30 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
152
161
|
this.l1BlockNumber = blockNumber;
|
|
153
162
|
this.updatePendingCheckpointNumber();
|
|
154
163
|
}
|
|
164
|
+
/** Sets the L1 block number that will be reported as "finalized". */ setFinalizedL1BlockNumber(blockNumber) {
|
|
165
|
+
this.finalizedL1BlockNumber = blockNumber;
|
|
166
|
+
}
|
|
155
167
|
/** Marks a checkpoint as proven. Updates provenCheckpointNumber. */ markCheckpointAsProven(checkpointNumber) {
|
|
156
168
|
this.provenCheckpointNumber = checkpointNumber;
|
|
157
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Simulates what `rollup.getProvenCheckpointNumber({ blockNumber: atL1Block })` would return.
|
|
172
|
+
*/ getProvenCheckpointNumberAtL1Block(atL1Block) {
|
|
173
|
+
if (this.provenCheckpointNumber === 0) {
|
|
174
|
+
return CheckpointNumber(0);
|
|
175
|
+
}
|
|
176
|
+
const checkpoint = this.checkpoints.find((cp)=>cp.checkpointNumber === this.provenCheckpointNumber);
|
|
177
|
+
if (checkpoint && checkpoint.l1BlockNumber <= atL1Block) {
|
|
178
|
+
return this.provenCheckpointNumber;
|
|
179
|
+
}
|
|
180
|
+
return CheckpointNumber(0);
|
|
181
|
+
}
|
|
158
182
|
/** Sets the target committee size for attestation validation. */ setTargetCommitteeSize(size) {
|
|
159
183
|
this.targetCommitteeSize = size;
|
|
160
184
|
}
|
|
185
|
+
/** Sets whether the rollup contract would allow pruning at the next block. */ setCanPrune(value) {
|
|
186
|
+
this.canPruneResult = value;
|
|
187
|
+
}
|
|
161
188
|
/**
|
|
162
189
|
* Removes all entries for a checkpoint number (simulates L1 reorg or prune).
|
|
163
190
|
* Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
|
|
@@ -238,6 +265,11 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
238
265
|
archiveOfMyCheckpoint: this.getArchiveAt(localCheckpointNum)
|
|
239
266
|
});
|
|
240
267
|
});
|
|
268
|
+
mockRollup.getProvenCheckpointNumber.mockImplementation((options)=>{
|
|
269
|
+
const atBlock = options?.blockNumber ?? this.l1BlockNumber;
|
|
270
|
+
return Promise.resolve(this.getProvenCheckpointNumberAtL1Block(atBlock));
|
|
271
|
+
});
|
|
272
|
+
mockRollup.canPruneAtTime.mockImplementation(()=>Promise.resolve(this.canPruneResult));
|
|
241
273
|
// Mock the wrapper method for fetching checkpoint events
|
|
242
274
|
mockRollup.getCheckpointProposedEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getCheckpointProposedLogs(fromBlock, toBlock)));
|
|
243
275
|
Object.defineProperty(mockRollup, 'address', {
|
|
@@ -247,11 +279,18 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
247
279
|
}
|
|
248
280
|
/** Creates mock InboxContract that reads from this fake state. */ createMockInboxContract(_publicClient) {
|
|
249
281
|
const mockInbox = mock();
|
|
250
|
-
mockInbox.getState.mockImplementation(()=>
|
|
282
|
+
mockInbox.getState.mockImplementation(()=>{
|
|
283
|
+
// treeInProgress must be > any sealed checkpoint. On L1, a checkpoint can only be proposed
|
|
284
|
+
// after its messages are sealed, so treeInProgress > checkpointNumber for all published checkpoints.
|
|
285
|
+
const maxFromMessages = this.messages.length > 0 ? Math.max(...this.messages.map((m)=>Number(m.checkpointNumber))) + 1 : 0;
|
|
286
|
+
const maxFromCheckpoints = this.checkpoints.length > 0 ? Math.max(...this.checkpoints.filter((cp)=>!cp.pruned).map((cp)=>Number(cp.checkpointNumber))) + 1 : 0;
|
|
287
|
+
const treeInProgress = Math.max(maxFromMessages, maxFromCheckpoints, INITIAL_CHECKPOINT_NUMBER);
|
|
288
|
+
return Promise.resolve({
|
|
251
289
|
messagesRollingHash: this.messagesRollingHash,
|
|
252
290
|
totalMessagesInserted: BigInt(this.messages.length),
|
|
253
|
-
treeInProgress:
|
|
254
|
-
})
|
|
291
|
+
treeInProgress: BigInt(treeInProgress)
|
|
292
|
+
});
|
|
293
|
+
});
|
|
255
294
|
// Mock the wrapper methods for fetching message events
|
|
256
295
|
mockInbox.getMessageSentEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock)));
|
|
257
296
|
mockInbox.getMessageSentEventByHash.mockImplementation((hash, fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock, hash)));
|
|
@@ -261,9 +300,13 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
261
300
|
const publicClient = mock();
|
|
262
301
|
publicClient.getChainId.mockResolvedValue(1);
|
|
263
302
|
publicClient.getBlockNumber.mockImplementation(()=>Promise.resolve(this.l1BlockNumber));
|
|
264
|
-
// Use async function pattern that existing test uses for getBlock
|
|
265
303
|
publicClient.getBlock.mockImplementation(async (args = {})=>{
|
|
266
|
-
|
|
304
|
+
let blockNum;
|
|
305
|
+
if (args.blockTag === 'finalized') {
|
|
306
|
+
blockNum = this.finalizedL1BlockNumber;
|
|
307
|
+
} else {
|
|
308
|
+
blockNum = args.blockNumber ?? await publicClient.getBlockNumber();
|
|
309
|
+
}
|
|
267
310
|
return {
|
|
268
311
|
number: blockNum,
|
|
269
312
|
timestamp: BigInt(blockNum) * BigInt(this.config.ethereumSlotDuration) + this.config.l1GenesisTime,
|
|
@@ -310,10 +353,8 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
310
353
|
checkpointNumber: cpData.checkpointNumber,
|
|
311
354
|
archive: cpData.checkpoint.archive.root,
|
|
312
355
|
versionedBlobHashes: cpData.blobHashes.map((h)=>Buffer.from(h.slice(2), 'hex')),
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
payloadDigest: undefined,
|
|
316
|
-
attestationsHash: undefined
|
|
356
|
+
attestationsHash: cpData.attestationsHash,
|
|
357
|
+
payloadDigest: cpData.payloadDigest
|
|
317
358
|
}
|
|
318
359
|
}));
|
|
319
360
|
}
|
|
@@ -330,13 +371,14 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
330
371
|
}
|
|
331
372
|
}));
|
|
332
373
|
}
|
|
333
|
-
makeRollupTx(checkpoint, signers) {
|
|
374
|
+
async makeRollupTx(checkpoint, signers) {
|
|
334
375
|
const attestations = signers.map((signer)=>makeCheckpointAttestationFromCheckpoint(checkpoint, signer)).map((attestation)=>CommitteeAttestation.fromSignature(attestation.signature)).map((committeeAttestation)=>committeeAttestation.toViem());
|
|
335
376
|
const header = checkpoint.header.toViem();
|
|
336
|
-
const blobInput = getPrefixedEthBlobCommitments(getBlobsPerL1Block(checkpoint.toBlobFields()));
|
|
377
|
+
const blobInput = getPrefixedEthBlobCommitments(await getBlobsPerL1Block(checkpoint.toBlobFields()));
|
|
337
378
|
const archive = toHex(checkpoint.archive.root.toBuffer());
|
|
338
379
|
const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations.map((attestation)=>CommitteeAttestation.fromViem(attestation)));
|
|
339
380
|
const attestationsAndSignersSignature = makeAndSignCommitteeAttestationsAndSigners(attestationsAndSigners, signers[0]);
|
|
381
|
+
const packedAttestations = attestationsAndSigners.getPackedAttestations();
|
|
340
382
|
const rollupInput = encodeFunctionData({
|
|
341
383
|
abi: RollupAbi,
|
|
342
384
|
functionName: 'propose',
|
|
@@ -348,7 +390,7 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
348
390
|
feeAssetPriceModifier: 0n
|
|
349
391
|
}
|
|
350
392
|
},
|
|
351
|
-
|
|
393
|
+
packedAttestations,
|
|
352
394
|
attestationsAndSigners.getSigners().map((signer)=>signer.toString()),
|
|
353
395
|
attestationsAndSignersSignature.toViemSignature(),
|
|
354
396
|
blobInput
|
|
@@ -367,17 +409,47 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
367
409
|
]
|
|
368
410
|
]
|
|
369
411
|
});
|
|
370
|
-
|
|
412
|
+
// Compute attestationsHash (same logic as CalldataRetriever)
|
|
413
|
+
const attestationsHash = Buffer32.fromString(keccak256(encodeAbiParameters([
|
|
414
|
+
this.getCommitteeAttestationsStructDef()
|
|
415
|
+
], [
|
|
416
|
+
packedAttestations
|
|
417
|
+
])));
|
|
418
|
+
// Compute payloadDigest (same logic as CalldataRetriever)
|
|
419
|
+
const consensusPayload = ConsensusPayload.fromCheckpoint(checkpoint);
|
|
420
|
+
const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.checkpointAttestation);
|
|
421
|
+
const payloadDigest = Buffer32.fromString(keccak256(payloadToSign));
|
|
422
|
+
const tx = {
|
|
371
423
|
input: multiCallInput,
|
|
372
424
|
hash: archive,
|
|
373
425
|
blockHash: archive,
|
|
374
426
|
to: MULTI_CALL_3_ADDRESS
|
|
375
427
|
};
|
|
428
|
+
return {
|
|
429
|
+
tx,
|
|
430
|
+
attestationsHash,
|
|
431
|
+
payloadDigest
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/** Extracts the CommitteeAttestations struct definition from RollupAbi for hash computation. */ getCommitteeAttestationsStructDef() {
|
|
435
|
+
const proposeFunction = RollupAbi.find((item)=>item.type === 'function' && item.name === 'propose');
|
|
436
|
+
if (!proposeFunction) {
|
|
437
|
+
throw new Error('propose function not found in RollupAbi');
|
|
438
|
+
}
|
|
439
|
+
const attestationsParam = proposeFunction.inputs.find((param)=>param.name === '_attestations');
|
|
440
|
+
if (!attestationsParam) {
|
|
441
|
+
throw new Error('_attestations parameter not found in propose function');
|
|
442
|
+
}
|
|
443
|
+
const tupleParam = attestationsParam;
|
|
444
|
+
return {
|
|
445
|
+
type: 'tuple',
|
|
446
|
+
components: tupleParam.components || []
|
|
447
|
+
};
|
|
376
448
|
}
|
|
377
|
-
makeVersionedBlobHashes(checkpoint) {
|
|
378
|
-
return getBlobsPerL1Block(checkpoint.toBlobFields()).map((b)=>`0x${b.getEthVersionedBlobHash().toString('hex')}`);
|
|
449
|
+
async makeVersionedBlobHashes(checkpoint) {
|
|
450
|
+
return (await getBlobsPerL1Block(checkpoint.toBlobFields())).map((b)=>`0x${b.getEthVersionedBlobHash().toString('hex')}`);
|
|
379
451
|
}
|
|
380
|
-
makeBlobsFromCheckpoint(checkpoint) {
|
|
381
|
-
return getBlobsPerL1Block(checkpoint.toBlobFields());
|
|
452
|
+
async makeBlobsFromCheckpoint(checkpoint) {
|
|
453
|
+
return await getBlobsPerL1Block(checkpoint.toBlobFields());
|
|
382
454
|
}
|
|
383
455
|
}
|
|
@@ -28,4 +28,4 @@ export declare class MockPrefilledArchiver extends MockArchiver {
|
|
|
28
28
|
}[]): void;
|
|
29
29
|
createBlocks(numBlocks: number): Promise<void>;
|
|
30
30
|
}
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvbW9ja19hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3hFLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHbkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFOUQ7O0dBRUc7QUFDSCxxQkFBYSxZQUFhLFNBQVEsaUJBQWtCLFlBQVcsYUFBYSxFQUFFLG1CQUFtQjtJQUMvRixPQUFPLENBQUMsYUFBYSxDQUFrQztJQUVoRCxpQkFBaUIsQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLFFBRXRFO0lBRUQsaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBRW5FO0lBRUQscUJBQXFCLENBQUMsY0FBYyxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUVyRTtDQUNGO0FBRUQ7O0dBRUc7QUFDSCxxQkFBYSxxQkFBc0IsU0FBUSxZQUFZO0lBQ3JELE9BQU8sQ0FBQyxTQUFTLENBQW9CO0lBRXJDLFlBQVksU0FBUyxFQUFFO1FBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQUUsRUFHbEU7SUFFTSxZQUFZLENBQUMsU0FBUyxFQUFFO1FBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQUUsUUFRMUU7SUFFZSxZQUFZLENBQUMsU0FBUyxFQUFFLE1BQU0saUJBYTdDO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock_archiver.d.ts","sourceRoot":"","sources":["../../src/test/mock_archiver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;GAEG;AACH,qBAAa,YAAa,SAAQ,iBAAkB,YAAW,aAAa,EAAE,mBAAmB;IAC/F,OAAO,CAAC,aAAa,CAAkC;IAEhD,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,EAAE,QAEtE;IAED,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAEnE;IAED,qBAAqB,CAAC,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAErE;CACF;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,SAAS,CAAoB;IAErC,YAAY,SAAS,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,EAAE,EAAE,CAAA;KAAE,EAAE,EAGlE;IAEM,YAAY,CAAC,SAAS,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,EAAE,EAAE,CAAA;KAAE,EAAE,QAQ1E;IAEe,YAAY,CAAC,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mock_archiver.d.ts","sourceRoot":"","sources":["../../src/test/mock_archiver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;GAEG;AACH,qBAAa,YAAa,SAAQ,iBAAkB,YAAW,aAAa,EAAE,mBAAmB;IAC/F,OAAO,CAAC,aAAa,CAAkC;IAEhD,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,EAAE,QAEtE;IAED,iBAAiB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAEnE;IAED,qBAAqB,CAAC,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAErE;CACF;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,SAAS,CAAoB;IAErC,YAAY,SAAS,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,EAAE,EAAE,CAAA;KAAE,EAAE,EAGlE;IAEM,YAAY,CAAC,SAAS,EAAE;QAAE,UAAU,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,EAAE,EAAE,CAAA;KAAE,EAAE,QAQ1E;IAEe,YAAY,CAAC,SAAS,EAAE,MAAM,iBAa7C;CACF"}
|
|
@@ -37,8 +37,9 @@ import { MockL2BlockSource } from './mock_l2_block_source.js';
|
|
|
37
37
|
throw new Error(`Not enough precomputed blocks to create ${numBlocks} more blocks (already at ${this.l2Blocks.length})`);
|
|
38
38
|
}
|
|
39
39
|
const fromBlock = this.l2Blocks.length;
|
|
40
|
-
|
|
41
|
-
this.addProposedBlocks(
|
|
40
|
+
const checkpointsToAdd = this.prefilled.slice(fromBlock, fromBlock + numBlocks);
|
|
41
|
+
this.addProposedBlocks(checkpointsToAdd.flatMap((c)=>c.blocks));
|
|
42
|
+
this.checkpointList.push(...checkpointsToAdd);
|
|
42
43
|
return Promise.resolve();
|
|
43
44
|
}
|
|
44
45
|
}
|