@aztec/archiver 0.0.1-commit.c80b6263 → 0.0.1-commit.cf93bcc56
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 +5 -2
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +9 -91
- package/dest/factory.d.ts +1 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +9 -4
- 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 +18 -19
- package/dest/l1/calldata_retriever.d.ts +7 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +17 -4
- package/dest/l1/data_retrieval.d.ts +3 -2
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +4 -3
- package/dest/modules/data_source_base.d.ts +11 -6
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +28 -72
- package/dest/modules/data_store_updater.d.ts +9 -2
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +40 -19
- package/dest/modules/instrumentation.d.ts +4 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +9 -2
- package/dest/modules/l1_synchronizer.d.ts +3 -2
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +6 -6
- package/dest/store/block_store.d.ts +19 -15
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +71 -19
- package/dest/store/contract_class_store.d.ts +1 -1
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +11 -7
- package/dest/store/kv_archiver_store.d.ts +21 -7
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +20 -3
- 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 +1 -1
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +56 -36
- package/dest/test/fake_l1_state.d.ts +4 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +15 -9
- 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 -6
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +127 -84
- package/package.json +13 -13
- package/src/archiver.ts +10 -110
- package/src/factory.ts +23 -8
- package/src/index.ts +1 -0
- package/src/l1/bin/retrieve-calldata.ts +17 -23
- package/src/l1/calldata_retriever.ts +25 -3
- package/src/l1/data_retrieval.ts +4 -1
- package/src/modules/data_source_base.ts +56 -95
- package/src/modules/data_store_updater.ts +43 -18
- package/src/modules/instrumentation.ts +9 -2
- package/src/modules/l1_synchronizer.ts +7 -5
- package/src/store/block_store.ts +87 -38
- package/src/store/contract_class_store.ts +11 -7
- package/src/store/kv_archiver_store.ts +40 -8
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +95 -33
- package/src/test/fake_l1_state.ts +17 -9
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +163 -83
package/src/store/log_store.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
Tag,
|
|
21
21
|
TxScopedL2Log,
|
|
22
22
|
} from '@aztec/stdlib/logs';
|
|
23
|
+
import { TxHash } from '@aztec/stdlib/tx';
|
|
23
24
|
|
|
24
25
|
import type { BlockStore } from './block_store.js';
|
|
25
26
|
|
|
@@ -219,6 +220,7 @@ export class LogStore {
|
|
|
219
220
|
.map((txEffect, txIndex) =>
|
|
220
221
|
[
|
|
221
222
|
numToUInt32BE(txIndex),
|
|
223
|
+
txEffect.txHash.toBuffer(),
|
|
222
224
|
numToUInt32BE(txEffect.publicLogs.length),
|
|
223
225
|
txEffect.publicLogs.map(log => log.toBuffer()),
|
|
224
226
|
].flat(),
|
|
@@ -242,6 +244,7 @@ export class LogStore {
|
|
|
242
244
|
.map((txEffect, txIndex) =>
|
|
243
245
|
[
|
|
244
246
|
numToUInt32BE(txIndex),
|
|
247
|
+
txEffect.txHash.toBuffer(),
|
|
245
248
|
numToUInt32BE(txEffect.contractClassLogs.length),
|
|
246
249
|
txEffect.contractClassLogs.map(log => log.toBuffer()),
|
|
247
250
|
].flat(),
|
|
@@ -271,7 +274,7 @@ export class LogStore {
|
|
|
271
274
|
});
|
|
272
275
|
}
|
|
273
276
|
|
|
274
|
-
#packWithBlockHash(blockHash:
|
|
277
|
+
#packWithBlockHash(blockHash: BlockHash, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
|
|
275
278
|
return Buffer.concat([blockHash.toBuffer(), ...data]);
|
|
276
279
|
}
|
|
277
280
|
|
|
@@ -282,7 +285,7 @@ export class LogStore {
|
|
|
282
285
|
throw new Error('Failed to read block hash from log entry buffer');
|
|
283
286
|
}
|
|
284
287
|
|
|
285
|
-
return BlockHash
|
|
288
|
+
return new BlockHash(blockHash);
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
@@ -386,24 +389,33 @@ export class LogStore {
|
|
|
386
389
|
}
|
|
387
390
|
|
|
388
391
|
const buffer = (await this.#publicLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
|
|
389
|
-
const publicLogsInBlock:
|
|
392
|
+
const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
|
|
390
393
|
const reader = new BufferReader(buffer);
|
|
391
394
|
|
|
392
395
|
const blockHash = this.#unpackBlockHash(reader);
|
|
393
396
|
|
|
394
397
|
while (reader.remainingBytes() > 0) {
|
|
395
398
|
const indexOfTx = reader.readNumber();
|
|
399
|
+
const txHash = reader.readObject(TxHash);
|
|
396
400
|
const numLogsInTx = reader.readNumber();
|
|
397
|
-
publicLogsInBlock[indexOfTx] = [];
|
|
401
|
+
publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
398
402
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
399
|
-
publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
|
|
403
|
+
publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
|
|
400
404
|
}
|
|
401
405
|
}
|
|
402
406
|
|
|
403
|
-
const
|
|
407
|
+
const txData = publicLogsInBlock[txIndex];
|
|
404
408
|
|
|
405
409
|
const logs: ExtendedPublicLog[] = [];
|
|
406
|
-
const maxLogsHit = this.#
|
|
410
|
+
const maxLogsHit = this.#accumulatePublicLogs(
|
|
411
|
+
logs,
|
|
412
|
+
blockNumber,
|
|
413
|
+
blockHash,
|
|
414
|
+
txIndex,
|
|
415
|
+
txData.txHash,
|
|
416
|
+
txData.logs,
|
|
417
|
+
filter,
|
|
418
|
+
);
|
|
407
419
|
|
|
408
420
|
return { logs, maxLogsHit };
|
|
409
421
|
}
|
|
@@ -424,22 +436,31 @@ export class LogStore {
|
|
|
424
436
|
|
|
425
437
|
let maxLogsHit = false;
|
|
426
438
|
loopOverBlocks: for await (const [blockNumber, logBuffer] of this.#publicLogsByBlock.entriesAsync({ start, end })) {
|
|
427
|
-
const publicLogsInBlock:
|
|
439
|
+
const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
|
|
428
440
|
const reader = new BufferReader(logBuffer);
|
|
429
441
|
|
|
430
442
|
const blockHash = this.#unpackBlockHash(reader);
|
|
431
443
|
|
|
432
444
|
while (reader.remainingBytes() > 0) {
|
|
433
445
|
const indexOfTx = reader.readNumber();
|
|
446
|
+
const txHash = reader.readObject(TxHash);
|
|
434
447
|
const numLogsInTx = reader.readNumber();
|
|
435
|
-
publicLogsInBlock[indexOfTx] = [];
|
|
448
|
+
publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
436
449
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
437
|
-
publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
|
|
450
|
+
publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
|
|
438
451
|
}
|
|
439
452
|
}
|
|
440
453
|
for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++) {
|
|
441
|
-
const
|
|
442
|
-
maxLogsHit = this.#
|
|
454
|
+
const txData = publicLogsInBlock[txIndex];
|
|
455
|
+
maxLogsHit = this.#accumulatePublicLogs(
|
|
456
|
+
logs,
|
|
457
|
+
blockNumber,
|
|
458
|
+
blockHash,
|
|
459
|
+
txIndex,
|
|
460
|
+
txData.txHash,
|
|
461
|
+
txData.logs,
|
|
462
|
+
filter,
|
|
463
|
+
);
|
|
443
464
|
if (maxLogsHit) {
|
|
444
465
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
445
466
|
break loopOverBlocks;
|
|
@@ -475,24 +496,33 @@ export class LogStore {
|
|
|
475
496
|
return { logs: [], maxLogsHit: false };
|
|
476
497
|
}
|
|
477
498
|
const contractClassLogsBuffer = (await this.#contractClassLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
|
|
478
|
-
const contractClassLogsInBlock:
|
|
499
|
+
const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
|
|
479
500
|
|
|
480
501
|
const reader = new BufferReader(contractClassLogsBuffer);
|
|
481
502
|
const blockHash = this.#unpackBlockHash(reader);
|
|
482
503
|
|
|
483
504
|
while (reader.remainingBytes() > 0) {
|
|
484
505
|
const indexOfTx = reader.readNumber();
|
|
506
|
+
const txHash = reader.readObject(TxHash);
|
|
485
507
|
const numLogsInTx = reader.readNumber();
|
|
486
|
-
contractClassLogsInBlock[indexOfTx] = [];
|
|
508
|
+
contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
487
509
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
488
|
-
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
510
|
+
contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
|
|
489
511
|
}
|
|
490
512
|
}
|
|
491
513
|
|
|
492
|
-
const
|
|
514
|
+
const txData = contractClassLogsInBlock[txIndex];
|
|
493
515
|
|
|
494
516
|
const logs: ExtendedContractClassLog[] = [];
|
|
495
|
-
const maxLogsHit = this.#
|
|
517
|
+
const maxLogsHit = this.#accumulateContractClassLogs(
|
|
518
|
+
logs,
|
|
519
|
+
blockNumber,
|
|
520
|
+
blockHash,
|
|
521
|
+
txIndex,
|
|
522
|
+
txData.txHash,
|
|
523
|
+
txData.logs,
|
|
524
|
+
filter,
|
|
525
|
+
);
|
|
496
526
|
|
|
497
527
|
return { logs, maxLogsHit };
|
|
498
528
|
}
|
|
@@ -516,20 +546,29 @@ export class LogStore {
|
|
|
516
546
|
start,
|
|
517
547
|
end,
|
|
518
548
|
})) {
|
|
519
|
-
const contractClassLogsInBlock:
|
|
549
|
+
const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
|
|
520
550
|
const reader = new BufferReader(logBuffer);
|
|
521
551
|
const blockHash = this.#unpackBlockHash(reader);
|
|
522
552
|
while (reader.remainingBytes() > 0) {
|
|
523
553
|
const indexOfTx = reader.readNumber();
|
|
554
|
+
const txHash = reader.readObject(TxHash);
|
|
524
555
|
const numLogsInTx = reader.readNumber();
|
|
525
|
-
contractClassLogsInBlock[indexOfTx] = [];
|
|
556
|
+
contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
526
557
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
527
|
-
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
558
|
+
contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
|
|
528
559
|
}
|
|
529
560
|
}
|
|
530
561
|
for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++) {
|
|
531
|
-
const
|
|
532
|
-
maxLogsHit = this.#
|
|
562
|
+
const txData = contractClassLogsInBlock[txIndex];
|
|
563
|
+
maxLogsHit = this.#accumulateContractClassLogs(
|
|
564
|
+
logs,
|
|
565
|
+
blockNumber,
|
|
566
|
+
blockHash,
|
|
567
|
+
txIndex,
|
|
568
|
+
txData.txHash,
|
|
569
|
+
txData.logs,
|
|
570
|
+
filter,
|
|
571
|
+
);
|
|
533
572
|
if (maxLogsHit) {
|
|
534
573
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
535
574
|
break loopOverBlocks;
|
|
@@ -540,12 +579,13 @@ export class LogStore {
|
|
|
540
579
|
return { logs, maxLogsHit };
|
|
541
580
|
}
|
|
542
581
|
|
|
543
|
-
#
|
|
544
|
-
results:
|
|
582
|
+
#accumulatePublicLogs(
|
|
583
|
+
results: ExtendedPublicLog[],
|
|
545
584
|
blockNumber: number,
|
|
546
585
|
blockHash: BlockHash,
|
|
547
586
|
txIndex: number,
|
|
548
|
-
|
|
587
|
+
txHash: TxHash,
|
|
588
|
+
txLogs: PublicLog[],
|
|
549
589
|
filter: LogFilter = {},
|
|
550
590
|
): boolean {
|
|
551
591
|
let maxLogsHit = false;
|
|
@@ -553,15 +593,37 @@ export class LogStore {
|
|
|
553
593
|
for (; logIndex < txLogs.length; logIndex++) {
|
|
554
594
|
const log = txLogs[logIndex];
|
|
555
595
|
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
throw new Error('Unknown log type');
|
|
596
|
+
results.push(
|
|
597
|
+
new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
if (results.length >= this.#logsMaxPageSize) {
|
|
601
|
+
maxLogsHit = true;
|
|
602
|
+
break;
|
|
564
603
|
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return maxLogsHit;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
#accumulateContractClassLogs(
|
|
611
|
+
results: ExtendedContractClassLog[],
|
|
612
|
+
blockNumber: number,
|
|
613
|
+
blockHash: BlockHash,
|
|
614
|
+
txIndex: number,
|
|
615
|
+
txHash: TxHash,
|
|
616
|
+
txLogs: ContractClassLog[],
|
|
617
|
+
filter: LogFilter = {},
|
|
618
|
+
): boolean {
|
|
619
|
+
let maxLogsHit = false;
|
|
620
|
+
let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
|
|
621
|
+
for (; logIndex < txLogs.length; logIndex++) {
|
|
622
|
+
const log = txLogs[logIndex];
|
|
623
|
+
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
624
|
+
results.push(
|
|
625
|
+
new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
|
|
626
|
+
);
|
|
565
627
|
|
|
566
628
|
if (results.length >= this.#logsMaxPageSize) {
|
|
567
629
|
maxLogsHit = true;
|
|
@@ -131,6 +131,7 @@ export class FakeL1State {
|
|
|
131
131
|
private provenCheckpointNumber: CheckpointNumber = CheckpointNumber(0);
|
|
132
132
|
private targetCommitteeSize: number = 0;
|
|
133
133
|
private version: bigint = 1n;
|
|
134
|
+
private canPruneResult: boolean = false;
|
|
134
135
|
|
|
135
136
|
// Computed from checkpoints based on L1 block visibility
|
|
136
137
|
private pendingCheckpointNumber: CheckpointNumber = CheckpointNumber(0);
|
|
@@ -194,9 +195,9 @@ export class FakeL1State {
|
|
|
194
195
|
this.addMessages(checkpointNumber, messagesL1BlockNumber, messages);
|
|
195
196
|
|
|
196
197
|
// Create the transaction and blobs
|
|
197
|
-
const tx = this.makeRollupTx(checkpoint, signers);
|
|
198
|
-
const blobHashes = this.makeVersionedBlobHashes(checkpoint);
|
|
199
|
-
const blobs = this.makeBlobsFromCheckpoint(checkpoint);
|
|
198
|
+
const tx = await this.makeRollupTx(checkpoint, signers);
|
|
199
|
+
const blobHashes = await this.makeVersionedBlobHashes(checkpoint);
|
|
200
|
+
const blobs = await this.makeBlobsFromCheckpoint(checkpoint);
|
|
200
201
|
|
|
201
202
|
// Store the checkpoint data
|
|
202
203
|
this.checkpoints.push({
|
|
@@ -276,6 +277,11 @@ export class FakeL1State {
|
|
|
276
277
|
this.targetCommitteeSize = size;
|
|
277
278
|
}
|
|
278
279
|
|
|
280
|
+
/** Sets whether the rollup contract would allow pruning at the next block. */
|
|
281
|
+
setCanPrune(value: boolean): void {
|
|
282
|
+
this.canPruneResult = value;
|
|
283
|
+
}
|
|
284
|
+
|
|
279
285
|
/**
|
|
280
286
|
* Removes all entries for a checkpoint number (simulates L1 reorg or prune).
|
|
281
287
|
* Note: Does NOT remove messages for this checkpoint (use numL1ToL2Messages: 0 when re-adding).
|
|
@@ -384,6 +390,8 @@ export class FakeL1State {
|
|
|
384
390
|
});
|
|
385
391
|
});
|
|
386
392
|
|
|
393
|
+
mockRollup.canPruneAtTime.mockImplementation(() => Promise.resolve(this.canPruneResult));
|
|
394
|
+
|
|
387
395
|
// Mock the wrapper method for fetching checkpoint events
|
|
388
396
|
mockRollup.getCheckpointProposedEvents.mockImplementation((fromBlock: bigint, toBlock: bigint) =>
|
|
389
397
|
Promise.resolve(this.getCheckpointProposedLogs(fromBlock, toBlock)),
|
|
@@ -531,14 +539,14 @@ export class FakeL1State {
|
|
|
531
539
|
}));
|
|
532
540
|
}
|
|
533
541
|
|
|
534
|
-
private makeRollupTx(checkpoint: Checkpoint, signers: Secp256k1Signer[]): Transaction {
|
|
542
|
+
private async makeRollupTx(checkpoint: Checkpoint, signers: Secp256k1Signer[]): Promise<Transaction> {
|
|
535
543
|
const attestations = signers
|
|
536
544
|
.map(signer => makeCheckpointAttestationFromCheckpoint(checkpoint, signer))
|
|
537
545
|
.map(attestation => CommitteeAttestation.fromSignature(attestation.signature))
|
|
538
546
|
.map(committeeAttestation => committeeAttestation.toViem());
|
|
539
547
|
|
|
540
548
|
const header = checkpoint.header.toViem();
|
|
541
|
-
const blobInput = getPrefixedEthBlobCommitments(getBlobsPerL1Block(checkpoint.toBlobFields()));
|
|
549
|
+
const blobInput = getPrefixedEthBlobCommitments(await getBlobsPerL1Block(checkpoint.toBlobFields()));
|
|
542
550
|
const archive = toHex(checkpoint.archive.root.toBuffer());
|
|
543
551
|
const attestationsAndSigners = new CommitteeAttestationsAndSigners(
|
|
544
552
|
attestations.map(attestation => CommitteeAttestation.fromViem(attestation)),
|
|
@@ -587,13 +595,13 @@ export class FakeL1State {
|
|
|
587
595
|
} as Transaction<bigint, number>;
|
|
588
596
|
}
|
|
589
597
|
|
|
590
|
-
private makeVersionedBlobHashes(checkpoint: Checkpoint):
|
|
591
|
-
return getBlobsPerL1Block(checkpoint.toBlobFields()).map(
|
|
598
|
+
private async makeVersionedBlobHashes(checkpoint: Checkpoint): Promise<`0x${string}`[]> {
|
|
599
|
+
return (await getBlobsPerL1Block(checkpoint.toBlobFields())).map(
|
|
592
600
|
b => `0x${b.getEthVersionedBlobHash().toString('hex')}` as `0x${string}`,
|
|
593
601
|
);
|
|
594
602
|
}
|
|
595
603
|
|
|
596
|
-
private makeBlobsFromCheckpoint(checkpoint: Checkpoint): Blob[] {
|
|
597
|
-
return getBlobsPerL1Block(checkpoint.toBlobFields());
|
|
604
|
+
private async makeBlobsFromCheckpoint(checkpoint: Checkpoint): Promise<Blob[]> {
|
|
605
|
+
return await getBlobsPerL1Block(checkpoint.toBlobFields());
|
|
598
606
|
}
|
|
599
607
|
}
|
|
@@ -56,8 +56,9 @@ export class MockPrefilledArchiver extends MockArchiver {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const fromBlock = this.l2Blocks.length;
|
|
59
|
-
|
|
60
|
-
this.addProposedBlocks(
|
|
59
|
+
const checkpointsToAdd = this.prefilled.slice(fromBlock, fromBlock + numBlocks);
|
|
60
|
+
this.addProposedBlocks(checkpointsToAdd.flatMap(c => c.blocks));
|
|
61
|
+
this.checkpointList.push(...checkpointsToAdd);
|
|
61
62
|
return Promise.resolve();
|
|
62
63
|
}
|
|
63
64
|
}
|