@aztec/archiver 0.0.1-commit.1bea0213 → 0.0.1-commit.1de2a32
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 +9 -3
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +40 -98
- package/dest/factory.d.ts +4 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +14 -11
- 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 +22 -20
- 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/l1/validate_trace.d.ts +6 -3
- package/dest/l1/validate_trace.d.ts.map +1 -1
- package/dest/l1/validate_trace.js +13 -9
- 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 +13 -3
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +48 -19
- package/dest/modules/instrumentation.d.ts +15 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +36 -12
- 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 +18 -12
- 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/store/message_store.js +1 -1
- package/dest/test/fake_l1_state.d.ts +6 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +56 -18
- package/dest/test/index.js +3 -1
- 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 +22 -6
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +130 -84
- package/dest/test/mock_structs.d.ts +6 -2
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +20 -6
- package/dest/test/noop_l1_archiver.d.ts +23 -0
- package/dest/test/noop_l1_archiver.d.ts.map +1 -0
- package/dest/test/noop_l1_archiver.js +68 -0
- package/package.json +14 -13
- package/src/archiver.ts +61 -118
- package/src/factory.ts +30 -13
- 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 +24 -26
- package/src/l1/spire_proposer.ts +7 -15
- package/src/l1/validate_trace.ts +24 -6
- package/src/modules/data_source_base.ts +56 -95
- package/src/modules/data_store_updater.ts +49 -19
- package/src/modules/instrumentation.ts +44 -12
- package/src/modules/l1_synchronizer.ts +24 -16
- 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/store/message_store.ts +1 -1
- package/src/test/fake_l1_state.ts +75 -17
- package/src/test/index.ts +3 -0
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +169 -83
- package/src/test/mock_structs.ts +42 -12
- package/src/test/noop_l1_archiver.ts +109 -0
|
@@ -3,15 +3,17 @@ import { Buffer16 } from '@aztec/foundation/buffer';
|
|
|
3
3
|
import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
+
import { L2Block } from '@aztec/stdlib/block';
|
|
6
7
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
7
8
|
import { PrivateLog, PublicLog, SiloedTag, Tag } from '@aztec/stdlib/logs';
|
|
8
9
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
9
10
|
import { StateReference } from '@aztec/stdlib/tx';
|
|
10
11
|
import { type InboxMessage } from '../structs/inbox_message.js';
|
|
11
12
|
export declare function makeInboxMessage(previousRollingHash?: Buffer16, overrides?: Partial<InboxMessage>): InboxMessage;
|
|
12
|
-
export declare function makeInboxMessages(
|
|
13
|
+
export declare function makeInboxMessages(totalCount: number, opts?: {
|
|
13
14
|
initialHash?: Buffer16;
|
|
14
15
|
initialCheckpointNumber?: CheckpointNumber;
|
|
16
|
+
messagesPerCheckpoint?: number;
|
|
15
17
|
overrideFn?: (msg: InboxMessage, index: number) => InboxMessage;
|
|
16
18
|
}): InboxMessage[];
|
|
17
19
|
/** Creates inbox messages distributed across multiple blocks with proper checkpoint numbering. */
|
|
@@ -27,6 +29,8 @@ export declare function makeBlockHash(blockNumber: number): `0x${string}`;
|
|
|
27
29
|
export declare function makeStateForBlock(blockNumber: number, txsPerBlock: number): StateReference;
|
|
28
30
|
/** Creates L1PublishedData with deterministic values based on l1BlockNumber. */
|
|
29
31
|
export declare function makeL1PublishedData(l1BlockNumber: number): L1PublishedData;
|
|
32
|
+
/** Creates a Checkpoint from a list of blocks with a header that matches the blocks' structure. */
|
|
33
|
+
export declare function makeCheckpoint(blocks: L2Block[], checkpointNumber?: CheckpointNumber): Checkpoint;
|
|
30
34
|
/** Wraps a Checkpoint with L1 published data and random attestations. */
|
|
31
35
|
export declare function makePublishedCheckpoint(checkpoint: Checkpoint, l1BlockNumber: number, attestationCount?: number): PublishedCheckpoint;
|
|
32
36
|
export interface MakeChainedCheckpointsOptions {
|
|
@@ -81,4 +85,4 @@ export interface MockCheckpointWithLogsOptions {
|
|
|
81
85
|
}
|
|
82
86
|
/** Creates a checkpoint with specified logs on each tx effect. */
|
|
83
87
|
export declare function makeCheckpointWithLogs(blockNumber: number, options?: MockCheckpointWithLogsOptions): Promise<PublishedCheckpoint>;
|
|
84
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9ja19zdHJ1Y3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9tb2NrX3N0cnVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFlLGdCQUFnQixFQUF5QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxRQUFRLEVBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUc5RCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVqRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBd0IsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFLM0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0QsT0FBTyxFQUF5QixjQUFjLEVBQVksTUFBTSxrQkFBa0IsQ0FBQztBQUVuRixPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQXFCLE1BQU0sNkJBQTZCLENBQUM7QUFFbkYsd0JBQWdCLGdCQUFnQixDQUM5QixtQkFBbUIsV0FBZ0IsRUFDbkMsU0FBUyxHQUFFLE9BQU8sQ0FBQyxZQUFZLENBQU0sR0FDcEMsWUFBWSxDQWdCZDtBQUVELHdCQUFnQixpQkFBaUIsQ0FDL0IsVUFBVSxFQUFFLE1BQU0sRUFDbEIsSUFBSSxHQUFFO0lBQ0osV0FBVyxDQUFDLEVBQUUsUUFBUSxDQUFDO0lBQ3ZCLHVCQUF1QixDQUFDLEVBQUUsZ0JBQWdCLENBQUM7SUFDM0MscUJBQXFCLENBQUMsRUFB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"AAMA,OAAO,EAAe,gBAAgB,EAAyB,MAAM,iCAAiC,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"mock_structs.d.ts","sourceRoot":"","sources":["../../src/test/mock_structs.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,16 +32,18 @@ export function makeInboxMessage(previousRollingHash = Buffer16.ZERO, overrides
|
|
|
32
32
|
rollingHash
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
export function makeInboxMessages(
|
|
36
|
-
const { initialHash = Buffer16.ZERO, overrideFn = (msg)=>msg, initialCheckpointNumber = 1 } = opts;
|
|
35
|
+
export function makeInboxMessages(totalCount, opts = {}) {
|
|
36
|
+
const { initialHash = Buffer16.ZERO, overrideFn = (msg)=>msg, initialCheckpointNumber = CheckpointNumber(1), messagesPerCheckpoint = 1 } = opts;
|
|
37
37
|
const messages = [];
|
|
38
38
|
let rollingHash = initialHash;
|
|
39
|
-
for(let i = 0; i <
|
|
39
|
+
for(let i = 0; i < totalCount; i++){
|
|
40
|
+
const msgIndex = i % messagesPerCheckpoint;
|
|
41
|
+
const checkpointNumber = CheckpointNumber.fromBigInt(BigInt(initialCheckpointNumber) + BigInt(i) / BigInt(messagesPerCheckpoint));
|
|
40
42
|
const leaf = Fr.random();
|
|
41
|
-
const checkpointNumber = CheckpointNumber(i + initialCheckpointNumber);
|
|
42
43
|
const message = overrideFn(makeInboxMessage(rollingHash, {
|
|
43
44
|
leaf,
|
|
44
|
-
checkpointNumber
|
|
45
|
+
checkpointNumber,
|
|
46
|
+
index: InboxLeaf.smallestIndexForCheckpoint(checkpointNumber) + BigInt(msgIndex)
|
|
45
47
|
}), i);
|
|
46
48
|
rollingHash = message.rollingHash;
|
|
47
49
|
messages.push(message);
|
|
@@ -75,6 +77,18 @@ export function makeInboxMessages(count, opts = {}) {
|
|
|
75
77
|
/** Creates L1PublishedData with deterministic values based on l1BlockNumber. */ export function makeL1PublishedData(l1BlockNumber) {
|
|
76
78
|
return new L1PublishedData(BigInt(l1BlockNumber), BigInt(l1BlockNumber * 1000), makeBlockHash(l1BlockNumber));
|
|
77
79
|
}
|
|
80
|
+
/** Creates a Checkpoint from a list of blocks with a header that matches the blocks' structure. */ export function makeCheckpoint(blocks, checkpointNumber = CheckpointNumber(1)) {
|
|
81
|
+
const firstBlock = blocks[0];
|
|
82
|
+
const { slotNumber, timestamp, coinbase, feeRecipient, gasFees } = firstBlock.header.globalVariables;
|
|
83
|
+
return new Checkpoint(blocks.at(-1).archive, CheckpointHeader.random({
|
|
84
|
+
lastArchiveRoot: firstBlock.header.lastArchive.root,
|
|
85
|
+
slotNumber,
|
|
86
|
+
timestamp,
|
|
87
|
+
coinbase,
|
|
88
|
+
feeRecipient,
|
|
89
|
+
gasFees
|
|
90
|
+
}), blocks, checkpointNumber);
|
|
91
|
+
}
|
|
78
92
|
/** Wraps a Checkpoint with L1 published data and random attestations. */ export function makePublishedCheckpoint(checkpoint, l1BlockNumber, attestationCount = 3) {
|
|
79
93
|
return new PublishedCheckpoint(checkpoint, makeL1PublishedData(l1BlockNumber), times(attestationCount, CommitteeAttestation.random));
|
|
80
94
|
}
|
|
@@ -162,7 +176,7 @@ export function makeInboxMessages(count, opts = {}) {
|
|
|
162
176
|
txEffect.publicLogs = publicLogs ? makePublicLogs(blockNumber, txIndex, publicLogs.numLogsPerTx, publicLogs.contractAddress) : [];
|
|
163
177
|
return txEffect;
|
|
164
178
|
});
|
|
165
|
-
const checkpoint =
|
|
179
|
+
const checkpoint = makeCheckpoint([
|
|
166
180
|
block
|
|
167
181
|
], CheckpointNumber.fromBlockNumber(BlockNumber(blockNumber)));
|
|
168
182
|
return makePublishedCheckpoint(checkpoint, blockNumber);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
3
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
|
+
import { Archiver } from '../archiver.js';
|
|
5
|
+
import { ArchiverInstrumentation } from '../modules/instrumentation.js';
|
|
6
|
+
import type { KVArchiverDataStore } from '../store/kv_archiver_store.js';
|
|
7
|
+
/**
|
|
8
|
+
* Archiver with mocked L1 connectivity for testing.
|
|
9
|
+
* Uses mock L1 clients and a noop synchronizer, enabling tests that
|
|
10
|
+
* don't require real Ethereum connectivity.
|
|
11
|
+
*/
|
|
12
|
+
export declare class NoopL1Archiver extends Archiver {
|
|
13
|
+
constructor(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
|
|
14
|
+
genesisArchiveRoot: Fr;
|
|
15
|
+
}, instrumentation: ArchiverInstrumentation);
|
|
16
|
+
/** Override start to skip L1 validation checks. */
|
|
17
|
+
start(_blockUntilSynced?: boolean): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Creates an archiver with mocked L1 connectivity for testing. */
|
|
20
|
+
export declare function createNoopL1Archiver(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
|
|
21
|
+
genesisArchiveRoot: Fr;
|
|
22
|
+
}, telemetry?: TelemetryClient): Promise<NoopL1Archiver>;
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFJcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQW1DLE1BQU0seUJBQXlCLENBQUM7QUFLaEcsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRXhFLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUF5QnpFOzs7O0dBSUc7QUFDSCxxQkFBYSxjQUFlLFNBQVEsUUFBUTtJQUMxQyxZQUNFLFNBQVMsRUFBRSxtQkFBbUIsRUFDOUIsV0FBVyxFQUFFLGlCQUFpQixHQUFHO1FBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFBO0tBQUUsRUFDM0QsZUFBZSxFQUFFLHVCQUF1QixFQXVDekM7SUFFRCxtREFBbUQ7SUFDbkMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FJaEU7Q0FDRjtBQUVELG1FQUFtRTtBQUNuRSx3QkFBc0Isb0JBQW9CLENBQ3hDLFNBQVMsRUFBRSxtQkFBbUIsRUFDOUIsV0FBVyxFQUFFLGlCQUFpQixHQUFHO0lBQUUsa0JBQWtCLEVBQUUsRUFBRSxDQUFBO0NBQUUsRUFDM0QsU0FBUyxHQUFFLGVBQXNDLEdBQ2hELE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FHekIifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop_l1_archiver.d.ts","sourceRoot":"","sources":["../../src/test/noop_l1_archiver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,KAAK,eAAe,EAAmC,MAAM,yBAAyB,CAAC;AAKhG,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAyBzE;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,YACE,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;QAAE,kBAAkB,EAAE,EAAE,CAAA;KAAE,EAC3D,eAAe,EAAE,uBAAuB,EAuCzC;IAED,mDAAmD;IACnC,KAAK,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;CACF;AAED,mEAAmE;AACnE,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,iBAAiB,GAAG;IAAE,kBAAkB,EAAE,EAAE,CAAA;CAAE,EAC3D,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,cAAc,CAAC,CAGzB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
4
|
+
import { mock } from 'jest-mock-extended';
|
|
5
|
+
import { EventEmitter } from 'node:events';
|
|
6
|
+
import { Archiver } from '../archiver.js';
|
|
7
|
+
import { ArchiverInstrumentation } from '../modules/instrumentation.js';
|
|
8
|
+
/** Noop L1 synchronizer for testing without L1 connectivity. */ class NoopL1Synchronizer {
|
|
9
|
+
tracer;
|
|
10
|
+
constructor(tracer){
|
|
11
|
+
this.tracer = tracer;
|
|
12
|
+
}
|
|
13
|
+
setConfig(_config) {}
|
|
14
|
+
getL1BlockNumber() {
|
|
15
|
+
return 0n;
|
|
16
|
+
}
|
|
17
|
+
getL1Timestamp() {
|
|
18
|
+
return 0n;
|
|
19
|
+
}
|
|
20
|
+
testEthereumNodeSynced() {
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
syncFromL1(_initialSyncComplete) {
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Archiver with mocked L1 connectivity for testing.
|
|
29
|
+
* Uses mock L1 clients and a noop synchronizer, enabling tests that
|
|
30
|
+
* don't require real Ethereum connectivity.
|
|
31
|
+
*/ export class NoopL1Archiver extends Archiver {
|
|
32
|
+
constructor(dataStore, l1Constants, instrumentation){
|
|
33
|
+
// Create mocks for L1 clients
|
|
34
|
+
const publicClient = mock();
|
|
35
|
+
const debugClient = mock();
|
|
36
|
+
const rollup = mock();
|
|
37
|
+
const blobClient = mock();
|
|
38
|
+
// Mock methods called during start()
|
|
39
|
+
blobClient.testSources.mockResolvedValue();
|
|
40
|
+
publicClient.getBlockNumber.mockResolvedValue(1n);
|
|
41
|
+
const events = new EventEmitter();
|
|
42
|
+
const synchronizer = new NoopL1Synchronizer(instrumentation.tracer);
|
|
43
|
+
super(publicClient, debugClient, rollup, {
|
|
44
|
+
registryAddress: EthAddress.ZERO,
|
|
45
|
+
governanceProposerAddress: EthAddress.ZERO,
|
|
46
|
+
slashFactoryAddress: EthAddress.ZERO,
|
|
47
|
+
slashingProposerAddress: EthAddress.ZERO
|
|
48
|
+
}, dataStore, {
|
|
49
|
+
pollingIntervalMs: 1000,
|
|
50
|
+
batchSize: 100,
|
|
51
|
+
skipValidateCheckpointAttestations: true,
|
|
52
|
+
maxAllowedEthClientDriftSeconds: 300,
|
|
53
|
+
ethereumAllowNoDebugHosts: true
|
|
54
|
+
}, blobClient, instrumentation, {
|
|
55
|
+
...l1Constants,
|
|
56
|
+
l1StartBlockHash: Buffer32.random()
|
|
57
|
+
}, synchronizer, events);
|
|
58
|
+
}
|
|
59
|
+
/** Override start to skip L1 validation checks. */ start(_blockUntilSynced) {
|
|
60
|
+
// Just start the running promise without L1 checks
|
|
61
|
+
this.runningPromise.start();
|
|
62
|
+
return Promise.resolve();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Creates an archiver with mocked L1 connectivity for testing. */ export async function createNoopL1Archiver(dataStore, l1Constants, telemetry = getTelemetryClient()) {
|
|
66
|
+
const instrumentation = await ArchiverInstrumentation.new(telemetry, ()=>dataStore.estimateSize());
|
|
67
|
+
return new NoopL1Archiver(dataStore, l1Constants, instrumentation);
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.1de2a32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
7
7
|
"./test": "./dest/test/index.js",
|
|
8
|
+
"./test/noop-l1": "./dest/test/noop_l1_archiver.js",
|
|
8
9
|
"./config": "./dest/config.js"
|
|
9
10
|
},
|
|
10
11
|
"typedocOptions": {
|
|
@@ -64,18 +65,18 @@
|
|
|
64
65
|
]
|
|
65
66
|
},
|
|
66
67
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
68
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
69
|
-
"@aztec/constants": "0.0.1-commit.
|
|
70
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
71
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
72
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
73
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
74
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
75
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
76
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
77
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
78
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
68
|
+
"@aztec/blob-client": "0.0.1-commit.1de2a32",
|
|
69
|
+
"@aztec/blob-lib": "0.0.1-commit.1de2a32",
|
|
70
|
+
"@aztec/constants": "0.0.1-commit.1de2a32",
|
|
71
|
+
"@aztec/epoch-cache": "0.0.1-commit.1de2a32",
|
|
72
|
+
"@aztec/ethereum": "0.0.1-commit.1de2a32",
|
|
73
|
+
"@aztec/foundation": "0.0.1-commit.1de2a32",
|
|
74
|
+
"@aztec/kv-store": "0.0.1-commit.1de2a32",
|
|
75
|
+
"@aztec/l1-artifacts": "0.0.1-commit.1de2a32",
|
|
76
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.1de2a32",
|
|
77
|
+
"@aztec/protocol-contracts": "0.0.1-commit.1de2a32",
|
|
78
|
+
"@aztec/stdlib": "0.0.1-commit.1de2a32",
|
|
79
|
+
"@aztec/telemetry-client": "0.0.1-commit.1de2a32",
|
|
79
80
|
"lodash.groupby": "^4.6.0",
|
|
80
81
|
"lodash.omit": "^4.5.0",
|
|
81
82
|
"tslib": "^2.5.0",
|
package/src/archiver.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
2
|
-
import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
3
2
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
4
3
|
import { BlockTagTooOldError, RollupContract } from '@aztec/ethereum/contracts';
|
|
5
4
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
@@ -15,8 +14,6 @@ import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/runni
|
|
|
15
14
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
16
15
|
import {
|
|
17
16
|
type ArchiverEmitter,
|
|
18
|
-
type CheckpointId,
|
|
19
|
-
GENESIS_CHECKPOINT_HEADER_HASH,
|
|
20
17
|
L2Block,
|
|
21
18
|
type L2BlockSink,
|
|
22
19
|
type L2Tips,
|
|
@@ -26,6 +23,7 @@ import { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
|
26
23
|
import {
|
|
27
24
|
type L1RollupConstants,
|
|
28
25
|
getEpochNumberAtTimestamp,
|
|
26
|
+
getSlotAtNextL1Block,
|
|
29
27
|
getSlotAtTimestamp,
|
|
30
28
|
getSlotRangeForEpoch,
|
|
31
29
|
getTimestampRangeForEpoch,
|
|
@@ -40,6 +38,7 @@ import { ArchiverDataStoreUpdater } from './modules/data_store_updater.js';
|
|
|
40
38
|
import type { ArchiverInstrumentation } from './modules/instrumentation.js';
|
|
41
39
|
import type { ArchiverL1Synchronizer } from './modules/l1_synchronizer.js';
|
|
42
40
|
import type { KVArchiverDataStore } from './store/kv_archiver_store.js';
|
|
41
|
+
import { L2TipsCache } from './store/l2_tips_cache.js';
|
|
43
42
|
|
|
44
43
|
/** Export ArchiverEmitter for use in factory and tests. */
|
|
45
44
|
export type { ArchiverEmitter };
|
|
@@ -68,7 +67,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
68
67
|
public readonly events: ArchiverEmitter;
|
|
69
68
|
|
|
70
69
|
/** A loop in which we will be continually fetching new checkpoints. */
|
|
71
|
-
|
|
70
|
+
protected runningPromise: RunningPromise;
|
|
72
71
|
|
|
73
72
|
/** L1 synchronizer that handles fetching checkpoints and messages from L1. */
|
|
74
73
|
private readonly synchronizer: ArchiverL1Synchronizer;
|
|
@@ -82,6 +81,9 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
82
81
|
/** Helper to handle updates to the store */
|
|
83
82
|
private readonly updater: ArchiverDataStoreUpdater;
|
|
84
83
|
|
|
84
|
+
/** In-memory cache for L2 chain tips. */
|
|
85
|
+
private readonly l2TipsCache: L2TipsCache;
|
|
86
|
+
|
|
85
87
|
public readonly tracer: Tracer;
|
|
86
88
|
|
|
87
89
|
/**
|
|
@@ -118,9 +120,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
118
120
|
},
|
|
119
121
|
private readonly blobClient: BlobClientInterface,
|
|
120
122
|
instrumentation: ArchiverInstrumentation,
|
|
121
|
-
protected override readonly l1Constants: L1RollupConstants & {
|
|
123
|
+
protected override readonly l1Constants: L1RollupConstants & {
|
|
124
|
+
l1StartBlockHash: Buffer32;
|
|
125
|
+
genesisArchiveRoot: Fr;
|
|
126
|
+
rollupManaLimit?: number;
|
|
127
|
+
},
|
|
122
128
|
synchronizer: ArchiverL1Synchronizer,
|
|
123
129
|
events: ArchiverEmitter,
|
|
130
|
+
l2TipsCache?: L2TipsCache,
|
|
124
131
|
private readonly log: Logger = createLogger('archiver'),
|
|
125
132
|
) {
|
|
126
133
|
super(dataStore, l1Constants);
|
|
@@ -129,7 +136,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
129
136
|
this.initialSyncPromise = promiseWithResolvers();
|
|
130
137
|
this.synchronizer = synchronizer;
|
|
131
138
|
this.events = events;
|
|
132
|
-
this.
|
|
139
|
+
this.l2TipsCache = l2TipsCache ?? new L2TipsCache(this.dataStore.blockStore);
|
|
140
|
+
this.updater = new ArchiverDataStoreUpdater(this.dataStore, this.l2TipsCache, {
|
|
141
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
142
|
+
});
|
|
133
143
|
|
|
134
144
|
// Running promise starts with a small interval inbetween runs, so all iterations needed for the initial sync
|
|
135
145
|
// are done as fast as possible. This then gets updated once the initial sync completes.
|
|
@@ -158,7 +168,11 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
158
168
|
|
|
159
169
|
await this.blobClient.testSources();
|
|
160
170
|
await this.synchronizer.testEthereumNodeSynced();
|
|
161
|
-
await validateAndLogTraceAvailability(
|
|
171
|
+
await validateAndLogTraceAvailability(
|
|
172
|
+
this.debugClient,
|
|
173
|
+
this.config.ethereumAllowNoDebugHosts ?? false,
|
|
174
|
+
this.log.getBindings(),
|
|
175
|
+
);
|
|
162
176
|
|
|
163
177
|
// Log initial state for the archiver
|
|
164
178
|
const { l1StartBlock } = this.l1Constants;
|
|
@@ -212,8 +226,23 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
212
226
|
const queuedItems = this.blockQueue.splice(0, this.blockQueue.length);
|
|
213
227
|
this.log.debug(`Processing ${queuedItems.length} queued block(s)`);
|
|
214
228
|
|
|
229
|
+
// Calculate slot threshold for validation
|
|
230
|
+
const l1Timestamp = this.synchronizer.getL1Timestamp();
|
|
231
|
+
const slotAtNextL1Block =
|
|
232
|
+
l1Timestamp === undefined ? undefined : getSlotAtNextL1Block(l1Timestamp, this.l1Constants);
|
|
233
|
+
|
|
215
234
|
// Process each block individually to properly resolve/reject each promise
|
|
216
235
|
for (const { block, resolve, reject } of queuedItems) {
|
|
236
|
+
const blockSlot = block.header.globalVariables.slotNumber;
|
|
237
|
+
if (slotAtNextL1Block !== undefined && blockSlot < slotAtNextL1Block) {
|
|
238
|
+
this.log.warn(
|
|
239
|
+
`Rejecting proposed block ${block.number} for past slot ${blockSlot} (current is ${slotAtNextL1Block})`,
|
|
240
|
+
{ block: block.toBlockInfo(), l1Timestamp, slotAtNextL1Block },
|
|
241
|
+
);
|
|
242
|
+
reject(new Error(`Block ${block.number} is for past slot ${blockSlot} (current is ${slotAtNextL1Block})`));
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
217
246
|
try {
|
|
218
247
|
await this.updater.addProposedBlocks([block]);
|
|
219
248
|
this.log.debug(`Added block ${block.number} to store`);
|
|
@@ -371,115 +400,11 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
371
400
|
return true;
|
|
372
401
|
}
|
|
373
402
|
|
|
374
|
-
public
|
|
375
|
-
|
|
376
|
-
this.getBlockNumber(),
|
|
377
|
-
this.getProvenBlockNumber(),
|
|
378
|
-
this.getCheckpointedL2BlockNumber(),
|
|
379
|
-
this.getFinalizedL2BlockNumber(),
|
|
380
|
-
] as const);
|
|
381
|
-
|
|
382
|
-
const beforeInitialblockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
383
|
-
|
|
384
|
-
// Get the latest block header and checkpointed blocks for proven, finalised and checkpointed blocks
|
|
385
|
-
const [latestBlockHeader, provenCheckpointedBlock, finalizedCheckpointedBlock, checkpointedBlock] =
|
|
386
|
-
await Promise.all([
|
|
387
|
-
latestBlockNumber > beforeInitialblockNumber ? this.getBlockHeader(latestBlockNumber) : undefined,
|
|
388
|
-
provenBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(provenBlockNumber) : undefined,
|
|
389
|
-
finalizedBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(finalizedBlockNumber) : undefined,
|
|
390
|
-
checkpointedBlockNumber > beforeInitialblockNumber
|
|
391
|
-
? this.getCheckpointedBlock(checkpointedBlockNumber)
|
|
392
|
-
: undefined,
|
|
393
|
-
] as const);
|
|
394
|
-
|
|
395
|
-
if (latestBlockNumber > beforeInitialblockNumber && !latestBlockHeader) {
|
|
396
|
-
throw new Error(`Failed to retrieve latest block header for block ${latestBlockNumber}`);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Checkpointed blocks must exist for proven, finalized and checkpointed tips if they are beyond the initial block number.
|
|
400
|
-
if (checkpointedBlockNumber > beforeInitialblockNumber && !checkpointedBlock?.block.header) {
|
|
401
|
-
throw new Error(
|
|
402
|
-
`Failed to retrieve checkpointed block header for block ${checkpointedBlockNumber} (latest block is ${latestBlockNumber})`,
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
if (provenBlockNumber > beforeInitialblockNumber && !provenCheckpointedBlock?.block.header) {
|
|
407
|
-
throw new Error(
|
|
408
|
-
`Failed to retrieve proven checkpointed for block ${provenBlockNumber} (latest block is ${latestBlockNumber})`,
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (finalizedBlockNumber > beforeInitialblockNumber && !finalizedCheckpointedBlock?.block.header) {
|
|
413
|
-
throw new Error(
|
|
414
|
-
`Failed to retrieve finalized block header for block ${finalizedBlockNumber} (latest block is ${latestBlockNumber})`,
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
const latestBlockHeaderHash = (await latestBlockHeader?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
|
|
419
|
-
const provenBlockHeaderHash = (await provenCheckpointedBlock?.block.header?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
|
|
420
|
-
const finalizedBlockHeaderHash =
|
|
421
|
-
(await finalizedCheckpointedBlock?.block.header?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
|
|
422
|
-
const checkpointedBlockHeaderHash = (await checkpointedBlock?.block.header?.hash()) ?? GENESIS_BLOCK_HEADER_HASH;
|
|
423
|
-
|
|
424
|
-
// Now attempt to retrieve checkpoints for proven, finalised and checkpointed blocks
|
|
425
|
-
const [[provenBlockCheckpoint], [finalizedBlockCheckpoint], [checkpointedBlockCheckpoint]] = await Promise.all([
|
|
426
|
-
provenCheckpointedBlock !== undefined
|
|
427
|
-
? await this.getCheckpoints(provenCheckpointedBlock?.checkpointNumber, 1)
|
|
428
|
-
: [undefined],
|
|
429
|
-
finalizedCheckpointedBlock !== undefined
|
|
430
|
-
? await this.getCheckpoints(finalizedCheckpointedBlock?.checkpointNumber, 1)
|
|
431
|
-
: [undefined],
|
|
432
|
-
checkpointedBlock !== undefined ? await this.getCheckpoints(checkpointedBlock?.checkpointNumber, 1) : [undefined],
|
|
433
|
-
]);
|
|
434
|
-
|
|
435
|
-
const initialcheckpointId: CheckpointId = {
|
|
436
|
-
number: CheckpointNumber.ZERO,
|
|
437
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(),
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
const makeCheckpointId = (checkpoint: PublishedCheckpoint | undefined) => {
|
|
441
|
-
if (checkpoint === undefined) {
|
|
442
|
-
return initialcheckpointId;
|
|
443
|
-
}
|
|
444
|
-
return {
|
|
445
|
-
number: checkpoint.checkpoint.number,
|
|
446
|
-
hash: checkpoint.checkpoint.hash().toString(),
|
|
447
|
-
};
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
const l2Tips: L2Tips = {
|
|
451
|
-
proposed: {
|
|
452
|
-
number: latestBlockNumber,
|
|
453
|
-
hash: latestBlockHeaderHash.toString(),
|
|
454
|
-
},
|
|
455
|
-
proven: {
|
|
456
|
-
block: {
|
|
457
|
-
number: provenBlockNumber,
|
|
458
|
-
hash: provenBlockHeaderHash.toString(),
|
|
459
|
-
},
|
|
460
|
-
checkpoint: makeCheckpointId(provenBlockCheckpoint),
|
|
461
|
-
},
|
|
462
|
-
finalized: {
|
|
463
|
-
block: {
|
|
464
|
-
number: finalizedBlockNumber,
|
|
465
|
-
hash: finalizedBlockHeaderHash.toString(),
|
|
466
|
-
},
|
|
467
|
-
checkpoint: makeCheckpointId(finalizedBlockCheckpoint),
|
|
468
|
-
},
|
|
469
|
-
checkpointed: {
|
|
470
|
-
block: {
|
|
471
|
-
number: checkpointedBlockNumber,
|
|
472
|
-
hash: checkpointedBlockHeaderHash.toString(),
|
|
473
|
-
},
|
|
474
|
-
checkpoint: makeCheckpointId(checkpointedBlockCheckpoint),
|
|
475
|
-
},
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
return l2Tips;
|
|
403
|
+
public getL2Tips(): Promise<L2Tips> {
|
|
404
|
+
return this.l2TipsCache.getL2Tips();
|
|
479
405
|
}
|
|
480
406
|
|
|
481
407
|
public async rollbackTo(targetL2BlockNumber: BlockNumber): Promise<void> {
|
|
482
|
-
// TODO(pw/mbps): This still assumes 1 block per checkpoint
|
|
483
408
|
const currentBlocks = await this.getL2Tips();
|
|
484
409
|
const currentL2Block = currentBlocks.proposed.number;
|
|
485
410
|
const currentProvenBlock = currentBlocks.proven.block.number;
|
|
@@ -491,8 +416,25 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
491
416
|
if (!targetL2Block) {
|
|
492
417
|
throw new Error(`Target L2 block ${targetL2BlockNumber} not found`);
|
|
493
418
|
}
|
|
494
|
-
const targetL1BlockNumber = targetL2Block.l1.blockNumber;
|
|
495
419
|
const targetCheckpointNumber = targetL2Block.checkpointNumber;
|
|
420
|
+
|
|
421
|
+
// Rollback operates at checkpoint granularity: the target block must be the last block of its checkpoint.
|
|
422
|
+
const checkpointData = await this.store.getCheckpointData(targetCheckpointNumber);
|
|
423
|
+
if (checkpointData) {
|
|
424
|
+
const lastBlockInCheckpoint = BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1);
|
|
425
|
+
if (targetL2BlockNumber !== lastBlockInCheckpoint) {
|
|
426
|
+
const previousCheckpointBoundary =
|
|
427
|
+
checkpointData.startBlock > 1 ? BlockNumber(checkpointData.startBlock - 1) : BlockNumber(0);
|
|
428
|
+
throw new Error(
|
|
429
|
+
`Target L2 block ${targetL2BlockNumber} is not at a checkpoint boundary. ` +
|
|
430
|
+
`Checkpoint ${targetCheckpointNumber} spans blocks ${checkpointData.startBlock} to ${lastBlockInCheckpoint}. ` +
|
|
431
|
+
`Use block ${lastBlockInCheckpoint} to roll back to this checkpoint, ` +
|
|
432
|
+
`or block ${previousCheckpointBoundary} to roll back to the previous one.`,
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const targetL1BlockNumber = targetL2Block.l1.blockNumber;
|
|
496
438
|
const targetL1Block = await this.publicClient.getBlock({
|
|
497
439
|
blockNumber: targetL1BlockNumber,
|
|
498
440
|
includeTransactions: false,
|
|
@@ -511,13 +453,14 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
511
453
|
await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
|
|
512
454
|
await this.store.setMessageSynchedL1Block({ l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash });
|
|
513
455
|
if (targetL2BlockNumber < currentProvenBlock) {
|
|
514
|
-
this.log.info(`
|
|
515
|
-
await this.
|
|
456
|
+
this.log.info(`Rolling back proven L2 checkpoint to ${targetCheckpointNumber}`);
|
|
457
|
+
await this.updater.setProvenCheckpointNumber(targetCheckpointNumber);
|
|
516
458
|
}
|
|
517
459
|
// TODO(palla/reorg): Set the finalized block when we add support for it.
|
|
460
|
+
// const currentFinalizedBlock = currentBlocks.finalized.block.number;
|
|
518
461
|
// if (targetL2BlockNumber < currentFinalizedBlock) {
|
|
519
|
-
// this.log.info(`
|
|
520
|
-
// await this.
|
|
462
|
+
// this.log.info(`Rolling back finalized L2 checkpoint to ${targetCheckpointNumber}`);
|
|
463
|
+
// await this.updater.setFinalizedCheckpointNumber(targetCheckpointNumber);
|
|
521
464
|
// }
|
|
522
465
|
}
|
|
523
466
|
}
|
package/src/factory.ts
CHANGED
|
@@ -6,9 +6,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
|
6
6
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
7
7
|
import { merge } from '@aztec/foundation/collection';
|
|
8
8
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
10
9
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
11
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
12
10
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
13
11
|
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
14
12
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
@@ -16,6 +14,7 @@ import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
|
|
|
16
14
|
import type { ArchiverEmitter } from '@aztec/stdlib/block';
|
|
17
15
|
import { type ContractClassPublic, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
18
16
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
17
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
19
18
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
20
19
|
|
|
21
20
|
import { EventEmitter } from 'events';
|
|
@@ -26,6 +25,7 @@ import { type ArchiverConfig, mapArchiverConfig } from './config.js';
|
|
|
26
25
|
import { ArchiverInstrumentation } from './modules/instrumentation.js';
|
|
27
26
|
import { ArchiverL1Synchronizer } from './modules/l1_synchronizer.js';
|
|
28
27
|
import { ARCHIVER_DB_VERSION, KVArchiverDataStore } from './store/kv_archiver_store.js';
|
|
28
|
+
import { L2TipsCache } from './store/l2_tips_cache.js';
|
|
29
29
|
|
|
30
30
|
export const ARCHIVER_STORE_NAME = 'archiver';
|
|
31
31
|
|
|
@@ -38,7 +38,7 @@ export async function createArchiverStore(
|
|
|
38
38
|
...userConfig,
|
|
39
39
|
dataStoreMapSizeKb: userConfig.archiverStoreMapSizeKb ?? userConfig.dataStoreMapSizeKb,
|
|
40
40
|
};
|
|
41
|
-
const store = await createStore(ARCHIVER_STORE_NAME, ARCHIVER_DB_VERSION, config
|
|
41
|
+
const store = await createStore(ARCHIVER_STORE_NAME, ARCHIVER_DB_VERSION, config);
|
|
42
42
|
return new KVArchiverDataStore(store, config.maxLogs, l1Constants);
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -78,14 +78,23 @@ export async function createArchiver(
|
|
|
78
78
|
const inbox = new InboxContract(publicClient, config.l1Contracts.inboxAddress);
|
|
79
79
|
|
|
80
80
|
// Fetch L1 constants from rollup contract
|
|
81
|
-
const [
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
const [
|
|
82
|
+
l1StartBlock,
|
|
83
|
+
l1GenesisTime,
|
|
84
|
+
proofSubmissionEpochs,
|
|
85
|
+
genesisArchiveRoot,
|
|
86
|
+
slashingProposerAddress,
|
|
87
|
+
targetCommitteeSize,
|
|
88
|
+
rollupManaLimit,
|
|
89
|
+
] = await Promise.all([
|
|
90
|
+
rollup.getL1StartBlock(),
|
|
91
|
+
rollup.getL1GenesisTime(),
|
|
92
|
+
rollup.getProofSubmissionEpochs(),
|
|
93
|
+
rollup.getGenesisArchiveTreeRoot(),
|
|
94
|
+
rollup.getSlashingProposerAddress(),
|
|
95
|
+
rollup.getTargetCommitteeSize(),
|
|
96
|
+
rollup.getManaLimit(),
|
|
97
|
+
] as const);
|
|
89
98
|
|
|
90
99
|
const l1StartBlockHash = await publicClient
|
|
91
100
|
.getBlock({ blockNumber: l1StartBlock, includeTransactions: false })
|
|
@@ -101,7 +110,9 @@ export async function createArchiver(
|
|
|
101
110
|
slotDuration,
|
|
102
111
|
ethereumSlotDuration,
|
|
103
112
|
proofSubmissionEpochs: Number(proofSubmissionEpochs),
|
|
113
|
+
targetCommitteeSize,
|
|
104
114
|
genesisArchiveRoot: Fr.fromString(genesisArchiveRoot.toString()),
|
|
115
|
+
rollupManaLimit: Number(rollupManaLimit),
|
|
105
116
|
};
|
|
106
117
|
|
|
107
118
|
const archiverConfig = merge(
|
|
@@ -121,13 +132,15 @@ export async function createArchiver(
|
|
|
121
132
|
// Create the event emitter that will be shared by archiver and synchronizer
|
|
122
133
|
const events = new EventEmitter() as ArchiverEmitter;
|
|
123
134
|
|
|
135
|
+
// Create L2 tips cache shared by archiver and synchronizer
|
|
136
|
+
const l2TipsCache = new L2TipsCache(archiverStore.blockStore);
|
|
137
|
+
|
|
124
138
|
// Create the L1 synchronizer
|
|
125
139
|
const synchronizer = new ArchiverL1Synchronizer(
|
|
126
140
|
publicClient,
|
|
127
141
|
debugClient,
|
|
128
142
|
rollup,
|
|
129
143
|
inbox,
|
|
130
|
-
{ ...config.l1Contracts, slashingProposerAddress },
|
|
131
144
|
archiverStore,
|
|
132
145
|
archiverConfig,
|
|
133
146
|
deps.blobClient,
|
|
@@ -137,6 +150,8 @@ export async function createArchiver(
|
|
|
137
150
|
l1Constants,
|
|
138
151
|
events,
|
|
139
152
|
instrumentation.tracer,
|
|
153
|
+
l2TipsCache,
|
|
154
|
+
undefined, // log (use default)
|
|
140
155
|
);
|
|
141
156
|
|
|
142
157
|
const archiver = new Archiver(
|
|
@@ -151,13 +166,15 @@ export async function createArchiver(
|
|
|
151
166
|
l1Constants,
|
|
152
167
|
synchronizer,
|
|
153
168
|
events,
|
|
169
|
+
l2TipsCache,
|
|
154
170
|
);
|
|
155
171
|
|
|
156
172
|
await archiver.start(opts.blockUntilSync);
|
|
157
173
|
return archiver;
|
|
158
174
|
}
|
|
159
175
|
|
|
160
|
-
|
|
176
|
+
/** Registers protocol contracts in the archiver store. */
|
|
177
|
+
export async function registerProtocolContracts(store: KVArchiverDataStore) {
|
|
161
178
|
const blockNumber = 0;
|
|
162
179
|
for (const name of protocolContractNames) {
|
|
163
180
|
const provider = new BundledProtocolContractsProvider();
|