@aztec/archiver 0.0.1-commit.8afd444 → 0.0.1-commit.8ee97c858
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 +36 -33
- 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 +148 -51
- 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 +46 -39
- 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 +219 -58
- 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
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
4
|
+
import type { CheckpointData } from '@aztec/stdlib/checkpoint';
|
|
5
|
+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
+
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
3
7
|
import {
|
|
4
8
|
Attributes,
|
|
5
9
|
type Gauge,
|
|
@@ -17,6 +21,7 @@ export class ArchiverInstrumentation {
|
|
|
17
21
|
public readonly tracer: Tracer;
|
|
18
22
|
|
|
19
23
|
private blockHeight: Gauge;
|
|
24
|
+
private checkpointHeight: Gauge;
|
|
20
25
|
private txCount: UpDownCounter;
|
|
21
26
|
private l1BlockHeight: Gauge;
|
|
22
27
|
private proofsSubmittedDelay: Histogram;
|
|
@@ -36,6 +41,8 @@ export class ArchiverInstrumentation {
|
|
|
36
41
|
|
|
37
42
|
private blockProposalTxTargetCount: UpDownCounter;
|
|
38
43
|
|
|
44
|
+
private checkpointL1InclusionDelay: Histogram;
|
|
45
|
+
|
|
39
46
|
private log = createLogger('archiver:instrumentation');
|
|
40
47
|
|
|
41
48
|
private constructor(
|
|
@@ -47,6 +54,8 @@ export class ArchiverInstrumentation {
|
|
|
47
54
|
|
|
48
55
|
this.blockHeight = meter.createGauge(Metrics.ARCHIVER_BLOCK_HEIGHT);
|
|
49
56
|
|
|
57
|
+
this.checkpointHeight = meter.createGauge(Metrics.ARCHIVER_CHECKPOINT_HEIGHT);
|
|
58
|
+
|
|
50
59
|
this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT);
|
|
51
60
|
|
|
52
61
|
this.txCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_TOTAL_TXS);
|
|
@@ -81,6 +90,8 @@ export class ArchiverInstrumentation {
|
|
|
81
90
|
},
|
|
82
91
|
);
|
|
83
92
|
|
|
93
|
+
this.checkpointL1InclusionDelay = meter.createHistogram(Metrics.ARCHIVER_CHECKPOINT_L1_INCLUSION_DELAY);
|
|
94
|
+
|
|
84
95
|
this.dbMetrics = new LmdbMetrics(
|
|
85
96
|
meter,
|
|
86
97
|
{
|
|
@@ -105,6 +116,7 @@ export class ArchiverInstrumentation {
|
|
|
105
116
|
public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
|
|
106
117
|
this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
|
|
107
118
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
119
|
+
this.checkpointHeight.record(Math.max(...blocks.map(b => b.checkpointNumber)));
|
|
108
120
|
this.syncBlockCount.add(blocks.length);
|
|
109
121
|
|
|
110
122
|
for (const block of blocks) {
|
|
@@ -127,8 +139,10 @@ export class ArchiverInstrumentation {
|
|
|
127
139
|
this.pruneDuration.record(Math.ceil(duration));
|
|
128
140
|
}
|
|
129
141
|
|
|
130
|
-
public
|
|
131
|
-
|
|
142
|
+
public updateLastProvenCheckpoint(checkpoint: CheckpointData) {
|
|
143
|
+
const lastBlockNumberInCheckpoint = checkpoint.startBlock + checkpoint.blockCount - 1;
|
|
144
|
+
this.blockHeight.record(lastBlockNumberInCheckpoint, { [Attributes.STATUS]: 'proven' });
|
|
145
|
+
this.checkpointHeight.record(checkpoint.checkpointNumber, { [Attributes.STATUS]: 'proven' });
|
|
132
146
|
}
|
|
133
147
|
|
|
134
148
|
public processProofsVerified(logs: { proverId: string; l2BlockNumber: bigint; delay: bigint }[]) {
|
|
@@ -154,4 +168,17 @@ export class ArchiverInstrumentation {
|
|
|
154
168
|
[Attributes.L1_BLOCK_PROPOSAL_USED_TRACE]: usedTrace,
|
|
155
169
|
});
|
|
156
170
|
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Records L1 inclusion timing for a checkpoint observed on L1 (seconds into the L2 slot).
|
|
174
|
+
*/
|
|
175
|
+
public processCheckpointL1Timing(data: {
|
|
176
|
+
slotNumber: SlotNumber;
|
|
177
|
+
l1Timestamp: bigint;
|
|
178
|
+
l1Constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>;
|
|
179
|
+
}): void {
|
|
180
|
+
const slotStartTs = getTimestampForSlot(data.slotNumber, data.l1Constants);
|
|
181
|
+
const inclusionDelaySeconds = Number(data.l1Timestamp - slotStartTs);
|
|
182
|
+
this.checkpointL1InclusionDelay.record(inclusionDelaySeconds);
|
|
183
|
+
}
|
|
157
184
|
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
2
2
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
3
3
|
import { InboxContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
4
|
-
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
5
4
|
import type { L1BlockId } from '@aztec/ethereum/l1-types';
|
|
6
5
|
import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
6
|
+
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
7
7
|
import { maxBigint } from '@aztec/foundation/bigint';
|
|
8
8
|
import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
9
9
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
10
10
|
import { pick } from '@aztec/foundation/collection';
|
|
11
11
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
13
12
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
14
13
|
import { count } from '@aztec/foundation/string';
|
|
15
14
|
import { DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
|
|
@@ -28,6 +27,7 @@ import {
|
|
|
28
27
|
retrievedToPublishedCheckpoint,
|
|
29
28
|
} from '../l1/data_retrieval.js';
|
|
30
29
|
import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
|
|
30
|
+
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
31
31
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
32
32
|
import { ArchiverDataStoreUpdater } from './data_store_updater.js';
|
|
33
33
|
import type { ArchiverInstrumentation } from './instrumentation.js';
|
|
@@ -60,10 +60,6 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
60
60
|
private readonly debugClient: ViemPublicDebugClient,
|
|
61
61
|
private readonly rollup: RollupContract,
|
|
62
62
|
private readonly inbox: InboxContract,
|
|
63
|
-
private readonly l1Addresses: Pick<
|
|
64
|
-
L1ContractAddresses,
|
|
65
|
-
'registryAddress' | 'governanceProposerAddress' | 'slashFactoryAddress'
|
|
66
|
-
> & { slashingProposerAddress: EthAddress },
|
|
67
63
|
private readonly store: KVArchiverDataStore,
|
|
68
64
|
private config: {
|
|
69
65
|
batchSize: number;
|
|
@@ -74,12 +70,18 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
74
70
|
private readonly epochCache: EpochCache,
|
|
75
71
|
private readonly dateProvider: DateProvider,
|
|
76
72
|
private readonly instrumentation: ArchiverInstrumentation,
|
|
77
|
-
private readonly l1Constants: L1RollupConstants & {
|
|
73
|
+
private readonly l1Constants: L1RollupConstants & {
|
|
74
|
+
l1StartBlockHash: Buffer32;
|
|
75
|
+
genesisArchiveRoot: Fr;
|
|
76
|
+
},
|
|
78
77
|
private readonly events: ArchiverEmitter,
|
|
79
78
|
tracer: Tracer,
|
|
79
|
+
l2TipsCache?: L2TipsCache,
|
|
80
80
|
private readonly log: Logger = createLogger('archiver:l1-sync'),
|
|
81
81
|
) {
|
|
82
|
-
this.updater = new ArchiverDataStoreUpdater(this.store
|
|
82
|
+
this.updater = new ArchiverDataStoreUpdater(this.store, l2TipsCache, {
|
|
83
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
84
|
+
});
|
|
83
85
|
this.tracer = tracer;
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -215,6 +217,9 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
215
217
|
this.instrumentation.updateL1BlockHeight(currentL1BlockNumber);
|
|
216
218
|
}
|
|
217
219
|
|
|
220
|
+
// Update the finalized L2 checkpoint based on L1 finality.
|
|
221
|
+
await this.updateFinalizedCheckpoint();
|
|
222
|
+
|
|
218
223
|
// After syncing has completed, update the current l1 block number and timestamp,
|
|
219
224
|
// otherwise we risk announcing to the world that we've synced to a given point,
|
|
220
225
|
// but the corresponding blocks have not been processed (see #12631).
|
|
@@ -230,6 +235,27 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
230
235
|
});
|
|
231
236
|
}
|
|
232
237
|
|
|
238
|
+
/** Query L1 for its finalized block and update the finalized checkpoint accordingly. */
|
|
239
|
+
private async updateFinalizedCheckpoint(): Promise<void> {
|
|
240
|
+
try {
|
|
241
|
+
const finalizedL1Block = await this.publicClient.getBlock({ blockTag: 'finalized', includeTransactions: false });
|
|
242
|
+
const finalizedL1BlockNumber = finalizedL1Block.number;
|
|
243
|
+
const finalizedCheckpointNumber = await this.rollup.getProvenCheckpointNumber({
|
|
244
|
+
blockNumber: finalizedL1BlockNumber,
|
|
245
|
+
});
|
|
246
|
+
const localFinalizedCheckpointNumber = await this.store.getFinalizedCheckpointNumber();
|
|
247
|
+
if (localFinalizedCheckpointNumber !== finalizedCheckpointNumber) {
|
|
248
|
+
await this.updater.setFinalizedCheckpointNumber(finalizedCheckpointNumber);
|
|
249
|
+
this.log.info(`Updated finalized chain to checkpoint ${finalizedCheckpointNumber}`, {
|
|
250
|
+
finalizedCheckpointNumber,
|
|
251
|
+
finalizedL1BlockNumber,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
} catch (err) {
|
|
255
|
+
this.log.warn(`Failed to update finalized checkpoint: ${err}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
233
259
|
/** Prune all proposed local blocks that should have been checkpointed by now. */
|
|
234
260
|
private async pruneUncheckpointedBlocks(currentL1Timestamp: bigint) {
|
|
235
261
|
const [lastCheckpointedBlockNumber, lastProposedBlockNumber] = await Promise.all([
|
|
@@ -308,17 +334,20 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
308
334
|
|
|
309
335
|
const checkpointsToUnwind = localPendingCheckpointNumber - provenCheckpointNumber;
|
|
310
336
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
checkpoints
|
|
318
|
-
.filter(isDefined)
|
|
319
|
-
.map(cp => this.store.getBlocksForCheckpoint(CheckpointNumber(cp.checkpointNumber))),
|
|
337
|
+
// Fetch checkpoints and blocks in bounded batches to avoid unbounded concurrent
|
|
338
|
+
// promises when the gap between local pending and proven checkpoint numbers is large.
|
|
339
|
+
const BATCH_SIZE = 10;
|
|
340
|
+
const indices = Array.from({ length: checkpointsToUnwind }, (_, i) => CheckpointNumber(i + pruneFrom));
|
|
341
|
+
const checkpoints = (await asyncPool(BATCH_SIZE, indices, idx => this.store.getCheckpointData(idx))).filter(
|
|
342
|
+
isDefined,
|
|
320
343
|
);
|
|
321
|
-
const newBlocks =
|
|
344
|
+
const newBlocks = (
|
|
345
|
+
await asyncPool(BATCH_SIZE, checkpoints, cp =>
|
|
346
|
+
this.store.getBlocksForCheckpoint(CheckpointNumber(cp.checkpointNumber)),
|
|
347
|
+
)
|
|
348
|
+
)
|
|
349
|
+
.filter(isDefined)
|
|
350
|
+
.flat();
|
|
322
351
|
|
|
323
352
|
// Emit an event for listening services to react to the chain prune
|
|
324
353
|
this.events.emit(L2BlockSourceEvents.L2PruneUnproven, {
|
|
@@ -366,6 +395,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
366
395
|
const localMessagesInserted = await this.store.getTotalL1ToL2MessageCount();
|
|
367
396
|
const localLastMessage = await this.store.getLastL1ToL2Message();
|
|
368
397
|
const remoteMessagesState = await this.inbox.getState({ blockNumber: currentL1BlockNumber });
|
|
398
|
+
await this.store.setInboxTreeInProgress(remoteMessagesState.treeInProgress);
|
|
369
399
|
|
|
370
400
|
this.log.trace(`Retrieved remote inbox state at L1 block ${currentL1BlockNumber}.`, {
|
|
371
401
|
localMessagesInserted,
|
|
@@ -550,7 +580,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
550
580
|
if (provenCheckpointNumber === 0) {
|
|
551
581
|
const localProvenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
552
582
|
if (localProvenCheckpointNumber !== provenCheckpointNumber) {
|
|
553
|
-
await this.
|
|
583
|
+
await this.updater.setProvenCheckpointNumber(provenCheckpointNumber);
|
|
554
584
|
this.log.info(`Rolled back proven chain to checkpoint ${provenCheckpointNumber}`, { provenCheckpointNumber });
|
|
555
585
|
}
|
|
556
586
|
}
|
|
@@ -582,13 +612,13 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
582
612
|
) {
|
|
583
613
|
const localProvenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
584
614
|
if (localProvenCheckpointNumber !== provenCheckpointNumber) {
|
|
585
|
-
await this.
|
|
615
|
+
await this.updater.setProvenCheckpointNumber(provenCheckpointNumber);
|
|
586
616
|
this.log.info(`Updated proven chain to checkpoint ${provenCheckpointNumber}`, { provenCheckpointNumber });
|
|
587
617
|
const provenSlotNumber = localCheckpointForDestinationProvenCheckpointNumber.header.slotNumber;
|
|
588
618
|
const provenEpochNumber: EpochNumber = getEpochAtSlot(provenSlotNumber, this.l1Constants);
|
|
589
619
|
const lastBlockNumberInCheckpoint =
|
|
590
620
|
localCheckpointForDestinationProvenCheckpointNumber.startBlock +
|
|
591
|
-
localCheckpointForDestinationProvenCheckpointNumber.
|
|
621
|
+
localCheckpointForDestinationProvenCheckpointNumber.blockCount -
|
|
592
622
|
1;
|
|
593
623
|
|
|
594
624
|
this.events.emit(L2BlockSourceEvents.L2BlockProven, {
|
|
@@ -597,7 +627,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
597
627
|
slotNumber: provenSlotNumber,
|
|
598
628
|
epochNumber: provenEpochNumber,
|
|
599
629
|
});
|
|
600
|
-
this.instrumentation.
|
|
630
|
+
this.instrumentation.updateLastProvenCheckpoint(localCheckpointForDestinationProvenCheckpointNumber);
|
|
601
631
|
} else {
|
|
602
632
|
this.log.trace(`Proven checkpoint ${provenCheckpointNumber} already stored.`);
|
|
603
633
|
}
|
|
@@ -706,7 +736,6 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
706
736
|
this.blobClient,
|
|
707
737
|
searchStartBlock, // TODO(palla/reorg): If the L2 reorg was due to an L1 reorg, we need to start search earlier
|
|
708
738
|
searchEndBlock,
|
|
709
|
-
this.l1Addresses,
|
|
710
739
|
this.instrumentation,
|
|
711
740
|
this.log,
|
|
712
741
|
!initialSyncComplete, // isHistoricalSync
|
|
@@ -801,6 +830,14 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
801
830
|
);
|
|
802
831
|
}
|
|
803
832
|
|
|
833
|
+
for (const published of validCheckpoints) {
|
|
834
|
+
this.instrumentation.processCheckpointL1Timing({
|
|
835
|
+
slotNumber: published.checkpoint.header.slotNumber,
|
|
836
|
+
l1Timestamp: published.l1.timestamp,
|
|
837
|
+
l1Constants: this.l1Constants,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
|
|
804
841
|
try {
|
|
805
842
|
const updatedValidationResult =
|
|
806
843
|
rollupStatus.validationResult === initialValidationResult ? undefined : rollupStatus.validationResult;
|
|
@@ -819,7 +856,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
819
856
|
const prunedCheckpointNumber = result.prunedBlocks[0].checkpointNumber;
|
|
820
857
|
const prunedSlotNumber = result.prunedBlocks[0].header.globalVariables.slotNumber;
|
|
821
858
|
|
|
822
|
-
this.log.
|
|
859
|
+
this.log.info(
|
|
823
860
|
`Pruned ${result.prunedBlocks.length} mismatching blocks for checkpoint ${prunedCheckpointNumber}`,
|
|
824
861
|
{ prunedBlocks: result.prunedBlocks.map(b => b.toBlockInfo()), prunedSlotNumber, prunedCheckpointNumber },
|
|
825
862
|
);
|