@aztec/archiver 0.0.1-commit.f5d02921e → 0.0.1-commit.f7ea82942
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/README.md +12 -6
- package/dest/archiver.d.ts +5 -3
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +15 -4
- package/dest/config.d.ts +3 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +13 -2
- package/dest/errors.d.ts +17 -1
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +22 -0
- package/dest/factory.d.ts +1 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +2 -1
- package/dest/index.d.ts +3 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/l1/data_retrieval.d.ts +19 -10
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +25 -32
- package/dest/l1/validate_historical_logs.d.ts +23 -0
- package/dest/l1/validate_historical_logs.d.ts.map +1 -0
- package/dest/l1/validate_historical_logs.js +108 -0
- package/dest/modules/data_store_updater.d.ts +12 -5
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +13 -3
- package/dest/modules/instrumentation.d.ts +7 -2
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +22 -6
- package/dest/modules/l1_synchronizer.d.ts +6 -2
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +213 -124
- package/dest/store/block_store.d.ts +11 -3
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +88 -6
- package/dest/store/kv_archiver_store.d.ts +11 -9
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +9 -7
- package/dest/store/l2_tips_cache.d.ts +1 -1
- package/dest/store/l2_tips_cache.d.ts.map +1 -1
- package/dest/store/l2_tips_cache.js +2 -2
- 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 +2 -4
- package/dest/store/message_store.d.ts +3 -3
- package/dest/store/message_store.d.ts.map +1 -1
- package/dest/store/message_store.js +9 -10
- package/dest/test/fake_l1_state.d.ts +14 -3
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +55 -10
- package/dest/test/noop_l1_archiver.d.ts +1 -1
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +4 -2
- package/package.json +13 -13
- package/src/archiver.ts +28 -6
- package/src/config.ts +14 -1
- package/src/errors.ts +34 -0
- package/src/factory.ts +1 -0
- package/src/index.ts +2 -1
- package/src/l1/data_retrieval.ts +36 -45
- package/src/l1/validate_historical_logs.ts +140 -0
- package/src/modules/data_store_updater.ts +27 -3
- package/src/modules/instrumentation.ts +27 -7
- package/src/modules/l1_synchronizer.ts +274 -148
- package/src/store/block_store.ts +112 -4
- package/src/store/kv_archiver_store.ts +18 -10
- package/src/store/l2_tips_cache.ts +8 -2
- package/src/store/log_store.ts +2 -5
- package/src/store/message_store.ts +10 -12
- package/src/structs/inbox_message.ts +1 -1
- package/src/test/fake_l1_state.ts +75 -13
- package/src/test/noop_l1_archiver.ts +3 -1
|
@@ -48,7 +48,9 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
48
48
|
canPruneResult;
|
|
49
49
|
// Computed from checkpoints based on L1 block visibility
|
|
50
50
|
pendingCheckpointNumber;
|
|
51
|
-
// The L1 block number reported as "finalized" (defaults to the start block)
|
|
51
|
+
// The L1 block number reported as "finalized" (defaults to the start block).
|
|
52
|
+
// `undefined` simulates the startup window on a fresh devnet where
|
|
53
|
+
// `getBlock({ blockTag: 'finalized' })` fails with "finalized block not found".
|
|
52
54
|
finalizedL1BlockNumber;
|
|
53
55
|
constructor(config){
|
|
54
56
|
this.config = config;
|
|
@@ -161,7 +163,10 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
161
163
|
this.l1BlockNumber = blockNumber;
|
|
162
164
|
this.updatePendingCheckpointNumber();
|
|
163
165
|
}
|
|
164
|
-
/**
|
|
166
|
+
/**
|
|
167
|
+
* Sets the L1 block number that will be reported as "finalized". Pass `undefined` to
|
|
168
|
+
* simulate a chain that does not yet have a finalized block (devnet startup).
|
|
169
|
+
*/ setFinalizedL1BlockNumber(blockNumber) {
|
|
165
170
|
this.finalizedL1BlockNumber = blockNumber;
|
|
166
171
|
}
|
|
167
172
|
/** Marks a checkpoint as proven. Updates provenCheckpointNumber. */ markCheckpointAsProven(checkpointNumber) {
|
|
@@ -194,6 +199,19 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
194
199
|
this.updatePendingCheckpointNumber();
|
|
195
200
|
}
|
|
196
201
|
/**
|
|
202
|
+
* Moves a checkpoint to a different L1 block number (simulates L1 reorg that
|
|
203
|
+
* re-includes the same checkpoint transaction in a different block).
|
|
204
|
+
* The checkpoint content stays the same — only the L1 metadata changes.
|
|
205
|
+
* Auto-updates pending status.
|
|
206
|
+
*/ moveCheckpointToL1Block(checkpointNumber, newL1BlockNumber) {
|
|
207
|
+
for (const cpData of this.checkpoints){
|
|
208
|
+
if (cpData.checkpointNumber === checkpointNumber) {
|
|
209
|
+
cpData.l1BlockNumber = newL1BlockNumber;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
this.updatePendingCheckpointNumber();
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
197
215
|
* Removes messages after a given total index (simulates L1 reorg).
|
|
198
216
|
* Auto-updates rolling hash.
|
|
199
217
|
*/ removeMessagesAfter(totalIndex) {
|
|
@@ -279,21 +297,26 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
279
297
|
}
|
|
280
298
|
/** Creates mock InboxContract that reads from this fake state. */ createMockInboxContract(_publicClient) {
|
|
281
299
|
const mockInbox = mock();
|
|
282
|
-
mockInbox.getState.mockImplementation(()=>{
|
|
300
|
+
mockInbox.getState.mockImplementation((opts = {})=>{
|
|
301
|
+
// Filter messages visible at the given block number (or all if not specified)
|
|
302
|
+
const blockNumber = opts.blockNumber ?? this.l1BlockNumber;
|
|
303
|
+
const visibleMessages = this.messages.filter((m)=>m.l1BlockNumber <= blockNumber);
|
|
283
304
|
// treeInProgress must be > any sealed checkpoint. On L1, a checkpoint can only be proposed
|
|
284
305
|
// after its messages are sealed, so treeInProgress > checkpointNumber for all published checkpoints.
|
|
285
|
-
const maxFromMessages =
|
|
286
|
-
const maxFromCheckpoints = this.checkpoints.length > 0 ? Math.max(...this.checkpoints.filter((cp)=>!cp.pruned).map((cp)=>Number(cp.checkpointNumber))) + 1 : 0;
|
|
306
|
+
const maxFromMessages = visibleMessages.length > 0 ? Math.max(...visibleMessages.map((m)=>Number(m.checkpointNumber))) + 1 : 0;
|
|
307
|
+
const maxFromCheckpoints = this.checkpoints.length > 0 ? Math.max(...this.checkpoints.filter((cp)=>!cp.pruned && cp.l1BlockNumber <= blockNumber).map((cp)=>Number(cp.checkpointNumber)), 0) + 1 : 0;
|
|
287
308
|
const treeInProgress = Math.max(maxFromMessages, maxFromCheckpoints, INITIAL_CHECKPOINT_NUMBER);
|
|
309
|
+
// Compute rolling hash only for visible messages
|
|
310
|
+
const rollingHash = visibleMessages.length > 0 ? visibleMessages[visibleMessages.length - 1].rollingHash : Buffer16.ZERO;
|
|
288
311
|
return Promise.resolve({
|
|
289
|
-
messagesRollingHash:
|
|
290
|
-
totalMessagesInserted: BigInt(
|
|
312
|
+
messagesRollingHash: rollingHash,
|
|
313
|
+
totalMessagesInserted: BigInt(visibleMessages.length),
|
|
291
314
|
treeInProgress: BigInt(treeInProgress)
|
|
292
315
|
});
|
|
293
316
|
});
|
|
294
317
|
// Mock the wrapper methods for fetching message events
|
|
295
318
|
mockInbox.getMessageSentEvents.mockImplementation((fromBlock, toBlock)=>Promise.resolve(this.getMessageSentLogs(fromBlock, toBlock)));
|
|
296
|
-
mockInbox.getMessageSentEventByHash.mockImplementation((
|
|
319
|
+
mockInbox.getMessageSentEventByHash.mockImplementation((msgHash, aroundL1BlockNumber)=>Promise.resolve(this.getMessageSentLogByHash(msgHash, aroundL1BlockNumber)));
|
|
297
320
|
return mockInbox;
|
|
298
321
|
}
|
|
299
322
|
/** Creates mock PublicClient that reads from this fake state. */ createMockPublicClient() {
|
|
@@ -303,6 +326,11 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
303
326
|
publicClient.getBlock.mockImplementation(async (args = {})=>{
|
|
304
327
|
let blockNum;
|
|
305
328
|
if (args.blockTag === 'finalized') {
|
|
329
|
+
if (this.finalizedL1BlockNumber === undefined) {
|
|
330
|
+
throw Object.assign(new Error('finalized block not found'), {
|
|
331
|
+
details: 'finalized block not found'
|
|
332
|
+
});
|
|
333
|
+
}
|
|
306
334
|
blockNum = this.finalizedL1BlockNumber;
|
|
307
335
|
} else {
|
|
308
336
|
blockNum = args.blockNumber ?? await publicClient.getBlockNumber();
|
|
@@ -319,8 +347,8 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
319
347
|
}
|
|
320
348
|
/** Creates mock BlobClient that reads from this fake state. */ createMockBlobClient() {
|
|
321
349
|
const blobClient = mock();
|
|
322
|
-
// The blockId is the
|
|
323
|
-
blobClient.getBlobSidecar.mockImplementation((blockId)=>Promise.resolve(this.checkpoints.find((cpData)=>cpData.
|
|
350
|
+
// The blockId is the L1 block hash, which we derive from the L1 block number
|
|
351
|
+
blobClient.getBlobSidecar.mockImplementation((blockId)=>Promise.resolve(this.checkpoints.find((cpData)=>Buffer32.fromBigInt(cpData.l1BlockNumber).toString() === blockId)?.blobs ?? []));
|
|
324
352
|
blobClient.testSources.mockResolvedValue(undefined);
|
|
325
353
|
return blobClient;
|
|
326
354
|
}
|
|
@@ -371,6 +399,23 @@ import { updateRollingHash } from '../structs/inbox_message.js';
|
|
|
371
399
|
}
|
|
372
400
|
}));
|
|
373
401
|
}
|
|
402
|
+
getMessageSentLogByHash(msgHash, aroundL1BlockNumber) {
|
|
403
|
+
const msg = this.messages.find((msg)=>msg.leaf.toString() === msgHash && msg.l1BlockNumber >= aroundL1BlockNumber - 5n && msg.l1BlockNumber <= aroundL1BlockNumber + 5n);
|
|
404
|
+
if (!msg) {
|
|
405
|
+
return undefined;
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
l1BlockNumber: msg.l1BlockNumber,
|
|
409
|
+
l1BlockHash: Buffer32.fromBigInt(msg.l1BlockNumber),
|
|
410
|
+
l1TransactionHash: `0x${msg.l1BlockNumber.toString(16)}`,
|
|
411
|
+
args: {
|
|
412
|
+
checkpointNumber: msg.checkpointNumber,
|
|
413
|
+
index: msg.index,
|
|
414
|
+
leaf: msg.leaf,
|
|
415
|
+
rollingHash: msg.rollingHash
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
}
|
|
374
419
|
async makeRollupTx(checkpoint, signers) {
|
|
375
420
|
const attestations = signers.map((signer)=>makeCheckpointAttestationFromCheckpoint(checkpoint, signer)).map((attestation)=>CommitteeAttestation.fromSignature(attestation.signature)).map((committeeAttestation)=>committeeAttestation.toViem());
|
|
376
421
|
const header = checkpoint.header.toViem();
|
|
@@ -23,4 +23,4 @@ export declare class NoopL1Archiver extends Archiver {
|
|
|
23
23
|
export declare function createNoopL1Archiver(dataStore: KVArchiverDataStore, l1Constants: L1RollupConstants & {
|
|
24
24
|
genesisArchiveRoot: Fr;
|
|
25
25
|
}, telemetry?: TelemetryClient): Promise<NoopL1Archiver>;
|
|
26
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9vcF9sMV9hcmNoaXZlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvbm9vcF9sMV9hcmNoaXZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFN0QsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBSXBELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBS2hHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBeUJ6RTs7OztHQUlHO0FBQ0gscUJBQWEsY0FBZSxTQUFRLFFBQVE7SUFDMUMsWUFDRSxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztRQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtLQUFFLEVBQzNELGVBQWUsRUFBRSx1QkFBdUIsRUF5Q3pDO0lBRUQsbURBQW1EO0lBQ25DLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWhFO0lBRUQsNkVBQTZFO0lBQzdELHFCQUFxQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBRXZFO0NBQ0Y7QUFFRCxtRUFBbUU7QUFDbkUsd0JBQXNCLG9CQUFvQixDQUN4QyxTQUFTLEVBQUUsbUJBQW1CLEVBQzlCLFdBQVcsRUFBRSxpQkFBaUIsR0FBRztJQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQTtDQUFFLEVBQzNELFNBQVMsR0FBRSxlQUFzQyxHQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLENBR3pCIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noop_l1_archiver.d.ts","sourceRoot":"","sources":["../../src/test/noop_l1_archiver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,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,
|
|
1
|
+
{"version":3,"file":"noop_l1_archiver.d.ts","sourceRoot":"","sources":["../../src/test/noop_l1_archiver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,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,EAyCzC;IAED,mDAAmD;IACnC,KAAK,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;IAED,6EAA6E;IAC7D,qBAAqB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEvE;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"}
|
|
@@ -42,16 +42,18 @@ import { ArchiverInstrumentation } from '../modules/instrumentation.js';
|
|
|
42
42
|
const events = new EventEmitter();
|
|
43
43
|
const synchronizer = new NoopL1Synchronizer(instrumentation.tracer);
|
|
44
44
|
super(publicClient, debugClient, rollup, {
|
|
45
|
+
rollupAddress: EthAddress.ZERO,
|
|
45
46
|
registryAddress: EthAddress.ZERO,
|
|
47
|
+
inboxAddress: EthAddress.ZERO,
|
|
46
48
|
governanceProposerAddress: EthAddress.ZERO,
|
|
47
|
-
slashFactoryAddress: EthAddress.ZERO,
|
|
48
49
|
slashingProposerAddress: EthAddress.ZERO
|
|
49
50
|
}, dataStore, {
|
|
50
51
|
pollingIntervalMs: 1000,
|
|
51
52
|
batchSize: 100,
|
|
52
53
|
skipValidateCheckpointAttestations: true,
|
|
53
54
|
maxAllowedEthClientDriftSeconds: 300,
|
|
54
|
-
ethereumAllowNoDebugHosts: true
|
|
55
|
+
ethereumAllowNoDebugHosts: true,
|
|
56
|
+
skipHistoricalLogsCheck: true
|
|
55
57
|
}, blobClient, instrumentation, {
|
|
56
58
|
...l1Constants,
|
|
57
59
|
l1StartBlockHash: Buffer32.random()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.f7ea82942",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -65,18 +65,18 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
69
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
70
|
-
"@aztec/constants": "0.0.1-commit.
|
|
71
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
72
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
73
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
74
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
75
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
76
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
77
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
78
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
79
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
68
|
+
"@aztec/blob-client": "0.0.1-commit.f7ea82942",
|
|
69
|
+
"@aztec/blob-lib": "0.0.1-commit.f7ea82942",
|
|
70
|
+
"@aztec/constants": "0.0.1-commit.f7ea82942",
|
|
71
|
+
"@aztec/epoch-cache": "0.0.1-commit.f7ea82942",
|
|
72
|
+
"@aztec/ethereum": "0.0.1-commit.f7ea82942",
|
|
73
|
+
"@aztec/foundation": "0.0.1-commit.f7ea82942",
|
|
74
|
+
"@aztec/kv-store": "0.0.1-commit.f7ea82942",
|
|
75
|
+
"@aztec/l1-artifacts": "0.0.1-commit.f7ea82942",
|
|
76
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.f7ea82942",
|
|
77
|
+
"@aztec/protocol-contracts": "0.0.1-commit.f7ea82942",
|
|
78
|
+
"@aztec/stdlib": "0.0.1-commit.f7ea82942",
|
|
79
|
+
"@aztec/telemetry-client": "0.0.1-commit.f7ea82942",
|
|
80
80
|
"lodash.groupby": "^4.6.0",
|
|
81
81
|
"lodash.omit": "^4.5.0",
|
|
82
82
|
"tslib": "^2.5.0",
|
package/src/archiver.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
11
11
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
12
12
|
import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
13
13
|
import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
|
|
14
|
-
import { DateProvider } from '@aztec/foundation/timer';
|
|
14
|
+
import { DateProvider, elapsed } from '@aztec/foundation/timer';
|
|
15
15
|
import {
|
|
16
16
|
type ArchiverEmitter,
|
|
17
17
|
L2Block,
|
|
@@ -31,6 +31,7 @@ import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@a
|
|
|
31
31
|
|
|
32
32
|
import { type ArchiverConfig, mapArchiverConfig } from './config.js';
|
|
33
33
|
import { BlockAlreadyCheckpointedError, NoBlobBodiesFoundError } from './errors.js';
|
|
34
|
+
import { validateAndLogHistoricalLogsAvailability } from './l1/validate_historical_logs.js';
|
|
34
35
|
import { validateAndLogTraceAvailability } from './l1/validate_trace.js';
|
|
35
36
|
import { ArchiverDataSourceBase } from './modules/data_source_base.js';
|
|
36
37
|
import { ArchiverDataStoreUpdater } from './modules/data_store_updater.js';
|
|
@@ -85,13 +86,15 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
85
86
|
|
|
86
87
|
public readonly tracer: Tracer;
|
|
87
88
|
|
|
89
|
+
private readonly instrumentation: ArchiverInstrumentation;
|
|
90
|
+
|
|
88
91
|
/**
|
|
89
92
|
* Creates a new instance of the Archiver.
|
|
90
93
|
* @param publicClient - A client for interacting with the Ethereum node.
|
|
91
94
|
* @param debugClient - A client for interacting with the Ethereum node for debug/trace methods.
|
|
92
95
|
* @param rollup - Rollup contract instance.
|
|
93
96
|
* @param inbox - Inbox contract instance.
|
|
94
|
-
* @param l1Addresses - L1 contract addresses (registry, governance proposer,
|
|
97
|
+
* @param l1Addresses - L1 contract addresses (registry, governance proposer, slashing proposer).
|
|
95
98
|
* @param dataStore - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
|
|
96
99
|
* @param config - Archiver configuration options.
|
|
97
100
|
* @param blobClient - Client for retrieving blob data.
|
|
@@ -106,8 +109,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
106
109
|
private readonly rollup: RollupContract,
|
|
107
110
|
private readonly l1Addresses: Pick<
|
|
108
111
|
L1ContractAddresses,
|
|
109
|
-
'registryAddress' | '
|
|
110
|
-
> & {
|
|
112
|
+
'rollupAddress' | 'registryAddress' | 'inboxAddress' | 'governanceProposerAddress'
|
|
113
|
+
> & {
|
|
114
|
+
slashingProposerAddress: EthAddress;
|
|
115
|
+
},
|
|
111
116
|
readonly dataStore: KVArchiverDataStore,
|
|
112
117
|
private config: {
|
|
113
118
|
pollingIntervalMs: number;
|
|
@@ -115,6 +120,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
115
120
|
skipValidateCheckpointAttestations?: boolean;
|
|
116
121
|
maxAllowedEthClientDriftSeconds: number;
|
|
117
122
|
ethereumAllowNoDebugHosts?: boolean;
|
|
123
|
+
skipHistoricalLogsCheck?: boolean;
|
|
118
124
|
},
|
|
119
125
|
private readonly blobClient: BlobClientInterface,
|
|
120
126
|
instrumentation: ArchiverInstrumentation,
|
|
@@ -130,6 +136,7 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
130
136
|
super(dataStore, l1Constants);
|
|
131
137
|
|
|
132
138
|
this.tracer = instrumentation.tracer;
|
|
139
|
+
this.instrumentation = instrumentation;
|
|
133
140
|
this.initialSyncPromise = promiseWithResolvers();
|
|
134
141
|
this.synchronizer = synchronizer;
|
|
135
142
|
this.events = events;
|
|
@@ -170,6 +177,17 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
170
177
|
this.config.ethereumAllowNoDebugHosts ?? false,
|
|
171
178
|
this.log.getBindings(),
|
|
172
179
|
);
|
|
180
|
+
await validateAndLogHistoricalLogsAvailability(
|
|
181
|
+
this.publicClient,
|
|
182
|
+
{
|
|
183
|
+
rollupAddress: this.l1Addresses.rollupAddress,
|
|
184
|
+
inboxAddress: this.l1Addresses.inboxAddress,
|
|
185
|
+
registryAddress: this.l1Addresses.registryAddress,
|
|
186
|
+
governanceProposerAddress: this.l1Addresses.governanceProposerAddress,
|
|
187
|
+
},
|
|
188
|
+
this.config.skipHistoricalLogsCheck ?? false,
|
|
189
|
+
this.log.getBindings(),
|
|
190
|
+
);
|
|
173
191
|
|
|
174
192
|
// Log initial state for the archiver
|
|
175
193
|
const { l1StartBlock } = this.l1Constants;
|
|
@@ -245,7 +263,8 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
245
263
|
}
|
|
246
264
|
|
|
247
265
|
try {
|
|
248
|
-
await this.updater.addProposedBlock(block);
|
|
266
|
+
const [durationMs] = await elapsed(() => this.updater.addProposedBlock(block));
|
|
267
|
+
this.instrumentation.processNewProposedBlock(durationMs, block);
|
|
249
268
|
this.log.debug(`Added block ${block.number} to store`);
|
|
250
269
|
resolve();
|
|
251
270
|
} catch (err: any) {
|
|
@@ -490,7 +509,10 @@ export class Archiver extends ArchiverDataSourceBase implements L2BlockSink, Tra
|
|
|
490
509
|
await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
491
510
|
this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
|
|
492
511
|
await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
|
|
493
|
-
await this.store.
|
|
512
|
+
await this.store.setMessageSyncState(
|
|
513
|
+
{ l1BlockNumber: targetL1BlockNumber, l1BlockHash: targetL1BlockHash },
|
|
514
|
+
undefined,
|
|
515
|
+
);
|
|
494
516
|
if (targetL2BlockNumber < currentProvenBlock) {
|
|
495
517
|
this.log.info(`Rolling back proven L2 checkpoint to ${targetCheckpointNumber}`);
|
|
496
518
|
await this.updater.setProvenCheckpointNumber(targetCheckpointNumber);
|
package/src/config.ts
CHANGED
|
@@ -50,13 +50,17 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
|
|
|
50
50
|
},
|
|
51
51
|
archiverStoreMapSizeKb: {
|
|
52
52
|
env: 'ARCHIVER_STORE_MAP_SIZE_KB',
|
|
53
|
-
parseEnv: (val: string
|
|
53
|
+
parseEnv: (val: string) => +val,
|
|
54
54
|
description: 'The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKb.',
|
|
55
55
|
},
|
|
56
56
|
skipValidateCheckpointAttestations: {
|
|
57
57
|
description: 'Skip validating checkpoint attestations (for testing purposes only)',
|
|
58
58
|
...booleanConfigHelper(false),
|
|
59
59
|
},
|
|
60
|
+
skipPromoteProposedCheckpointDuringL1Sync: {
|
|
61
|
+
description: 'Skip promoting proposed checkpoints during L1 sync (for testing purposes only)',
|
|
62
|
+
...booleanConfigHelper(false),
|
|
63
|
+
},
|
|
60
64
|
maxAllowedEthClientDriftSeconds: {
|
|
61
65
|
env: 'MAX_ALLOWED_ETH_CLIENT_DRIFT_SECONDS',
|
|
62
66
|
description: 'Maximum allowed drift in seconds between the Ethereum client and current time.',
|
|
@@ -67,6 +71,13 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
|
|
|
67
71
|
description: 'Whether to allow starting the archiver without debug/trace method support on Ethereum hosts',
|
|
68
72
|
...booleanConfigHelper(true),
|
|
69
73
|
},
|
|
74
|
+
archiverSkipHistoricalLogsCheck: {
|
|
75
|
+
env: 'ARCHIVER_SKIP_HISTORICAL_LOGS_CHECK',
|
|
76
|
+
description:
|
|
77
|
+
'Skip the startup check that probes the L1 RPC for historical Rollup contract logs. ' +
|
|
78
|
+
'Set to true to bypass the check when the connected RPC node is known to prune old logs.',
|
|
79
|
+
...booleanConfigHelper(false),
|
|
80
|
+
},
|
|
70
81
|
...chainConfigMappings,
|
|
71
82
|
...l1ReaderConfigMappings,
|
|
72
83
|
viemPollingIntervalMS: {
|
|
@@ -96,7 +107,9 @@ export function mapArchiverConfig(config: Partial<ArchiverConfig>) {
|
|
|
96
107
|
pollingIntervalMs: config.archiverPollingIntervalMS,
|
|
97
108
|
batchSize: config.archiverBatchSize,
|
|
98
109
|
skipValidateCheckpointAttestations: config.skipValidateCheckpointAttestations,
|
|
110
|
+
skipPromoteProposedCheckpointDuringL1Sync: config.skipPromoteProposedCheckpointDuringL1Sync,
|
|
99
111
|
maxAllowedEthClientDriftSeconds: config.maxAllowedEthClientDriftSeconds,
|
|
100
112
|
ethereumAllowNoDebugHosts: config.ethereumAllowNoDebugHosts,
|
|
113
|
+
skipHistoricalLogsCheck: config.archiverSkipHistoricalLogsCheck,
|
|
101
114
|
};
|
|
102
115
|
}
|
package/src/errors.ts
CHANGED
|
@@ -132,6 +132,40 @@ export class ProposedCheckpointNotSequentialError extends Error {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/** Thrown when attempting to promote a proposed checkpoint but no proposed checkpoint exists in the store. */
|
|
136
|
+
export class NoProposedCheckpointToPromoteError extends Error {
|
|
137
|
+
constructor() {
|
|
138
|
+
super('Cannot promote proposed checkpoint: no proposed checkpoint exists');
|
|
139
|
+
this.name = 'NoProposedCheckpointToPromoteError';
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Thrown when the archive root of the proposed checkpoint does not match the expected one. */
|
|
144
|
+
export class ProposedCheckpointArchiveRootMismatchError extends Error {
|
|
145
|
+
constructor(
|
|
146
|
+
public readonly expectedArchiveRoot: Fr,
|
|
147
|
+
public readonly actualArchiveRoot: Fr,
|
|
148
|
+
) {
|
|
149
|
+
super(
|
|
150
|
+
`Cannot promote proposed checkpoint: archive root mismatch (expected ${expectedArchiveRoot}, got ${actualArchiveRoot})`,
|
|
151
|
+
);
|
|
152
|
+
this.name = 'ProposedCheckpointArchiveRootMismatchError';
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Thrown when the proposed checkpoint does not directly follow the latest confirmed checkpoint. */
|
|
157
|
+
export class ProposedCheckpointPromotionNotSequentialError extends Error {
|
|
158
|
+
constructor(
|
|
159
|
+
public readonly proposedCheckpointNumber: number,
|
|
160
|
+
public readonly latestCheckpointNumber: number,
|
|
161
|
+
) {
|
|
162
|
+
super(
|
|
163
|
+
`Cannot promote proposed checkpoint: not sequential (latest ${latestCheckpointNumber}, proposed ${proposedCheckpointNumber})`,
|
|
164
|
+
);
|
|
165
|
+
this.name = 'ProposedCheckpointPromotionNotSequentialError';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
135
169
|
/** Thrown when a proposed block conflicts with an already checkpointed block (different content). */
|
|
136
170
|
export class CannotOverwriteCheckpointedBlockError extends Error {
|
|
137
171
|
constructor(
|
package/src/factory.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -10,4 +10,5 @@ export { KVArchiverDataStore, ARCHIVER_DB_VERSION } from './store/kv_archiver_st
|
|
|
10
10
|
export { ContractInstanceStore } from './store/contract_instance_store.js';
|
|
11
11
|
export { L2TipsCache } from './store/l2_tips_cache.js';
|
|
12
12
|
|
|
13
|
-
export {
|
|
13
|
+
export { retrieveL2ProofVerifiedEvents } from './l1/data_retrieval.js';
|
|
14
|
+
export { CalldataRetriever } from './l1/calldata_retriever.js';
|
package/src/l1/data_retrieval.ts
CHANGED
|
@@ -35,18 +35,28 @@ import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
|
35
35
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
36
36
|
import { CalldataRetriever } from './calldata_retriever.js';
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
type RetrievedCheckpointBase = {
|
|
39
39
|
checkpointNumber: CheckpointNumber;
|
|
40
40
|
archiveRoot: Fr;
|
|
41
41
|
feeAssetPriceModifier: bigint;
|
|
42
42
|
header: CheckpointHeader;
|
|
43
|
-
checkpointBlobData: CheckpointBlobData;
|
|
44
43
|
l1: L1PublishedData;
|
|
45
44
|
chainId: Fr;
|
|
46
45
|
version: Fr;
|
|
47
46
|
attestations: CommitteeAttestation[];
|
|
48
47
|
};
|
|
49
48
|
|
|
49
|
+
/** Checkpoint data as retrieved from L1 calldata and blob data. */
|
|
50
|
+
export type RetrievedCheckpoint = RetrievedCheckpointBase & { checkpointBlobData: CheckpointBlobData };
|
|
51
|
+
|
|
52
|
+
/** Checkpoint data retrieved from L1 calldata only, without blob data. */
|
|
53
|
+
export type RetrievedCheckpointFromCalldata = RetrievedCheckpointBase & {
|
|
54
|
+
/** Versioned blob hashes from the checkpoint proposed event. */
|
|
55
|
+
blobHashes: Buffer[];
|
|
56
|
+
/** Parent beacon block root from the L1 block, used for blob fetching. */
|
|
57
|
+
parentBeaconBlockRoot: string | undefined;
|
|
58
|
+
};
|
|
59
|
+
|
|
50
60
|
export async function retrievedToPublishedCheckpoint({
|
|
51
61
|
checkpointNumber,
|
|
52
62
|
archiveRoot,
|
|
@@ -137,31 +147,27 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
/**
|
|
140
|
-
* Fetches
|
|
150
|
+
* Fetches checkpoint calldata from the rollup contract without fetching blob data.
|
|
151
|
+
* Returns RetrievedCheckpointFromCalldata objects that preserve the information needed for deferred blob fetching.
|
|
141
152
|
* @param rollup - The rollup contract wrapper.
|
|
142
153
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
143
154
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
144
|
-
* @param blobClient - The blob client client for fetching blob data.
|
|
145
155
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
146
156
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
147
|
-
* @param contractAddresses - The contract addresses (governanceProposerAddress, slashFactoryAddress, slashingProposerAddress).
|
|
148
157
|
* @param instrumentation - The archiver instrumentation instance.
|
|
149
158
|
* @param logger - The logger instance.
|
|
150
|
-
* @
|
|
151
|
-
* @returns An array of retrieved checkpoints.
|
|
159
|
+
* @returns An array of calldata-only checkpoints.
|
|
152
160
|
*/
|
|
153
|
-
export async function
|
|
161
|
+
export async function retrieveCheckpointCalldataFromRollup(
|
|
154
162
|
rollup: RollupContract,
|
|
155
163
|
publicClient: ViemPublicClient,
|
|
156
164
|
debugClient: ViemPublicDebugClient,
|
|
157
|
-
blobClient: BlobClientInterface,
|
|
158
165
|
searchStartBlock: bigint,
|
|
159
166
|
searchEndBlock: bigint,
|
|
160
167
|
instrumentation: ArchiverInstrumentation,
|
|
161
168
|
logger: Logger = createLogger('archiver'),
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const retrievedCheckpoints: RetrievedCheckpoint[] = [];
|
|
169
|
+
): Promise<RetrievedCheckpointFromCalldata[]> {
|
|
170
|
+
const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
|
|
165
171
|
|
|
166
172
|
let rollupConstants: { chainId: Fr; version: Fr; targetCommitteeSize: number } | undefined;
|
|
167
173
|
|
|
@@ -197,46 +203,39 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
197
203
|
rollup,
|
|
198
204
|
publicClient,
|
|
199
205
|
debugClient,
|
|
200
|
-
blobClient,
|
|
201
206
|
checkpointProposedLogs,
|
|
202
207
|
rollupConstants,
|
|
203
208
|
instrumentation,
|
|
204
209
|
logger,
|
|
205
|
-
isHistoricalSync,
|
|
206
210
|
);
|
|
207
211
|
retrievedCheckpoints.push(...newCheckpoints);
|
|
208
212
|
searchStartBlock = lastLog.l1BlockNumber + 1n;
|
|
209
213
|
} while (searchStartBlock <= searchEndBlock);
|
|
210
214
|
|
|
211
|
-
// The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
|
|
212
215
|
return retrievedCheckpoints.sort((a, b) => Number(a.l1.blockNumber - b.l1.blockNumber));
|
|
213
216
|
}
|
|
214
217
|
|
|
215
218
|
/**
|
|
216
|
-
* Processes
|
|
219
|
+
* Processes CheckpointProposed logs, fetching only calldata (no blobs).
|
|
217
220
|
* @param rollup - The rollup contract wrapper.
|
|
218
221
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
219
222
|
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
220
|
-
* @param blobClient - The blob client client for fetching blob data.
|
|
221
223
|
* @param logs - CheckpointProposed logs.
|
|
222
224
|
* @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
|
|
223
225
|
* @param instrumentation - The archiver instrumentation instance.
|
|
224
226
|
* @param logger - The logger instance.
|
|
225
|
-
* @
|
|
226
|
-
* @returns An array of retrieved checkpoints.
|
|
227
|
+
* @returns An array of calldata-only checkpoints.
|
|
227
228
|
*/
|
|
228
229
|
async function processCheckpointProposedLogs(
|
|
229
230
|
rollup: RollupContract,
|
|
230
231
|
publicClient: ViemPublicClient,
|
|
231
232
|
debugClient: ViemPublicDebugClient,
|
|
232
|
-
blobClient: BlobClientInterface,
|
|
233
233
|
logs: CheckpointProposedLog[],
|
|
234
234
|
{ chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
|
|
235
235
|
instrumentation: ArchiverInstrumentation,
|
|
236
236
|
logger: Logger,
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const retrievedCheckpoints: RetrievedCheckpoint[] = [];
|
|
237
|
+
): Promise<RetrievedCheckpointFromCalldata[]> {
|
|
238
|
+
const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
|
|
240
239
|
const calldataRetriever = new CalldataRetriever(
|
|
241
240
|
publicClient,
|
|
242
241
|
debugClient,
|
|
@@ -252,7 +251,6 @@ async function processCheckpointProposedLogs(
|
|
|
252
251
|
const archiveFromChain = await rollup.archiveAt(checkpointNumber);
|
|
253
252
|
const blobHashes = log.args.versionedBlobHashes;
|
|
254
253
|
|
|
255
|
-
// The value from the event and contract will match only if the checkpoint is in the chain.
|
|
256
254
|
if (archive.equals(archiveFromChain)) {
|
|
257
255
|
const expectedHashes = {
|
|
258
256
|
attestationsHash: log.args.attestationsHash.toString() as Hex,
|
|
@@ -268,19 +266,16 @@ async function processCheckpointProposedLogs(
|
|
|
268
266
|
const { timestamp, parentBeaconBlockRoot } = await getL1Block(publicClient, log.l1BlockNumber);
|
|
269
267
|
const l1 = new L1PublishedData(log.l1BlockNumber, timestamp, log.l1BlockHash.toString());
|
|
270
268
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
retrievedCheckpoints.push({
|
|
270
|
+
...checkpoint,
|
|
271
|
+
l1,
|
|
272
|
+
chainId,
|
|
273
|
+
version,
|
|
274
274
|
blobHashes,
|
|
275
|
-
checkpointNumber,
|
|
276
|
-
logger,
|
|
277
|
-
isHistoricalSync,
|
|
278
275
|
parentBeaconBlockRoot,
|
|
279
|
-
|
|
280
|
-
);
|
|
276
|
+
});
|
|
281
277
|
|
|
282
|
-
|
|
283
|
-
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
|
|
278
|
+
logger.trace(`Retrieved checkpoint calldata ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
|
|
284
279
|
l1BlockNumber: log.l1BlockNumber,
|
|
285
280
|
checkpointNumber,
|
|
286
281
|
archive: archive.toString(),
|
|
@@ -344,14 +339,10 @@ export async function getCheckpointBlobDataFromBlobs(
|
|
|
344
339
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
|
345
340
|
export async function retrieveL1ToL2Message(
|
|
346
341
|
inbox: InboxContract,
|
|
347
|
-
|
|
348
|
-
fromBlock: bigint,
|
|
349
|
-
toBlock: bigint,
|
|
342
|
+
message: InboxMessage,
|
|
350
343
|
): Promise<InboxMessage | undefined> {
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
const messages = mapLogsInboxMessage(logs);
|
|
354
|
-
return messages.length > 0 ? messages[0] : undefined;
|
|
344
|
+
const log = await inbox.getMessageSentEventByHash(message.leaf.toString(), message.l1BlockNumber);
|
|
345
|
+
return log && mapLogInboxMessage(log);
|
|
355
346
|
}
|
|
356
347
|
|
|
357
348
|
/**
|
|
@@ -374,22 +365,22 @@ export async function retrieveL1ToL2Messages(
|
|
|
374
365
|
break;
|
|
375
366
|
}
|
|
376
367
|
|
|
377
|
-
retrievedL1ToL2Messages.push(...
|
|
368
|
+
retrievedL1ToL2Messages.push(...messageSentLogs.map(mapLogInboxMessage));
|
|
378
369
|
searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
|
|
379
370
|
}
|
|
380
371
|
|
|
381
372
|
return retrievedL1ToL2Messages;
|
|
382
373
|
}
|
|
383
374
|
|
|
384
|
-
function
|
|
385
|
-
return
|
|
375
|
+
function mapLogInboxMessage(log: MessageSentLog): InboxMessage {
|
|
376
|
+
return {
|
|
386
377
|
index: log.args.index,
|
|
387
378
|
leaf: log.args.leaf,
|
|
388
379
|
l1BlockNumber: log.l1BlockNumber,
|
|
389
380
|
l1BlockHash: log.l1BlockHash,
|
|
390
381
|
checkpointNumber: log.args.checkpointNumber,
|
|
391
382
|
rollingHash: log.args.rollingHash,
|
|
392
|
-
}
|
|
383
|
+
};
|
|
393
384
|
}
|
|
394
385
|
|
|
395
386
|
/** Retrieves L2ProofVerified events from the rollup contract. */
|