@aztec/archiver 3.0.0-rc.5 → 4.0.0-nightly.20260107
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/archiver.d.ts +69 -49
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +777 -214
- package/dest/archiver/archiver_store.d.ts +89 -30
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +1785 -288
- package/dest/archiver/config.d.ts +3 -3
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +2 -2
- package/dest/archiver/errors.d.ts +25 -1
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/errors.js +37 -0
- package/dest/archiver/index.d.ts +2 -2
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts +49 -17
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +320 -84
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +33 -37
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +60 -35
- package/dest/archiver/kv_archiver_store/log_store.d.ts +14 -11
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +149 -62
- package/dest/archiver/l1/bin/retrieve-calldata.js +5 -3
- package/dest/archiver/l1/calldata_retriever.d.ts +17 -3
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/archiver/l1/calldata_retriever.js +75 -7
- package/dest/archiver/l1/data_retrieval.d.ts +13 -10
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/l1/data_retrieval.js +31 -18
- package/dest/archiver/structs/published.d.ts +1 -2
- package/dest/archiver/structs/published.d.ts.map +1 -1
- package/dest/factory.d.ts +1 -1
- package/dest/factory.js +1 -1
- package/dest/test/mock_l2_block_source.d.ts +10 -3
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +16 -15
- package/package.json +13 -13
- package/src/archiver/archiver.ts +509 -260
- package/src/archiver/archiver_store.ts +99 -29
- package/src/archiver/archiver_store_test_suite.ts +1831 -274
- package/src/archiver/config.ts +7 -3
- package/src/archiver/errors.ts +64 -0
- package/src/archiver/index.ts +1 -1
- package/src/archiver/kv_archiver_store/block_store.ts +434 -94
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +74 -49
- package/src/archiver/kv_archiver_store/log_store.ts +213 -77
- package/src/archiver/l1/bin/retrieve-calldata.ts +3 -3
- package/src/archiver/l1/calldata_retriever.ts +116 -6
- package/src/archiver/l1/data_retrieval.ts +41 -20
- package/src/archiver/structs/published.ts +0 -1
- package/src/factory.ts +1 -1
- package/src/test/mock_l2_block_source.ts +20 -16
|
@@ -76,7 +76,7 @@ async function main() {
|
|
|
76
76
|
// Create viem public client
|
|
77
77
|
const publicClient = createPublicClient({
|
|
78
78
|
chain: mainnet,
|
|
79
|
-
transport: http(rpcUrl),
|
|
79
|
+
transport: http(rpcUrl, { batch: false }),
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
logger.info('Fetching transaction...');
|
|
@@ -141,8 +141,8 @@ async function main() {
|
|
|
141
141
|
logger.info('Retrieving block header from rollup transaction...');
|
|
142
142
|
logger.info('');
|
|
143
143
|
|
|
144
|
-
// For this script, we don't have blob hashes, so pass empty
|
|
145
|
-
const result = await retriever.getCheckpointFromRollupTx(txHash, [], CheckpointNumber(l2BlockNumber));
|
|
144
|
+
// For this script, we don't have blob hashes or expected hashes, so pass empty arrays/objects
|
|
145
|
+
const result = await retriever.getCheckpointFromRollupTx(txHash, [], CheckpointNumber(l2BlockNumber), {});
|
|
146
146
|
|
|
147
147
|
logger.info(' Successfully retrieved block header!');
|
|
148
148
|
logger.info('');
|
|
@@ -13,9 +13,20 @@ import {
|
|
|
13
13
|
TallySlashingProposerAbi,
|
|
14
14
|
} from '@aztec/l1-artifacts';
|
|
15
15
|
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
16
|
+
import { ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
|
|
16
17
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
17
18
|
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
type AbiParameter,
|
|
21
|
+
type Hex,
|
|
22
|
+
type Transaction,
|
|
23
|
+
decodeFunctionData,
|
|
24
|
+
encodeAbiParameters,
|
|
25
|
+
hexToBytes,
|
|
26
|
+
keccak256,
|
|
27
|
+
multicall3Abi,
|
|
28
|
+
toFunctionSelector,
|
|
29
|
+
} from 'viem';
|
|
19
30
|
|
|
20
31
|
import type { ArchiverInstrumentation } from '../instrumentation.js';
|
|
21
32
|
import { getSuccessfulCallsFromDebug } from './debug_tx.js';
|
|
@@ -56,12 +67,17 @@ export class CalldataRetriever {
|
|
|
56
67
|
* @param txHash - Hash of the tx that published it.
|
|
57
68
|
* @param blobHashes - Blob hashes for the checkpoint.
|
|
58
69
|
* @param checkpointNumber - Checkpoint number.
|
|
70
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
59
71
|
* @returns Checkpoint header and metadata from the calldata, deserialized
|
|
60
72
|
*/
|
|
61
73
|
async getCheckpointFromRollupTx(
|
|
62
74
|
txHash: `0x${string}`,
|
|
63
75
|
blobHashes: Buffer[],
|
|
64
76
|
checkpointNumber: CheckpointNumber,
|
|
77
|
+
expectedHashes: {
|
|
78
|
+
attestationsHash?: Hex;
|
|
79
|
+
payloadDigest?: Hex;
|
|
80
|
+
},
|
|
65
81
|
): Promise<{
|
|
66
82
|
checkpointNumber: CheckpointNumber;
|
|
67
83
|
archiveRoot: Fr;
|
|
@@ -69,10 +85,14 @@ export class CalldataRetriever {
|
|
|
69
85
|
attestations: CommitteeAttestation[];
|
|
70
86
|
blockHash: string;
|
|
71
87
|
}> {
|
|
72
|
-
this.logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}
|
|
88
|
+
this.logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}`, {
|
|
89
|
+
willValidateHashes: !!expectedHashes.attestationsHash || !!expectedHashes.payloadDigest,
|
|
90
|
+
hasAttestationsHash: !!expectedHashes.attestationsHash,
|
|
91
|
+
hasPayloadDigest: !!expectedHashes.payloadDigest,
|
|
92
|
+
});
|
|
73
93
|
const tx = await this.publicClient.getTransaction({ hash: txHash });
|
|
74
94
|
const proposeCalldata = await this.getProposeCallData(tx, checkpointNumber);
|
|
75
|
-
return this.decodeAndBuildCheckpoint(proposeCalldata, tx.blockHash!, checkpointNumber);
|
|
95
|
+
return this.decodeAndBuildCheckpoint(proposeCalldata, tx.blockHash!, checkpointNumber, expectedHashes);
|
|
76
96
|
}
|
|
77
97
|
|
|
78
98
|
/** Gets rollup propose calldata from a transaction */
|
|
@@ -324,17 +344,59 @@ export class CalldataRetriever {
|
|
|
324
344
|
return calls[0].input;
|
|
325
345
|
}
|
|
326
346
|
|
|
347
|
+
/**
|
|
348
|
+
* Extracts the CommitteeAttestations struct definition from RollupAbi.
|
|
349
|
+
* Finds the _attestations parameter by name in the propose function.
|
|
350
|
+
* Lazy-loaded to avoid issues during module initialization.
|
|
351
|
+
*/
|
|
352
|
+
private getCommitteeAttestationsStructDef(): AbiParameter {
|
|
353
|
+
const proposeFunction = RollupAbi.find(item => item.type === 'function' && item.name === 'propose') as
|
|
354
|
+
| { type: 'function'; name: string; inputs: readonly AbiParameter[] }
|
|
355
|
+
| undefined;
|
|
356
|
+
|
|
357
|
+
if (!proposeFunction) {
|
|
358
|
+
throw new Error('propose function not found in RollupAbi');
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Find the _attestations parameter by name, not by index
|
|
362
|
+
const attestationsParam = proposeFunction.inputs.find(param => param.name === '_attestations');
|
|
363
|
+
|
|
364
|
+
if (!attestationsParam) {
|
|
365
|
+
throw new Error('_attestations parameter not found in propose function');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (attestationsParam.type !== 'tuple') {
|
|
369
|
+
throw new Error(`Expected _attestations parameter to be a tuple, got ${attestationsParam.type}`);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Extract the tuple components (struct fields)
|
|
373
|
+
const tupleParam = attestationsParam as unknown as {
|
|
374
|
+
type: 'tuple';
|
|
375
|
+
components?: readonly AbiParameter[];
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
type: 'tuple',
|
|
380
|
+
components: tupleParam.components || [],
|
|
381
|
+
} as AbiParameter;
|
|
382
|
+
}
|
|
383
|
+
|
|
327
384
|
/**
|
|
328
385
|
* Decodes propose calldata and builds the checkpoint header structure.
|
|
329
386
|
* @param proposeCalldata - The propose function calldata
|
|
330
387
|
* @param blockHash - The L1 block hash containing this transaction
|
|
331
388
|
* @param checkpointNumber - The checkpoint number
|
|
389
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
332
390
|
* @returns The decoded checkpoint header and metadata
|
|
333
391
|
*/
|
|
334
392
|
protected decodeAndBuildCheckpoint(
|
|
335
393
|
proposeCalldata: Hex,
|
|
336
394
|
blockHash: Hex,
|
|
337
395
|
checkpointNumber: CheckpointNumber,
|
|
396
|
+
expectedHashes: {
|
|
397
|
+
attestationsHash?: Hex;
|
|
398
|
+
payloadDigest?: Hex;
|
|
399
|
+
},
|
|
338
400
|
): {
|
|
339
401
|
checkpointNumber: CheckpointNumber;
|
|
340
402
|
archiveRoot: Fr;
|
|
@@ -365,6 +427,57 @@ export class CalldataRetriever {
|
|
|
365
427
|
];
|
|
366
428
|
|
|
367
429
|
const attestations = CommitteeAttestation.fromPacked(packedAttestations, this.targetCommitteeSize);
|
|
430
|
+
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
431
|
+
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
432
|
+
|
|
433
|
+
// Validate attestationsHash if provided (skip for backwards compatibility with older events)
|
|
434
|
+
if (expectedHashes.attestationsHash) {
|
|
435
|
+
// Compute attestationsHash: keccak256(abi.encode(CommitteeAttestations))
|
|
436
|
+
const computedAttestationsHash = keccak256(
|
|
437
|
+
encodeAbiParameters([this.getCommitteeAttestationsStructDef()], [packedAttestations]),
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
// Compare as buffers to avoid case-sensitivity and string comparison issues
|
|
441
|
+
const computedBuffer = Buffer.from(hexToBytes(computedAttestationsHash));
|
|
442
|
+
const expectedBuffer = Buffer.from(hexToBytes(expectedHashes.attestationsHash));
|
|
443
|
+
|
|
444
|
+
if (!computedBuffer.equals(expectedBuffer)) {
|
|
445
|
+
throw new Error(
|
|
446
|
+
`Attestations hash mismatch for checkpoint ${checkpointNumber}: ` +
|
|
447
|
+
`computed=${computedAttestationsHash}, expected=${expectedHashes.attestationsHash}`,
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
this.logger.trace(`Validated attestationsHash for checkpoint ${checkpointNumber}`, {
|
|
452
|
+
computedAttestationsHash,
|
|
453
|
+
expectedAttestationsHash: expectedHashes.attestationsHash,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Validate payloadDigest if provided (skip for backwards compatibility with older events)
|
|
458
|
+
if (expectedHashes.payloadDigest) {
|
|
459
|
+
// Use ConsensusPayload to compute the digest - this ensures we match the exact logic
|
|
460
|
+
// used by the network for signing and verification
|
|
461
|
+
const consensusPayload = new ConsensusPayload(header, archiveRoot);
|
|
462
|
+
const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.blockAttestation);
|
|
463
|
+
const computedPayloadDigest = keccak256(payloadToSign);
|
|
464
|
+
|
|
465
|
+
// Compare as buffers to avoid case-sensitivity and string comparison issues
|
|
466
|
+
const computedBuffer = Buffer.from(hexToBytes(computedPayloadDigest));
|
|
467
|
+
const expectedBuffer = Buffer.from(hexToBytes(expectedHashes.payloadDigest));
|
|
468
|
+
|
|
469
|
+
if (!computedBuffer.equals(expectedBuffer)) {
|
|
470
|
+
throw new Error(
|
|
471
|
+
`Payload digest mismatch for checkpoint ${checkpointNumber}: ` +
|
|
472
|
+
`computed=${computedPayloadDigest}, expected=${expectedHashes.payloadDigest}`,
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
this.logger.trace(`Validated payloadDigest for checkpoint ${checkpointNumber}`, {
|
|
477
|
+
computedPayloadDigest,
|
|
478
|
+
expectedPayloadDigest: expectedHashes.payloadDigest,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
368
481
|
|
|
369
482
|
this.logger.trace(`Decoded propose calldata`, {
|
|
370
483
|
checkpointNumber,
|
|
@@ -376,9 +489,6 @@ export class CalldataRetriever {
|
|
|
376
489
|
targetCommitteeSize: this.targetCommitteeSize,
|
|
377
490
|
});
|
|
378
491
|
|
|
379
|
-
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
380
|
-
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
381
|
-
|
|
382
492
|
return {
|
|
383
493
|
checkpointNumber,
|
|
384
494
|
archiveRoot,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
1
2
|
import {
|
|
2
3
|
BlobDeserializationError,
|
|
3
4
|
type CheckpointBlobData,
|
|
@@ -5,7 +6,6 @@ import {
|
|
|
5
6
|
decodeCheckpointBlobDataFromBlobs,
|
|
6
7
|
encodeBlockBlobData,
|
|
7
8
|
} from '@aztec/blob-lib';
|
|
8
|
-
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
9
9
|
import type { EpochProofPublicInputArgs } from '@aztec/ethereum/contracts';
|
|
10
10
|
import type { ViemClient, ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
11
11
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
@@ -16,7 +16,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
16
16
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
17
17
|
import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
18
18
|
import { Body, CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
|
|
19
|
-
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
19
|
+
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
20
20
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
21
21
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
22
22
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
@@ -35,7 +35,6 @@ import { NoBlobBodiesFoundError } from '../errors.js';
|
|
|
35
35
|
import type { ArchiverInstrumentation } from '../instrumentation.js';
|
|
36
36
|
import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
37
37
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
38
|
-
import type { L1PublishedData } from '../structs/published.js';
|
|
39
38
|
import { CalldataRetriever } from './calldata_retriever.js';
|
|
40
39
|
|
|
41
40
|
export type RetrievedCheckpoint = {
|
|
@@ -138,19 +137,23 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
138
137
|
|
|
139
138
|
/**
|
|
140
139
|
* Fetches new checkpoints.
|
|
140
|
+
* @param rollup - The rollup contract instance.
|
|
141
141
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
142
142
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
143
|
-
* @param
|
|
143
|
+
* @param blobClient - The blob client client for fetching blob data.
|
|
144
144
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
145
145
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
146
|
-
* @param
|
|
147
|
-
* @
|
|
146
|
+
* @param contractAddresses - The contract addresses (governanceProposerAddress, slashFactoryAddress, slashingProposerAddress).
|
|
147
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
148
|
+
* @param logger - The logger instance.
|
|
149
|
+
* @param isHistoricalSync - Whether this is a historical sync.
|
|
150
|
+
* @returns An array of retrieved checkpoints.
|
|
148
151
|
*/
|
|
149
152
|
export async function retrieveCheckpointsFromRollup(
|
|
150
153
|
rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
|
|
151
154
|
publicClient: ViemPublicClient,
|
|
152
155
|
debugClient: ViemPublicDebugClient,
|
|
153
|
-
|
|
156
|
+
blobClient: BlobClientInterface,
|
|
154
157
|
searchStartBlock: bigint,
|
|
155
158
|
searchEndBlock: bigint,
|
|
156
159
|
contractAddresses: {
|
|
@@ -160,6 +163,7 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
160
163
|
},
|
|
161
164
|
instrumentation: ArchiverInstrumentation,
|
|
162
165
|
logger: Logger = createLogger('archiver'),
|
|
166
|
+
isHistoricalSync: boolean = false,
|
|
163
167
|
): Promise<RetrievedCheckpoint[]> {
|
|
164
168
|
const retrievedCheckpoints: RetrievedCheckpoint[] = [];
|
|
165
169
|
|
|
@@ -205,12 +209,13 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
205
209
|
rollup,
|
|
206
210
|
publicClient,
|
|
207
211
|
debugClient,
|
|
208
|
-
|
|
212
|
+
blobClient,
|
|
209
213
|
checkpointProposedLogs,
|
|
210
214
|
rollupConstants,
|
|
211
215
|
contractAddresses,
|
|
212
216
|
instrumentation,
|
|
213
217
|
logger,
|
|
218
|
+
isHistoricalSync,
|
|
214
219
|
);
|
|
215
220
|
retrievedCheckpoints.push(...newCheckpoints);
|
|
216
221
|
searchStartBlock = lastLog.blockNumber! + 1n;
|
|
@@ -222,17 +227,23 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
222
227
|
|
|
223
228
|
/**
|
|
224
229
|
* Processes newly received CheckpointProposed logs.
|
|
225
|
-
* @param rollup - The rollup contract
|
|
230
|
+
* @param rollup - The rollup contract instance.
|
|
226
231
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
227
232
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
233
|
+
* @param blobClient - The blob client client for fetching blob data.
|
|
228
234
|
* @param logs - CheckpointProposed logs.
|
|
229
|
-
* @
|
|
235
|
+
* @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
|
|
236
|
+
* @param contractAddresses - The contract addresses (governanceProposerAddress, slashFactoryAddress, slashingProposerAddress).
|
|
237
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
238
|
+
* @param logger - The logger instance.
|
|
239
|
+
* @param isHistoricalSync - Whether this is a historical sync.
|
|
240
|
+
* @returns An array of retrieved checkpoints.
|
|
230
241
|
*/
|
|
231
242
|
async function processCheckpointProposedLogs(
|
|
232
243
|
rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
|
|
233
244
|
publicClient: ViemPublicClient,
|
|
234
245
|
debugClient: ViemPublicDebugClient,
|
|
235
|
-
|
|
246
|
+
blobClient: BlobClientInterface,
|
|
236
247
|
logs: GetContractEventsReturnType<typeof RollupAbi, 'CheckpointProposed'>,
|
|
237
248
|
{ chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
|
|
238
249
|
contractAddresses: {
|
|
@@ -242,6 +253,7 @@ async function processCheckpointProposedLogs(
|
|
|
242
253
|
},
|
|
243
254
|
instrumentation: ArchiverInstrumentation,
|
|
244
255
|
logger: Logger,
|
|
256
|
+
isHistoricalSync: boolean,
|
|
245
257
|
): Promise<RetrievedCheckpoint[]> {
|
|
246
258
|
const retrievedCheckpoints: RetrievedCheckpoint[] = [];
|
|
247
259
|
const calldataRetriever = new CalldataRetriever(
|
|
@@ -261,24 +273,32 @@ async function processCheckpointProposedLogs(
|
|
|
261
273
|
|
|
262
274
|
// The value from the event and contract will match only if the checkpoint is in the chain.
|
|
263
275
|
if (archive === archiveFromChain) {
|
|
276
|
+
// Build expected hashes object (fields may be undefined for backwards compatibility with older events)
|
|
277
|
+
const expectedHashes = {
|
|
278
|
+
attestationsHash: log.args.attestationsHash,
|
|
279
|
+
payloadDigest: log.args.payloadDigest,
|
|
280
|
+
};
|
|
281
|
+
|
|
264
282
|
const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(
|
|
265
283
|
log.transactionHash!,
|
|
266
284
|
blobHashes,
|
|
267
285
|
checkpointNumber,
|
|
286
|
+
expectedHashes,
|
|
268
287
|
);
|
|
269
288
|
const checkpointBlobData = await getCheckpointBlobDataFromBlobs(
|
|
270
|
-
|
|
289
|
+
blobClient,
|
|
271
290
|
checkpoint.blockHash,
|
|
272
291
|
blobHashes,
|
|
273
292
|
checkpointNumber,
|
|
274
293
|
logger,
|
|
294
|
+
isHistoricalSync,
|
|
275
295
|
);
|
|
276
296
|
|
|
277
|
-
const l1
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
297
|
+
const l1 = new L1PublishedData(
|
|
298
|
+
log.blockNumber,
|
|
299
|
+
await getL1BlockTime(publicClient, log.blockNumber),
|
|
300
|
+
log.blockHash,
|
|
301
|
+
);
|
|
282
302
|
|
|
283
303
|
retrievedCheckpoints.push({ ...checkpoint, checkpointBlobData, l1, chainId, version });
|
|
284
304
|
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.transactionHash}`, {
|
|
@@ -304,13 +324,14 @@ export async function getL1BlockTime(publicClient: ViemPublicClient, blockNumber
|
|
|
304
324
|
}
|
|
305
325
|
|
|
306
326
|
export async function getCheckpointBlobDataFromBlobs(
|
|
307
|
-
|
|
327
|
+
blobClient: BlobClientInterface,
|
|
308
328
|
blockHash: string,
|
|
309
329
|
blobHashes: Buffer<ArrayBufferLike>[],
|
|
310
330
|
checkpointNumber: CheckpointNumber,
|
|
311
331
|
logger: Logger,
|
|
332
|
+
isHistoricalSync: boolean,
|
|
312
333
|
): Promise<CheckpointBlobData> {
|
|
313
|
-
const blobBodies = await
|
|
334
|
+
const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, { isHistoricalSync });
|
|
314
335
|
if (blobBodies.length === 0) {
|
|
315
336
|
throw new NoBlobBodiesFoundError(checkpointNumber);
|
|
316
337
|
}
|
|
@@ -318,7 +339,7 @@ export async function getCheckpointBlobDataFromBlobs(
|
|
|
318
339
|
let checkpointBlobData: CheckpointBlobData;
|
|
319
340
|
try {
|
|
320
341
|
// Attempt to decode the checkpoint blob data.
|
|
321
|
-
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies
|
|
342
|
+
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies);
|
|
322
343
|
} catch (err: any) {
|
|
323
344
|
if (err instanceof BlobDeserializationError) {
|
|
324
345
|
logger.fatal(err.message);
|
package/src/factory.ts
CHANGED
|
@@ -28,7 +28,7 @@ export async function createArchiverStore(
|
|
|
28
28
|
/**
|
|
29
29
|
* Creates a local archiver.
|
|
30
30
|
* @param config - The archiver configuration.
|
|
31
|
-
* @param
|
|
31
|
+
* @param blobClient - The blob client client.
|
|
32
32
|
* @param opts - The options.
|
|
33
33
|
* @param telemetry - The telemetry client.
|
|
34
34
|
* @returns The local archiver.
|
|
@@ -10,12 +10,13 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
10
10
|
import {
|
|
11
11
|
L2Block,
|
|
12
12
|
L2BlockHash,
|
|
13
|
+
L2BlockNew,
|
|
13
14
|
type L2BlockSource,
|
|
14
15
|
type L2Tips,
|
|
15
16
|
PublishedL2Block,
|
|
16
17
|
type ValidateBlockResult,
|
|
17
18
|
} from '@aztec/stdlib/block';
|
|
18
|
-
import type
|
|
19
|
+
import { type Checkpoint, L1PublishedData } from '@aztec/stdlib/checkpoint';
|
|
19
20
|
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
20
21
|
import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
21
22
|
import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
@@ -91,6 +92,11 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
|
91
92
|
return Promise.resolve(BlockNumber(this.provenBlockNumber));
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
public getCheckpointedBlock(_number: BlockNumber) {
|
|
96
|
+
// In this mock, we don't track checkpointed blocks separately
|
|
97
|
+
return Promise.resolve(undefined);
|
|
98
|
+
}
|
|
99
|
+
|
|
94
100
|
/**
|
|
95
101
|
* Gets an l2 block.
|
|
96
102
|
* @param number - The block number to return (inclusive).
|
|
@@ -100,6 +106,16 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
|
100
106
|
return Promise.resolve(this.l2Blocks[number - 1]);
|
|
101
107
|
}
|
|
102
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Gets an L2 block (new format).
|
|
111
|
+
* @param number - The block number to return.
|
|
112
|
+
* @returns The requested L2 block.
|
|
113
|
+
*/
|
|
114
|
+
public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
|
|
115
|
+
const block = this.l2Blocks[number - 1];
|
|
116
|
+
return Promise.resolve(block?.toL2Block());
|
|
117
|
+
}
|
|
118
|
+
|
|
103
119
|
/**
|
|
104
120
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
105
121
|
* @param from - Number of the first block to return (inclusive).
|
|
@@ -129,11 +145,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
|
129
145
|
return blocks.map(block =>
|
|
130
146
|
PublishedL2Block.fromFields({
|
|
131
147
|
block,
|
|
132
|
-
l1:
|
|
133
|
-
blockNumber: BigInt(block.number),
|
|
134
|
-
blockHash: Buffer32.random().toString(),
|
|
135
|
-
timestamp: BigInt(block.number),
|
|
136
|
-
},
|
|
148
|
+
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
137
149
|
attestations: [],
|
|
138
150
|
}),
|
|
139
151
|
);
|
|
@@ -145,11 +157,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
|
145
157
|
if (hash.equals(blockHash)) {
|
|
146
158
|
return PublishedL2Block.fromFields({
|
|
147
159
|
block,
|
|
148
|
-
l1:
|
|
149
|
-
blockNumber: BigInt(block.number),
|
|
150
|
-
blockHash: Buffer32.random().toString(),
|
|
151
|
-
timestamp: BigInt(block.number),
|
|
152
|
-
},
|
|
160
|
+
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
153
161
|
attestations: [],
|
|
154
162
|
});
|
|
155
163
|
}
|
|
@@ -165,11 +173,7 @@ export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
|
165
173
|
return Promise.resolve(
|
|
166
174
|
PublishedL2Block.fromFields({
|
|
167
175
|
block,
|
|
168
|
-
l1:
|
|
169
|
-
blockNumber: BigInt(block.number),
|
|
170
|
-
blockHash: Buffer32.random().toString(),
|
|
171
|
-
timestamp: BigInt(block.number),
|
|
172
|
-
},
|
|
176
|
+
l1: new L1PublishedData(BigInt(block.number), BigInt(block.number), Buffer32.random().toString()),
|
|
173
177
|
attestations: [],
|
|
174
178
|
}),
|
|
175
179
|
);
|