@aztec/archiver 0.0.1-commit.8afd444 → 0.0.1-commit.8c0b8ff
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 -4
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +73 -110
- package/dest/errors.d.ts +7 -9
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +9 -14
- package/dest/factory.d.ts +3 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +31 -24
- 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 +4 -7
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +9 -13
- 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 +10 -5
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +29 -73
- 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 +113 -40
- 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 +5 -8
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +40 -10
- package/dest/store/block_store.d.ts +30 -26
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +180 -83
- 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 +6 -2
- package/dest/store/contract_instance_store.d.ts +1 -1
- package/dest/store/contract_instance_store.d.ts.map +1 -1
- package/dest/store/contract_instance_store.js +6 -2
- package/dest/store/kv_archiver_store.d.ts +37 -15
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +42 -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 +1 -1
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +103 -45
- package/dest/store/message_store.js +1 -1
- package/dest/test/fake_l1_state.d.ts +20 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +97 -20
- 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 +88 -130
- package/src/errors.ts +10 -24
- package/src/factory.ts +45 -21
- 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 +6 -16
- package/src/l1/spire_proposer.ts +7 -15
- package/src/modules/data_source_base.ts +56 -95
- package/src/modules/data_store_updater.ts +123 -43
- package/src/modules/instrumentation.ts +9 -2
- package/src/modules/l1_synchronizer.ts +47 -14
- package/src/store/block_store.ts +219 -110
- package/src/store/contract_class_store.ts +7 -3
- package/src/store/contract_instance_store.ts +8 -5
- package/src/store/kv_archiver_store.ts +66 -20
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +159 -43
- package/src/store/message_store.ts +1 -1
- package/src/test/fake_l1_state.ts +125 -21
- 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,6 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
|
+
import type { CheckpointData } from '@aztec/stdlib/checkpoint';
|
|
3
4
|
import {
|
|
4
5
|
Attributes,
|
|
5
6
|
type Gauge,
|
|
@@ -17,6 +18,7 @@ export class ArchiverInstrumentation {
|
|
|
17
18
|
public readonly tracer: Tracer;
|
|
18
19
|
|
|
19
20
|
private blockHeight: Gauge;
|
|
21
|
+
private checkpointHeight: Gauge;
|
|
20
22
|
private txCount: UpDownCounter;
|
|
21
23
|
private l1BlockHeight: Gauge;
|
|
22
24
|
private proofsSubmittedDelay: Histogram;
|
|
@@ -47,6 +49,8 @@ export class ArchiverInstrumentation {
|
|
|
47
49
|
|
|
48
50
|
this.blockHeight = meter.createGauge(Metrics.ARCHIVER_BLOCK_HEIGHT);
|
|
49
51
|
|
|
52
|
+
this.checkpointHeight = meter.createGauge(Metrics.ARCHIVER_CHECKPOINT_HEIGHT);
|
|
53
|
+
|
|
50
54
|
this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT);
|
|
51
55
|
|
|
52
56
|
this.txCount = createUpDownCounterWithDefault(meter, Metrics.ARCHIVER_TOTAL_TXS);
|
|
@@ -105,6 +109,7 @@ export class ArchiverInstrumentation {
|
|
|
105
109
|
public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
|
|
106
110
|
this.syncDurationPerBlock.record(Math.ceil(syncTimePerBlock));
|
|
107
111
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
112
|
+
this.checkpointHeight.record(Math.max(...blocks.map(b => b.checkpointNumber)));
|
|
108
113
|
this.syncBlockCount.add(blocks.length);
|
|
109
114
|
|
|
110
115
|
for (const block of blocks) {
|
|
@@ -127,8 +132,10 @@ export class ArchiverInstrumentation {
|
|
|
127
132
|
this.pruneDuration.record(Math.ceil(duration));
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
public
|
|
131
|
-
|
|
135
|
+
public updateLastProvenCheckpoint(checkpoint: CheckpointData) {
|
|
136
|
+
const lastBlockNumberInCheckpoint = checkpoint.startBlock + checkpoint.blockCount - 1;
|
|
137
|
+
this.blockHeight.record(lastBlockNumberInCheckpoint, { [Attributes.STATUS]: 'proven' });
|
|
138
|
+
this.checkpointHeight.record(checkpoint.checkpointNumber, { [Attributes.STATUS]: 'proven' });
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
public processProofsVerified(logs: { proverId: string; l2BlockNumber: bigint; delay: bigint }[]) {
|
|
@@ -1,7 +1,6 @@
|
|
|
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';
|
|
7
6
|
import { maxBigint } from '@aztec/foundation/bigint';
|
|
@@ -9,7 +8,6 @@ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/br
|
|
|
9
8
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
10
9
|
import { pick } from '@aztec/foundation/collection';
|
|
11
10
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
13
11
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
14
12
|
import { count } from '@aztec/foundation/string';
|
|
15
13
|
import { DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
|
|
@@ -28,6 +26,7 @@ import {
|
|
|
28
26
|
retrievedToPublishedCheckpoint,
|
|
29
27
|
} from '../l1/data_retrieval.js';
|
|
30
28
|
import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
|
|
29
|
+
import type { L2TipsCache } from '../store/l2_tips_cache.js';
|
|
31
30
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
32
31
|
import { ArchiverDataStoreUpdater } from './data_store_updater.js';
|
|
33
32
|
import type { ArchiverInstrumentation } from './instrumentation.js';
|
|
@@ -60,10 +59,6 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
60
59
|
private readonly debugClient: ViemPublicDebugClient,
|
|
61
60
|
private readonly rollup: RollupContract,
|
|
62
61
|
private readonly inbox: InboxContract,
|
|
63
|
-
private readonly l1Addresses: Pick<
|
|
64
|
-
L1ContractAddresses,
|
|
65
|
-
'registryAddress' | 'governanceProposerAddress' | 'slashFactoryAddress'
|
|
66
|
-
> & { slashingProposerAddress: EthAddress },
|
|
67
62
|
private readonly store: KVArchiverDataStore,
|
|
68
63
|
private config: {
|
|
69
64
|
batchSize: number;
|
|
@@ -74,12 +69,18 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
74
69
|
private readonly epochCache: EpochCache,
|
|
75
70
|
private readonly dateProvider: DateProvider,
|
|
76
71
|
private readonly instrumentation: ArchiverInstrumentation,
|
|
77
|
-
private readonly l1Constants: L1RollupConstants & {
|
|
72
|
+
private readonly l1Constants: L1RollupConstants & {
|
|
73
|
+
l1StartBlockHash: Buffer32;
|
|
74
|
+
genesisArchiveRoot: Fr;
|
|
75
|
+
},
|
|
78
76
|
private readonly events: ArchiverEmitter,
|
|
79
77
|
tracer: Tracer,
|
|
78
|
+
l2TipsCache?: L2TipsCache,
|
|
80
79
|
private readonly log: Logger = createLogger('archiver:l1-sync'),
|
|
81
80
|
) {
|
|
82
|
-
this.updater = new ArchiverDataStoreUpdater(this.store
|
|
81
|
+
this.updater = new ArchiverDataStoreUpdater(this.store, l2TipsCache, {
|
|
82
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
83
|
+
});
|
|
83
84
|
this.tracer = tracer;
|
|
84
85
|
}
|
|
85
86
|
|
|
@@ -215,6 +216,9 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
215
216
|
this.instrumentation.updateL1BlockHeight(currentL1BlockNumber);
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
// Update the finalized L2 checkpoint based on L1 finality.
|
|
220
|
+
await this.updateFinalizedCheckpoint();
|
|
221
|
+
|
|
218
222
|
// After syncing has completed, update the current l1 block number and timestamp,
|
|
219
223
|
// otherwise we risk announcing to the world that we've synced to a given point,
|
|
220
224
|
// but the corresponding blocks have not been processed (see #12631).
|
|
@@ -230,6 +234,36 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
230
234
|
});
|
|
231
235
|
}
|
|
232
236
|
|
|
237
|
+
/** Query L1 for its finalized block and update the finalized checkpoint accordingly. */
|
|
238
|
+
private async updateFinalizedCheckpoint(): Promise<void> {
|
|
239
|
+
try {
|
|
240
|
+
const finalizedL1Block = await this.publicClient.getBlock({ blockTag: 'finalized', includeTransactions: false });
|
|
241
|
+
const finalizedL1BlockNumber = finalizedL1Block.number;
|
|
242
|
+
const finalizedCheckpointNumber = await this.rollup.getProvenCheckpointNumber({
|
|
243
|
+
blockNumber: finalizedL1BlockNumber,
|
|
244
|
+
});
|
|
245
|
+
const localFinalizedCheckpointNumber = await this.store.getFinalizedCheckpointNumber();
|
|
246
|
+
if (localFinalizedCheckpointNumber !== finalizedCheckpointNumber) {
|
|
247
|
+
await this.updater.setFinalizedCheckpointNumber(finalizedCheckpointNumber);
|
|
248
|
+
const finalizedL2BlockNumber = await this.store.getFinalizedL2BlockNumber();
|
|
249
|
+
this.log.info(
|
|
250
|
+
`Updated finalized chain to checkpoint ${finalizedCheckpointNumber} (L2 block ${finalizedL2BlockNumber})`,
|
|
251
|
+
{
|
|
252
|
+
finalizedCheckpointNumber,
|
|
253
|
+
previousFinalizedCheckpointNumber: localFinalizedCheckpointNumber,
|
|
254
|
+
finalizedL2BlockNumber,
|
|
255
|
+
finalizedL1BlockNumber,
|
|
256
|
+
},
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
} catch (err: any) {
|
|
260
|
+
// The rollup contract may not exist at the finalized L1 block right after deployment.
|
|
261
|
+
if (!err?.message?.includes('returned no data')) {
|
|
262
|
+
this.log.warn(`Failed to update finalized checkpoint: ${err}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
233
267
|
/** Prune all proposed local blocks that should have been checkpointed by now. */
|
|
234
268
|
private async pruneUncheckpointedBlocks(currentL1Timestamp: bigint) {
|
|
235
269
|
const [lastCheckpointedBlockNumber, lastProposedBlockNumber] = await Promise.all([
|
|
@@ -550,7 +584,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
550
584
|
if (provenCheckpointNumber === 0) {
|
|
551
585
|
const localProvenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
552
586
|
if (localProvenCheckpointNumber !== provenCheckpointNumber) {
|
|
553
|
-
await this.
|
|
587
|
+
await this.updater.setProvenCheckpointNumber(provenCheckpointNumber);
|
|
554
588
|
this.log.info(`Rolled back proven chain to checkpoint ${provenCheckpointNumber}`, { provenCheckpointNumber });
|
|
555
589
|
}
|
|
556
590
|
}
|
|
@@ -582,13 +616,13 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
582
616
|
) {
|
|
583
617
|
const localProvenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
584
618
|
if (localProvenCheckpointNumber !== provenCheckpointNumber) {
|
|
585
|
-
await this.
|
|
619
|
+
await this.updater.setProvenCheckpointNumber(provenCheckpointNumber);
|
|
586
620
|
this.log.info(`Updated proven chain to checkpoint ${provenCheckpointNumber}`, { provenCheckpointNumber });
|
|
587
621
|
const provenSlotNumber = localCheckpointForDestinationProvenCheckpointNumber.header.slotNumber;
|
|
588
622
|
const provenEpochNumber: EpochNumber = getEpochAtSlot(provenSlotNumber, this.l1Constants);
|
|
589
623
|
const lastBlockNumberInCheckpoint =
|
|
590
624
|
localCheckpointForDestinationProvenCheckpointNumber.startBlock +
|
|
591
|
-
localCheckpointForDestinationProvenCheckpointNumber.
|
|
625
|
+
localCheckpointForDestinationProvenCheckpointNumber.blockCount -
|
|
592
626
|
1;
|
|
593
627
|
|
|
594
628
|
this.events.emit(L2BlockSourceEvents.L2BlockProven, {
|
|
@@ -597,7 +631,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
597
631
|
slotNumber: provenSlotNumber,
|
|
598
632
|
epochNumber: provenEpochNumber,
|
|
599
633
|
});
|
|
600
|
-
this.instrumentation.
|
|
634
|
+
this.instrumentation.updateLastProvenCheckpoint(localCheckpointForDestinationProvenCheckpointNumber);
|
|
601
635
|
} else {
|
|
602
636
|
this.log.trace(`Proven checkpoint ${provenCheckpointNumber} already stored.`);
|
|
603
637
|
}
|
|
@@ -706,7 +740,6 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
706
740
|
this.blobClient,
|
|
707
741
|
searchStartBlock, // TODO(palla/reorg): If the L2 reorg was due to an L1 reorg, we need to start search earlier
|
|
708
742
|
searchEndBlock,
|
|
709
|
-
this.l1Addresses,
|
|
710
743
|
this.instrumentation,
|
|
711
744
|
this.log,
|
|
712
745
|
!initialSyncComplete, // isHistoricalSync
|
|
@@ -819,7 +852,7 @@ export class ArchiverL1Synchronizer implements Traceable {
|
|
|
819
852
|
const prunedCheckpointNumber = result.prunedBlocks[0].checkpointNumber;
|
|
820
853
|
const prunedSlotNumber = result.prunedBlocks[0].header.globalVariables.slotNumber;
|
|
821
854
|
|
|
822
|
-
this.log.
|
|
855
|
+
this.log.info(
|
|
823
856
|
`Pruned ${result.prunedBlocks.length} mismatching blocks for checkpoint ${prunedCheckpointNumber}`,
|
|
824
857
|
{ prunedBlocks: result.prunedBlocks.map(b => b.toBlockInfo()), prunedSlotNumber, prunedCheckpointNumber },
|
|
825
858
|
);
|