@aztec/archiver 0.0.1-commit.0b941701 → 0.0.1-commit.10bd49492
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 -5
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +76 -111
- package/dest/errors.d.ts +7 -9
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +9 -14
- package/dest/factory.d.ts +5 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +17 -16
- 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 +13 -8
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +29 -73
- package/dest/modules/data_store_updater.d.ts +22 -7
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +69 -29
- 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 +43 -13
- package/dest/store/block_store.d.ts +32 -29
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +132 -80
- 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 +37 -14
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +41 -12
- 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 +57 -37
- package/dest/store/message_store.js +1 -1
- package/dest/test/fake_l1_state.d.ts +13 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +84 -20
- 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 +25 -9
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +133 -87
- 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 +26 -0
- package/dest/test/noop_l1_archiver.d.ts.map +1 -0
- package/dest/test/noop_l1_archiver.js +72 -0
- package/package.json +14 -13
- package/src/archiver.ts +96 -132
- package/src/errors.ts +10 -24
- package/src/factory.ts +32 -17
- package/src/index.ts +1 -0
- package/src/l1/README.md +25 -68
- package/src/l1/bin/retrieve-calldata.ts +46 -39
- package/src/l1/calldata_retriever.ts +249 -379
- package/src/l1/data_retrieval.ts +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 +59 -98
- package/src/modules/data_store_updater.ts +71 -30
- package/src/modules/instrumentation.ts +44 -12
- package/src/modules/l1_synchronizer.ts +48 -17
- package/src/store/block_store.ts +162 -110
- package/src/store/contract_class_store.ts +11 -7
- package/src/store/kv_archiver_store.ts +67 -17
- package/src/store/l2_tips_cache.ts +89 -0
- package/src/store/log_store.ts +98 -36
- package/src/store/message_store.ts +1 -1
- package/src/test/fake_l1_state.ts +110 -21
- package/src/test/index.ts +3 -0
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l2_block_source.ts +179 -87
- package/src/test/mock_structs.ts +42 -12
- package/src/test/noop_l1_archiver.ts +115 -0
|
@@ -6,8 +6,14 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
6
6
|
import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
|
|
7
7
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
type BlockData,
|
|
11
|
+
BlockHash,
|
|
12
|
+
CheckpointedL2Block,
|
|
13
|
+
L2Block,
|
|
14
|
+
type ValidateCheckpointResult,
|
|
15
|
+
} from '@aztec/stdlib/block';
|
|
16
|
+
import type { CheckpointData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
17
|
import type {
|
|
12
18
|
ContractClassPublic,
|
|
13
19
|
ContractDataSource,
|
|
@@ -25,7 +31,7 @@ import type { UInt64 } from '@aztec/stdlib/types';
|
|
|
25
31
|
import { join } from 'path';
|
|
26
32
|
|
|
27
33
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
28
|
-
import { BlockStore, type
|
|
34
|
+
import { BlockStore, type RemoveCheckpointsResult } from './block_store.js';
|
|
29
35
|
import { ContractClassStore } from './contract_class_store.js';
|
|
30
36
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
31
37
|
import { LogStore } from './log_store.js';
|
|
@@ -65,15 +71,19 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
65
71
|
constructor(
|
|
66
72
|
private db: AztecAsyncKVStore,
|
|
67
73
|
logsMaxPageSize: number = 1000,
|
|
68
|
-
l1Constants: Pick<L1RollupConstants, 'epochDuration'>,
|
|
69
74
|
) {
|
|
70
|
-
this.#blockStore = new BlockStore(db
|
|
75
|
+
this.#blockStore = new BlockStore(db);
|
|
71
76
|
this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
|
|
72
77
|
this.#messageStore = new MessageStore(db);
|
|
73
78
|
this.#contractClassStore = new ContractClassStore(db);
|
|
74
79
|
this.#contractInstanceStore = new ContractInstanceStore(db);
|
|
75
80
|
}
|
|
76
81
|
|
|
82
|
+
/** Returns the underlying block store. Used by L2TipsCache. */
|
|
83
|
+
get blockStore(): BlockStore {
|
|
84
|
+
return this.#blockStore;
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
/** Opens a new transaction to the underlying store and runs all operations within it. */
|
|
78
88
|
public transactionAsync<T>(callback: () => Promise<T>): Promise<T> {
|
|
79
89
|
return this.db.transactionAsync(callback);
|
|
@@ -235,14 +245,14 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
235
245
|
}
|
|
236
246
|
|
|
237
247
|
/**
|
|
238
|
-
* Append new proposed
|
|
239
|
-
*
|
|
248
|
+
* Append a new proposed block to the store.
|
|
249
|
+
* This is an uncheckpointed block that has been proposed by the sequencer but not yet included in a checkpoint on L1.
|
|
240
250
|
* For checkpointed blocks (already published to L1), use addCheckpoints() instead.
|
|
241
|
-
* @param
|
|
251
|
+
* @param block - The proposed L2 block to be added to the store.
|
|
242
252
|
* @returns True if the operation is successful.
|
|
243
253
|
*/
|
|
244
|
-
|
|
245
|
-
return this.#blockStore.
|
|
254
|
+
addProposedBlock(block: L2Block, opts: { force?: boolean } = {}): Promise<boolean> {
|
|
255
|
+
return this.#blockStore.addProposedBlock(block, opts);
|
|
246
256
|
}
|
|
247
257
|
|
|
248
258
|
/**
|
|
@@ -291,7 +301,7 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
291
301
|
* Returns the block for the given hash, or undefined if not exists.
|
|
292
302
|
* @param blockHash - The block hash to return.
|
|
293
303
|
*/
|
|
294
|
-
getCheckpointedBlockByHash(blockHash:
|
|
304
|
+
getCheckpointedBlockByHash(blockHash: BlockHash): Promise<CheckpointedL2Block | undefined> {
|
|
295
305
|
return this.#blockStore.getCheckpointedBlockByHash(blockHash);
|
|
296
306
|
}
|
|
297
307
|
/**
|
|
@@ -312,8 +322,8 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
312
322
|
* Returns the block for the given hash, or undefined if not exists.
|
|
313
323
|
* @param blockHash - The block hash to return.
|
|
314
324
|
*/
|
|
315
|
-
getBlockByHash(blockHash:
|
|
316
|
-
return this.#blockStore.getBlockByHash(
|
|
325
|
+
getBlockByHash(blockHash: BlockHash): Promise<L2Block | undefined> {
|
|
326
|
+
return this.#blockStore.getBlockByHash(blockHash);
|
|
317
327
|
}
|
|
318
328
|
/**
|
|
319
329
|
* Returns the block for the given archive root, or undefined if not exists.
|
|
@@ -357,8 +367,8 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
357
367
|
* Returns the block header for the given hash, or undefined if not exists.
|
|
358
368
|
* @param blockHash - The block hash to return.
|
|
359
369
|
*/
|
|
360
|
-
getBlockHeaderByHash(blockHash:
|
|
361
|
-
return this.#blockStore.getBlockHeaderByHash(
|
|
370
|
+
getBlockHeaderByHash(blockHash: BlockHash): Promise<BlockHeader | undefined> {
|
|
371
|
+
return this.#blockStore.getBlockHeaderByHash(blockHash);
|
|
362
372
|
}
|
|
363
373
|
|
|
364
374
|
/**
|
|
@@ -369,6 +379,22 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
369
379
|
return this.#blockStore.getBlockHeaderByArchive(archive);
|
|
370
380
|
}
|
|
371
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Gets block metadata (without tx data) by block number.
|
|
384
|
+
* @param blockNumber - The block number to return.
|
|
385
|
+
*/
|
|
386
|
+
getBlockData(blockNumber: BlockNumber): Promise<BlockData | undefined> {
|
|
387
|
+
return this.#blockStore.getBlockData(blockNumber);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Gets block metadata (without tx data) by archive root.
|
|
392
|
+
* @param archive - The archive root to return.
|
|
393
|
+
*/
|
|
394
|
+
getBlockDataByArchive(archive: Fr): Promise<BlockData | undefined> {
|
|
395
|
+
return this.#blockStore.getBlockDataByArchive(archive);
|
|
396
|
+
}
|
|
397
|
+
|
|
372
398
|
/**
|
|
373
399
|
* Gets a tx effect.
|
|
374
400
|
* @param txHash - The hash of the tx corresponding to the tx effect.
|
|
@@ -383,8 +409,11 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
383
409
|
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
384
410
|
* @returns The requested tx receipt (or undefined if not found).
|
|
385
411
|
*/
|
|
386
|
-
getSettledTxReceipt(
|
|
387
|
-
|
|
412
|
+
getSettledTxReceipt(
|
|
413
|
+
txHash: TxHash,
|
|
414
|
+
l1Constants?: Pick<L1RollupConstants, 'epochDuration'>,
|
|
415
|
+
): Promise<TxReceipt | undefined> {
|
|
416
|
+
return this.#blockStore.getSettledTxReceipt(txHash, l1Constants);
|
|
388
417
|
}
|
|
389
418
|
|
|
390
419
|
/**
|
|
@@ -515,6 +544,22 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
515
544
|
await this.#blockStore.setProvenCheckpointNumber(checkpointNumber);
|
|
516
545
|
}
|
|
517
546
|
|
|
547
|
+
/**
|
|
548
|
+
* Gets the number of the latest finalized checkpoint processed.
|
|
549
|
+
* @returns The number of the latest finalized checkpoint processed.
|
|
550
|
+
*/
|
|
551
|
+
getFinalizedCheckpointNumber(): Promise<CheckpointNumber> {
|
|
552
|
+
return this.#blockStore.getFinalizedCheckpointNumber();
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Stores the number of the latest finalized checkpoint processed.
|
|
557
|
+
* @param checkpointNumber - The number of the latest finalized checkpoint processed.
|
|
558
|
+
*/
|
|
559
|
+
async setFinalizedCheckpointNumber(checkpointNumber: CheckpointNumber) {
|
|
560
|
+
await this.#blockStore.setFinalizedCheckpointNumber(checkpointNumber);
|
|
561
|
+
}
|
|
562
|
+
|
|
518
563
|
async setBlockSynchedL1BlockNumber(l1BlockNumber: bigint) {
|
|
519
564
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
520
565
|
}
|
|
@@ -618,6 +663,11 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
618
663
|
return this.#blockStore.getCheckpointData(checkpointNumber);
|
|
619
664
|
}
|
|
620
665
|
|
|
666
|
+
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */
|
|
667
|
+
getCheckpointDataForSlotRange(startSlot: SlotNumber, endSlot: SlotNumber): Promise<CheckpointData[]> {
|
|
668
|
+
return this.#blockStore.getCheckpointDataForSlotRange(startSlot, endSlot);
|
|
669
|
+
}
|
|
670
|
+
|
|
621
671
|
/**
|
|
622
672
|
* Gets all blocks that have the given slot number.
|
|
623
673
|
* @param slotNumber - The slot number to search for.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
|
+
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { type BlockData, type CheckpointId, GENESIS_CHECKPOINT_HEADER_HASH, type L2Tips } from '@aztec/stdlib/block';
|
|
4
|
+
|
|
5
|
+
import type { BlockStore } from './block_store.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* In-memory cache for L2 chain tips (proposed, checkpointed, proven, finalized).
|
|
9
|
+
* Populated from the BlockStore on first access, then kept up-to-date by the ArchiverDataStoreUpdater.
|
|
10
|
+
* Refresh calls should happen within the store transaction that mutates block data to ensure consistency.
|
|
11
|
+
*/
|
|
12
|
+
export class L2TipsCache {
|
|
13
|
+
#tipsPromise: Promise<L2Tips> | undefined;
|
|
14
|
+
|
|
15
|
+
constructor(private blockStore: BlockStore) {}
|
|
16
|
+
|
|
17
|
+
/** Returns the cached L2 tips. Loads from the block store on first call. */
|
|
18
|
+
public getL2Tips(): Promise<L2Tips> {
|
|
19
|
+
return (this.#tipsPromise ??= this.loadFromStore());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Reloads the L2 tips from the block store. Should be called within the store transaction that mutates data. */
|
|
23
|
+
public async refresh(): Promise<void> {
|
|
24
|
+
this.#tipsPromise = this.loadFromStore();
|
|
25
|
+
await this.#tipsPromise;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private async loadFromStore(): Promise<L2Tips> {
|
|
29
|
+
const [latestBlockNumber, provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber] = await Promise.all([
|
|
30
|
+
this.blockStore.getLatestBlockNumber(),
|
|
31
|
+
this.blockStore.getProvenBlockNumber(),
|
|
32
|
+
this.blockStore.getCheckpointedL2BlockNumber(),
|
|
33
|
+
this.blockStore.getFinalizedL2BlockNumber(),
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const genesisBlockHeader = {
|
|
37
|
+
blockHash: GENESIS_BLOCK_HEADER_HASH,
|
|
38
|
+
checkpointNumber: CheckpointNumber.ZERO,
|
|
39
|
+
} as const;
|
|
40
|
+
const beforeInitialBlockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
41
|
+
|
|
42
|
+
const getBlockData = (blockNumber: BlockNumber) =>
|
|
43
|
+
blockNumber > beforeInitialBlockNumber ? this.blockStore.getBlockData(blockNumber) : genesisBlockHeader;
|
|
44
|
+
|
|
45
|
+
const [latestBlockData, provenBlockData, checkpointedBlockData, finalizedBlockData] = await Promise.all(
|
|
46
|
+
[latestBlockNumber, provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber].map(getBlockData),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
if (!latestBlockData || !provenBlockData || !finalizedBlockData || !checkpointedBlockData) {
|
|
50
|
+
throw new Error('Failed to load block data for L2 tips');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const [provenCheckpointId, finalizedCheckpointId, checkpointedCheckpointId] = await Promise.all([
|
|
54
|
+
this.getCheckpointIdForBlock(provenBlockData),
|
|
55
|
+
this.getCheckpointIdForBlock(finalizedBlockData),
|
|
56
|
+
this.getCheckpointIdForBlock(checkpointedBlockData),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
proposed: { number: latestBlockNumber, hash: latestBlockData.blockHash.toString() },
|
|
61
|
+
proven: {
|
|
62
|
+
block: { number: provenBlockNumber, hash: provenBlockData.blockHash.toString() },
|
|
63
|
+
checkpoint: provenCheckpointId,
|
|
64
|
+
},
|
|
65
|
+
finalized: {
|
|
66
|
+
block: { number: finalizedBlockNumber, hash: finalizedBlockData.blockHash.toString() },
|
|
67
|
+
checkpoint: finalizedCheckpointId,
|
|
68
|
+
},
|
|
69
|
+
checkpointed: {
|
|
70
|
+
block: { number: checkpointedBlockNumber, hash: checkpointedBlockData.blockHash.toString() },
|
|
71
|
+
checkpoint: checkpointedCheckpointId,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async getCheckpointIdForBlock(blockData: Pick<BlockData, 'checkpointNumber'>): Promise<CheckpointId> {
|
|
77
|
+
const checkpointData = await this.blockStore.getCheckpointData(blockData.checkpointNumber);
|
|
78
|
+
if (!checkpointData) {
|
|
79
|
+
return {
|
|
80
|
+
number: CheckpointNumber.ZERO,
|
|
81
|
+
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
number: checkpointData.checkpointNumber,
|
|
86
|
+
hash: checkpointData.header.hash().toString(),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/store/log_store.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
6
6
|
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
|
|
7
7
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
8
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import {
|
|
9
|
+
import { BlockHash, L2Block } from '@aztec/stdlib/block';
|
|
10
10
|
import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
|
|
11
11
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
12
12
|
import {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
Tag,
|
|
21
21
|
TxScopedL2Log,
|
|
22
22
|
} from '@aztec/stdlib/logs';
|
|
23
|
+
import { TxHash } from '@aztec/stdlib/tx';
|
|
23
24
|
|
|
24
25
|
import type { BlockStore } from './block_store.js';
|
|
25
26
|
|
|
@@ -219,6 +220,7 @@ export class LogStore {
|
|
|
219
220
|
.map((txEffect, txIndex) =>
|
|
220
221
|
[
|
|
221
222
|
numToUInt32BE(txIndex),
|
|
223
|
+
txEffect.txHash.toBuffer(),
|
|
222
224
|
numToUInt32BE(txEffect.publicLogs.length),
|
|
223
225
|
txEffect.publicLogs.map(log => log.toBuffer()),
|
|
224
226
|
].flat(),
|
|
@@ -242,6 +244,7 @@ export class LogStore {
|
|
|
242
244
|
.map((txEffect, txIndex) =>
|
|
243
245
|
[
|
|
244
246
|
numToUInt32BE(txIndex),
|
|
247
|
+
txEffect.txHash.toBuffer(),
|
|
245
248
|
numToUInt32BE(txEffect.contractClassLogs.length),
|
|
246
249
|
txEffect.contractClassLogs.map(log => log.toBuffer()),
|
|
247
250
|
].flat(),
|
|
@@ -271,18 +274,18 @@ export class LogStore {
|
|
|
271
274
|
});
|
|
272
275
|
}
|
|
273
276
|
|
|
274
|
-
#packWithBlockHash(blockHash:
|
|
277
|
+
#packWithBlockHash(blockHash: BlockHash, data: Buffer<ArrayBufferLike>[]): Buffer<ArrayBufferLike> {
|
|
275
278
|
return Buffer.concat([blockHash.toBuffer(), ...data]);
|
|
276
279
|
}
|
|
277
280
|
|
|
278
|
-
#unpackBlockHash(reader: BufferReader):
|
|
281
|
+
#unpackBlockHash(reader: BufferReader): BlockHash {
|
|
279
282
|
const blockHash = reader.remainingBytes() > 0 ? reader.readObject(Fr) : undefined;
|
|
280
283
|
|
|
281
284
|
if (!blockHash) {
|
|
282
285
|
throw new Error('Failed to read block hash from log entry buffer');
|
|
283
286
|
}
|
|
284
287
|
|
|
285
|
-
return
|
|
288
|
+
return new BlockHash(blockHash);
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
deleteLogs(blocks: L2Block[]): Promise<boolean> {
|
|
@@ -386,24 +389,33 @@ export class LogStore {
|
|
|
386
389
|
}
|
|
387
390
|
|
|
388
391
|
const buffer = (await this.#publicLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
|
|
389
|
-
const publicLogsInBlock:
|
|
392
|
+
const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
|
|
390
393
|
const reader = new BufferReader(buffer);
|
|
391
394
|
|
|
392
395
|
const blockHash = this.#unpackBlockHash(reader);
|
|
393
396
|
|
|
394
397
|
while (reader.remainingBytes() > 0) {
|
|
395
398
|
const indexOfTx = reader.readNumber();
|
|
399
|
+
const txHash = reader.readObject(TxHash);
|
|
396
400
|
const numLogsInTx = reader.readNumber();
|
|
397
|
-
publicLogsInBlock[indexOfTx] = [];
|
|
401
|
+
publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
398
402
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
399
|
-
publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
|
|
403
|
+
publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
|
|
400
404
|
}
|
|
401
405
|
}
|
|
402
406
|
|
|
403
|
-
const
|
|
407
|
+
const txData = publicLogsInBlock[txIndex];
|
|
404
408
|
|
|
405
409
|
const logs: ExtendedPublicLog[] = [];
|
|
406
|
-
const maxLogsHit = this.#
|
|
410
|
+
const maxLogsHit = this.#accumulatePublicLogs(
|
|
411
|
+
logs,
|
|
412
|
+
blockNumber,
|
|
413
|
+
blockHash,
|
|
414
|
+
txIndex,
|
|
415
|
+
txData.txHash,
|
|
416
|
+
txData.logs,
|
|
417
|
+
filter,
|
|
418
|
+
);
|
|
407
419
|
|
|
408
420
|
return { logs, maxLogsHit };
|
|
409
421
|
}
|
|
@@ -424,22 +436,31 @@ export class LogStore {
|
|
|
424
436
|
|
|
425
437
|
let maxLogsHit = false;
|
|
426
438
|
loopOverBlocks: for await (const [blockNumber, logBuffer] of this.#publicLogsByBlock.entriesAsync({ start, end })) {
|
|
427
|
-
const publicLogsInBlock:
|
|
439
|
+
const publicLogsInBlock: { txHash: TxHash; logs: PublicLog[] }[] = [];
|
|
428
440
|
const reader = new BufferReader(logBuffer);
|
|
429
441
|
|
|
430
442
|
const blockHash = this.#unpackBlockHash(reader);
|
|
431
443
|
|
|
432
444
|
while (reader.remainingBytes() > 0) {
|
|
433
445
|
const indexOfTx = reader.readNumber();
|
|
446
|
+
const txHash = reader.readObject(TxHash);
|
|
434
447
|
const numLogsInTx = reader.readNumber();
|
|
435
|
-
publicLogsInBlock[indexOfTx] = [];
|
|
448
|
+
publicLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
436
449
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
437
|
-
publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
|
|
450
|
+
publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
|
|
438
451
|
}
|
|
439
452
|
}
|
|
440
453
|
for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++) {
|
|
441
|
-
const
|
|
442
|
-
maxLogsHit = this.#
|
|
454
|
+
const txData = publicLogsInBlock[txIndex];
|
|
455
|
+
maxLogsHit = this.#accumulatePublicLogs(
|
|
456
|
+
logs,
|
|
457
|
+
blockNumber,
|
|
458
|
+
blockHash,
|
|
459
|
+
txIndex,
|
|
460
|
+
txData.txHash,
|
|
461
|
+
txData.logs,
|
|
462
|
+
filter,
|
|
463
|
+
);
|
|
443
464
|
if (maxLogsHit) {
|
|
444
465
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
445
466
|
break loopOverBlocks;
|
|
@@ -475,24 +496,33 @@ export class LogStore {
|
|
|
475
496
|
return { logs: [], maxLogsHit: false };
|
|
476
497
|
}
|
|
477
498
|
const contractClassLogsBuffer = (await this.#contractClassLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
|
|
478
|
-
const contractClassLogsInBlock:
|
|
499
|
+
const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
|
|
479
500
|
|
|
480
501
|
const reader = new BufferReader(contractClassLogsBuffer);
|
|
481
502
|
const blockHash = this.#unpackBlockHash(reader);
|
|
482
503
|
|
|
483
504
|
while (reader.remainingBytes() > 0) {
|
|
484
505
|
const indexOfTx = reader.readNumber();
|
|
506
|
+
const txHash = reader.readObject(TxHash);
|
|
485
507
|
const numLogsInTx = reader.readNumber();
|
|
486
|
-
contractClassLogsInBlock[indexOfTx] = [];
|
|
508
|
+
contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
487
509
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
488
|
-
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
510
|
+
contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
|
|
489
511
|
}
|
|
490
512
|
}
|
|
491
513
|
|
|
492
|
-
const
|
|
514
|
+
const txData = contractClassLogsInBlock[txIndex];
|
|
493
515
|
|
|
494
516
|
const logs: ExtendedContractClassLog[] = [];
|
|
495
|
-
const maxLogsHit = this.#
|
|
517
|
+
const maxLogsHit = this.#accumulateContractClassLogs(
|
|
518
|
+
logs,
|
|
519
|
+
blockNumber,
|
|
520
|
+
blockHash,
|
|
521
|
+
txIndex,
|
|
522
|
+
txData.txHash,
|
|
523
|
+
txData.logs,
|
|
524
|
+
filter,
|
|
525
|
+
);
|
|
496
526
|
|
|
497
527
|
return { logs, maxLogsHit };
|
|
498
528
|
}
|
|
@@ -516,20 +546,29 @@ export class LogStore {
|
|
|
516
546
|
start,
|
|
517
547
|
end,
|
|
518
548
|
})) {
|
|
519
|
-
const contractClassLogsInBlock:
|
|
549
|
+
const contractClassLogsInBlock: { txHash: TxHash; logs: ContractClassLog[] }[] = [];
|
|
520
550
|
const reader = new BufferReader(logBuffer);
|
|
521
551
|
const blockHash = this.#unpackBlockHash(reader);
|
|
522
552
|
while (reader.remainingBytes() > 0) {
|
|
523
553
|
const indexOfTx = reader.readNumber();
|
|
554
|
+
const txHash = reader.readObject(TxHash);
|
|
524
555
|
const numLogsInTx = reader.readNumber();
|
|
525
|
-
contractClassLogsInBlock[indexOfTx] = [];
|
|
556
|
+
contractClassLogsInBlock[indexOfTx] = { txHash, logs: [] };
|
|
526
557
|
for (let i = 0; i < numLogsInTx; i++) {
|
|
527
|
-
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
558
|
+
contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
|
|
528
559
|
}
|
|
529
560
|
}
|
|
530
561
|
for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++) {
|
|
531
|
-
const
|
|
532
|
-
maxLogsHit = this.#
|
|
562
|
+
const txData = contractClassLogsInBlock[txIndex];
|
|
563
|
+
maxLogsHit = this.#accumulateContractClassLogs(
|
|
564
|
+
logs,
|
|
565
|
+
blockNumber,
|
|
566
|
+
blockHash,
|
|
567
|
+
txIndex,
|
|
568
|
+
txData.txHash,
|
|
569
|
+
txData.logs,
|
|
570
|
+
filter,
|
|
571
|
+
);
|
|
533
572
|
if (maxLogsHit) {
|
|
534
573
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
535
574
|
break loopOverBlocks;
|
|
@@ -540,12 +579,13 @@ export class LogStore {
|
|
|
540
579
|
return { logs, maxLogsHit };
|
|
541
580
|
}
|
|
542
581
|
|
|
543
|
-
#
|
|
544
|
-
results:
|
|
582
|
+
#accumulatePublicLogs(
|
|
583
|
+
results: ExtendedPublicLog[],
|
|
545
584
|
blockNumber: number,
|
|
546
|
-
blockHash:
|
|
585
|
+
blockHash: BlockHash,
|
|
547
586
|
txIndex: number,
|
|
548
|
-
|
|
587
|
+
txHash: TxHash,
|
|
588
|
+
txLogs: PublicLog[],
|
|
549
589
|
filter: LogFilter = {},
|
|
550
590
|
): boolean {
|
|
551
591
|
let maxLogsHit = false;
|
|
@@ -553,15 +593,37 @@ export class LogStore {
|
|
|
553
593
|
for (; logIndex < txLogs.length; logIndex++) {
|
|
554
594
|
const log = txLogs[logIndex];
|
|
555
595
|
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
throw new Error('Unknown log type');
|
|
596
|
+
results.push(
|
|
597
|
+
new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
if (results.length >= this.#logsMaxPageSize) {
|
|
601
|
+
maxLogsHit = true;
|
|
602
|
+
break;
|
|
564
603
|
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return maxLogsHit;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
#accumulateContractClassLogs(
|
|
611
|
+
results: ExtendedContractClassLog[],
|
|
612
|
+
blockNumber: number,
|
|
613
|
+
blockHash: BlockHash,
|
|
614
|
+
txIndex: number,
|
|
615
|
+
txHash: TxHash,
|
|
616
|
+
txLogs: ContractClassLog[],
|
|
617
|
+
filter: LogFilter = {},
|
|
618
|
+
): boolean {
|
|
619
|
+
let maxLogsHit = false;
|
|
620
|
+
let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
|
|
621
|
+
for (; logIndex < txLogs.length; logIndex++) {
|
|
622
|
+
const log = txLogs[logIndex];
|
|
623
|
+
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
624
|
+
results.push(
|
|
625
|
+
new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log),
|
|
626
|
+
);
|
|
565
627
|
|
|
566
628
|
if (results.length >= this.#logsMaxPageSize) {
|
|
567
629
|
maxLogsHit = true;
|
|
@@ -137,7 +137,7 @@ export class MessageStore {
|
|
|
137
137
|
);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
// Check the first message in a
|
|
140
|
+
// Check the first message in a checkpoint has the correct index.
|
|
141
141
|
if (
|
|
142
142
|
(!lastMessage || message.checkpointNumber > lastMessage.checkpointNumber) &&
|
|
143
143
|
message.index !== expectedStart
|