@aztec/archiver 0.55.0 → 0.56.0

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.
Files changed (47) hide show
  1. package/dest/archiver/archiver.d.ts +4 -5
  2. package/dest/archiver/archiver.d.ts.map +1 -1
  3. package/dest/archiver/archiver.js +89 -110
  4. package/dest/archiver/archiver_store.d.ts +11 -17
  5. package/dest/archiver/archiver_store.d.ts.map +1 -1
  6. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.js +1 -25
  8. package/dest/archiver/config.d.ts +0 -4
  9. package/dest/archiver/config.d.ts.map +1 -1
  10. package/dest/archiver/config.js +1 -6
  11. package/dest/archiver/data_retrieval.d.ts +33 -5
  12. package/dest/archiver/data_retrieval.d.ts.map +1 -1
  13. package/dest/archiver/data_retrieval.js +124 -15
  14. package/dest/archiver/kv_archiver_store/block_store.d.ts +2 -2
  15. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  16. package/dest/archiver/kv_archiver_store/block_store.js +16 -10
  17. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +3 -15
  18. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  19. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +12 -25
  20. package/dest/archiver/kv_archiver_store/message_store.d.ts +1 -0
  21. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
  22. package/dest/archiver/kv_archiver_store/message_store.js +11 -8
  23. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +3 -20
  24. package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
  25. package/dest/archiver/memory_archiver_store/memory_archiver_store.js +9 -28
  26. package/dest/index.d.ts +0 -1
  27. package/dest/index.d.ts.map +1 -1
  28. package/dest/index.js +1 -2
  29. package/package.json +10 -10
  30. package/src/archiver/archiver.ts +140 -156
  31. package/src/archiver/archiver_store.ts +12 -18
  32. package/src/archiver/archiver_store_test_suite.ts +1 -28
  33. package/src/archiver/config.ts +0 -10
  34. package/src/archiver/data_retrieval.ts +189 -29
  35. package/src/archiver/kv_archiver_store/block_store.ts +17 -10
  36. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +11 -25
  37. package/src/archiver/kv_archiver_store/message_store.ts +9 -5
  38. package/src/archiver/memory_archiver_store/memory_archiver_store.ts +10 -32
  39. package/src/index.ts +0 -2
  40. package/dest/archiver/eth_log_handlers.d.ts +0 -59
  41. package/dest/archiver/eth_log_handlers.d.ts.map +0 -1
  42. package/dest/archiver/eth_log_handlers.js +0 -155
  43. package/dest/archiver/kv_archiver_store/block_body_store.d.ts +0 -34
  44. package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +0 -1
  45. package/dest/archiver/kv_archiver_store/block_body_store.js +0 -65
  46. package/src/archiver/eth_log_handlers.ts +0 -213
  47. package/src/archiver/kv_archiver_store/block_body_store.ts +0 -74
@@ -1,20 +1,25 @@
1
- import { type InboxLeaf, type L2Block } from '@aztec/circuit-types';
2
- import { Fr, type Proof } from '@aztec/circuits.js';
1
+ import { Body, InboxLeaf, L2Block } from '@aztec/circuit-types';
2
+ import { AppendOnlyTreeSnapshot, Fr, Header, Proof } from '@aztec/circuits.js';
3
3
  import { type EthAddress } from '@aztec/foundation/eth-address';
4
+ import { type ViemSignature } from '@aztec/foundation/eth-signature';
4
5
  import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
5
- import { RollupAbi } from '@aztec/l1-artifacts';
6
-
7
- import { type Hex, type PublicClient, getAbiItem } from 'viem';
6
+ import { numToUInt32BE } from '@aztec/foundation/serialize';
7
+ import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
8
8
 
9
9
  import {
10
- getBlockProofFromSubmitProofTx,
11
- getL2BlockProposedLogs,
12
- getMessageSentLogs,
13
- processL2BlockProposedLogs,
14
- processMessageSentLogs,
15
- } from './eth_log_handlers.js';
10
+ type Chain,
11
+ type GetContractEventsReturnType,
12
+ type GetContractReturnType,
13
+ type Hex,
14
+ type HttpTransport,
15
+ type PublicClient,
16
+ decodeFunctionData,
17
+ getAbiItem,
18
+ hexToBytes,
19
+ } from 'viem';
20
+
16
21
  import { type DataRetrieval } from './structs/data_retrieval.js';
17
- import { type L1Published } from './structs/published.js';
22
+ import { type L1Published, type L1PublishedData } from './structs/published.js';
18
23
 
19
24
  /**
20
25
  * Fetches new L2 blocks.
@@ -27,12 +32,11 @@ import { type L1Published } from './structs/published.js';
27
32
  * @returns An array of block; as well as the next eth block to search from.
28
33
  */
29
34
  export async function retrieveBlockFromRollup(
35
+ rollup: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, Chain>>,
30
36
  publicClient: PublicClient,
31
- rollupAddress: EthAddress,
32
37
  blockUntilSynced: boolean,
33
38
  searchStartBlock: bigint,
34
39
  searchEndBlock: bigint,
35
- expectedNextL2BlockNum: bigint,
36
40
  logger: DebugLogger = createDebugLogger('aztec:archiver'),
37
41
  ): Promise<L1Published<L2Block>[]> {
38
42
  const retrievedBlocks: L1Published<L2Block>[] = [];
@@ -40,29 +44,120 @@ export async function retrieveBlockFromRollup(
40
44
  if (searchStartBlock > searchEndBlock) {
41
45
  break;
42
46
  }
43
- const L2BlockProposedLogs = await getL2BlockProposedLogs(
44
- publicClient,
45
- rollupAddress,
46
- searchStartBlock,
47
- searchEndBlock,
47
+ const l2BlockProposedLogs = await rollup.getEvents.L2BlockProposed(
48
+ {},
49
+ {
50
+ fromBlock: searchStartBlock,
51
+ toBlock: searchEndBlock + 1n,
52
+ },
48
53
  );
49
- if (L2BlockProposedLogs.length === 0) {
54
+
55
+ if (l2BlockProposedLogs.length === 0) {
50
56
  break;
51
57
  }
52
58
 
53
- const lastLog = L2BlockProposedLogs[L2BlockProposedLogs.length - 1];
59
+ const lastLog = l2BlockProposedLogs[l2BlockProposedLogs.length - 1];
54
60
  logger.debug(
55
- `Got L2 block processed logs for ${L2BlockProposedLogs[0].blockNumber}-${lastLog.blockNumber} between ${searchStartBlock}-${searchEndBlock} L1 blocks`,
61
+ `Got L2 block processed logs for ${l2BlockProposedLogs[0].blockNumber}-${lastLog.blockNumber} between ${searchStartBlock}-${searchEndBlock} L1 blocks`,
56
62
  );
57
63
 
58
- const newBlocks = await processL2BlockProposedLogs(publicClient, expectedNextL2BlockNum, L2BlockProposedLogs);
64
+ const newBlocks = await processL2BlockProposedLogs(rollup, publicClient, l2BlockProposedLogs, logger);
59
65
  retrievedBlocks.push(...newBlocks);
60
66
  searchStartBlock = lastLog.blockNumber! + 1n;
61
- expectedNextL2BlockNum += BigInt(newBlocks.length);
62
67
  } while (blockUntilSynced && searchStartBlock <= searchEndBlock);
63
68
  return retrievedBlocks;
64
69
  }
65
70
 
71
+ /**
72
+ * Processes newly received L2BlockProposed logs.
73
+ * @param rollup - The rollup contract
74
+ * @param publicClient - The viem public client to use for transaction retrieval.
75
+ * @param logs - L2BlockProposed logs.
76
+ * @returns - An array blocks.
77
+ */
78
+ export async function processL2BlockProposedLogs(
79
+ rollup: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, Chain>>,
80
+ publicClient: PublicClient,
81
+ logs: GetContractEventsReturnType<typeof RollupAbi, 'L2BlockProposed'>,
82
+ logger: DebugLogger,
83
+ ): Promise<L1Published<L2Block>[]> {
84
+ const retrievedBlocks: L1Published<L2Block>[] = [];
85
+ for (const log of logs) {
86
+ const l2BlockNumber = log.args.blockNumber!;
87
+ const archive = log.args.archive!;
88
+ const archiveFromChain = await rollup.read.archiveAt([l2BlockNumber]);
89
+
90
+ // The value from the event and contract will match only if the block is in the chain.
91
+ if (archive === archiveFromChain) {
92
+ // TODO: Fetch blocks from calldata in parallel
93
+ const block = await getBlockFromRollupTx(publicClient, log.transactionHash!, l2BlockNumber);
94
+
95
+ const l1: L1PublishedData = {
96
+ blockNumber: log.blockNumber,
97
+ blockHash: log.blockHash,
98
+ timestamp: await getL1BlockTime(publicClient, log.blockNumber),
99
+ };
100
+
101
+ retrievedBlocks.push({ data: block, l1 });
102
+ } else {
103
+ logger.warn(
104
+ `Archive mismatch matching, ignoring block ${l2BlockNumber} with archive: ${archive}, expected ${archiveFromChain}`,
105
+ );
106
+ }
107
+ }
108
+
109
+ return retrievedBlocks;
110
+ }
111
+
112
+ export async function getL1BlockTime(publicClient: PublicClient, blockNumber: bigint): Promise<bigint> {
113
+ const block = await publicClient.getBlock({ blockNumber, includeTransactions: false });
114
+ return block.timestamp;
115
+ }
116
+
117
+ /**
118
+ * Gets block from the calldata of an L1 transaction.
119
+ * Assumes that the block was published from an EOA.
120
+ * TODO: Add retries and error management.
121
+ * @param publicClient - The viem public client to use for transaction retrieval.
122
+ * @param txHash - Hash of the tx that published it.
123
+ * @param l2BlockNum - L2 block number.
124
+ * @returns L2 block from the calldata, deserialized
125
+ */
126
+ async function getBlockFromRollupTx(
127
+ publicClient: PublicClient,
128
+ txHash: `0x${string}`,
129
+ l2BlockNum: bigint,
130
+ ): Promise<L2Block> {
131
+ const { input: data } = await publicClient.getTransaction({ hash: txHash });
132
+ const { functionName, args } = decodeFunctionData({
133
+ abi: RollupAbi,
134
+ data,
135
+ });
136
+
137
+ if (!(functionName === 'propose')) {
138
+ throw new Error(`Unexpected method called ${functionName}`);
139
+ }
140
+ const [headerHex, archiveRootHex, , , , bodyHex] = args! as readonly [Hex, Hex, Hex, Hex[], ViemSignature[], Hex];
141
+
142
+ const header = Header.fromBuffer(Buffer.from(hexToBytes(headerHex)));
143
+ const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex)));
144
+
145
+ const blockNumberFromHeader = header.globalVariables.blockNumber.toBigInt();
146
+
147
+ if (blockNumberFromHeader !== l2BlockNum) {
148
+ throw new Error(`Block number mismatch: expected ${l2BlockNum} but got ${blockNumberFromHeader}`);
149
+ }
150
+
151
+ const archive = AppendOnlyTreeSnapshot.fromBuffer(
152
+ Buffer.concat([
153
+ Buffer.from(hexToBytes(archiveRootHex)), // L2Block.archive.root
154
+ numToUInt32BE(Number(l2BlockNum + 1n)), // L2Block.archive.nextAvailableLeafIndex
155
+ ]),
156
+ );
157
+
158
+ return new L2Block(archive, header, blockBody);
159
+ }
160
+
66
161
  /**
67
162
  * Fetch L1 to L2 messages.
68
163
  * @param publicClient - The viem public client to use for transaction retrieval.
@@ -73,8 +168,7 @@ export async function retrieveBlockFromRollup(
73
168
  * @returns An array of InboxLeaf and next eth block to search from.
74
169
  */
75
170
  export async function retrieveL1ToL2Messages(
76
- publicClient: PublicClient,
77
- inboxAddress: EthAddress,
171
+ inbox: GetContractReturnType<typeof InboxAbi, PublicClient<HttpTransport, Chain>>,
78
172
  blockUntilSynced: boolean,
79
173
  searchStartBlock: bigint,
80
174
  searchEndBlock: bigint,
@@ -84,12 +178,24 @@ export async function retrieveL1ToL2Messages(
84
178
  if (searchStartBlock > searchEndBlock) {
85
179
  break;
86
180
  }
87
- const messageSentLogs = await getMessageSentLogs(publicClient, inboxAddress, searchStartBlock, searchEndBlock);
181
+
182
+ const messageSentLogs = await inbox.getEvents.MessageSent(
183
+ {},
184
+ {
185
+ fromBlock: searchStartBlock,
186
+ toBlock: searchEndBlock + 1n,
187
+ },
188
+ );
189
+
88
190
  if (messageSentLogs.length === 0) {
89
191
  break;
90
192
  }
91
- const l1ToL2Messages = processMessageSentLogs(messageSentLogs);
92
- retrievedL1ToL2Messages.push(...l1ToL2Messages);
193
+
194
+ for (const log of messageSentLogs) {
195
+ const { l2BlockNumber, index, hash } = log.args;
196
+ retrievedL1ToL2Messages.push(new InboxLeaf(l2BlockNumber!, index!, Fr.fromString(hash!)));
197
+ }
198
+
93
199
  // handles the case when there are no new messages:
94
200
  searchStartBlock = (messageSentLogs.findLast(msgLog => !!msgLog)?.blockNumber || searchStartBlock) + 1n;
95
201
  } while (blockUntilSynced && searchStartBlock <= searchEndBlock);
@@ -139,3 +245,57 @@ export async function retrieveL2ProofsFromRollup(
139
245
  lastProcessedL1BlockNumber,
140
246
  };
141
247
  }
248
+
249
+ export type SubmitBlockProof = {
250
+ header: Header;
251
+ archiveRoot: Fr;
252
+ proverId: Fr;
253
+ aggregationObject: Buffer;
254
+ proof: Proof;
255
+ };
256
+
257
+ /**
258
+ * Gets block metadata (header and archive snapshot) from the calldata of an L1 transaction.
259
+ * Assumes that the block was published from an EOA.
260
+ * TODO: Add retries and error management.
261
+ * @param publicClient - The viem public client to use for transaction retrieval.
262
+ * @param txHash - Hash of the tx that published it.
263
+ * @param l2BlockNum - L2 block number.
264
+ * @returns L2 block metadata (header and archive) from the calldata, deserialized
265
+ */
266
+ export async function getBlockProofFromSubmitProofTx(
267
+ publicClient: PublicClient,
268
+ txHash: `0x${string}`,
269
+ l2BlockNum: bigint,
270
+ expectedProverId: Fr,
271
+ ): Promise<SubmitBlockProof> {
272
+ const { input: data } = await publicClient.getTransaction({ hash: txHash });
273
+ const { functionName, args } = decodeFunctionData({
274
+ abi: RollupAbi,
275
+ data,
276
+ });
277
+
278
+ if (!(functionName === 'submitBlockRootProof')) {
279
+ throw new Error(`Unexpected method called ${functionName}`);
280
+ }
281
+ const [headerHex, archiveHex, proverIdHex, aggregationObjectHex, proofHex] = args!;
282
+
283
+ const header = Header.fromBuffer(Buffer.from(hexToBytes(headerHex)));
284
+ const proverId = Fr.fromString(proverIdHex);
285
+
286
+ const blockNumberFromHeader = header.globalVariables.blockNumber.toBigInt();
287
+ if (blockNumberFromHeader !== l2BlockNum) {
288
+ throw new Error(`Block number mismatch: expected ${l2BlockNum} but got ${blockNumberFromHeader}`);
289
+ }
290
+ if (!proverId.equals(expectedProverId)) {
291
+ throw new Error(`Prover ID mismatch: expected ${expectedProverId} but got ${proverId}`);
292
+ }
293
+
294
+ return {
295
+ header,
296
+ proverId,
297
+ aggregationObject: Buffer.from(hexToBytes(aggregationObjectHex)),
298
+ archiveRoot: Fr.fromString(archiveHex),
299
+ proof: Proof.fromBuffer(Buffer.from(hexToBytes(proofHex))),
300
+ };
301
+ }
@@ -1,10 +1,9 @@
1
- import { L2Block, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types';
1
+ import { Body, L2Block, type TxEffect, type TxHash, TxReceipt } from '@aztec/circuit-types';
2
2
  import { AppendOnlyTreeSnapshot, type AztecAddress, Header, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
3
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
4
  import { type AztecKVStore, type AztecMap, type AztecSingleton, type Range } from '@aztec/kv-store';
5
5
 
6
6
  import { type L1Published, type L1PublishedData } from '../structs/published.js';
7
- import { type BlockBodyStore } from './block_body_store.js';
8
7
 
9
8
  type BlockIndexValue = [blockNumber: number, index: number];
10
9
 
@@ -20,6 +19,10 @@ type BlockStorage = {
20
19
  export class BlockStore {
21
20
  /** Map block number to block data */
22
21
  #blocks: AztecMap<number, BlockStorage>;
22
+
23
+ /** Map block body hash to block body */
24
+ #blockBodies: AztecMap<string, Buffer>;
25
+
23
26
  /** Stores L1 block number in which the last processed L2 block was included */
24
27
  #lastSynchedL1Block: AztecSingleton<bigint>;
25
28
 
@@ -31,12 +34,9 @@ export class BlockStore {
31
34
 
32
35
  #log = createDebugLogger('aztec:archiver:block_store');
33
36
 
34
- #blockBodyStore: BlockBodyStore;
35
-
36
- constructor(private db: AztecKVStore, blockBodyStore: BlockBodyStore) {
37
- this.#blockBodyStore = blockBodyStore;
38
-
37
+ constructor(private db: AztecKVStore) {
39
38
  this.#blocks = db.openMap('archiver_blocks');
39
+ this.#blockBodies = db.openMap('archiver_block_bodies');
40
40
  this.#txIndex = db.openMap('archiver_tx_index');
41
41
  this.#contractIndex = db.openMap('archiver_contract_index');
42
42
  this.#lastSynchedL1Block = db.openSingleton('archiver_last_synched_l1_block');
@@ -63,6 +63,8 @@ export class BlockStore {
63
63
  block.data.body.txEffects.forEach((tx, i) => {
64
64
  void this.#txIndex.set(tx.txHash.toString(), [block.data.number, i]);
65
65
  });
66
+
67
+ void this.#blockBodies.set(block.data.body.getTxsEffectsHash().toString('hex'), block.data.body.toBuffer());
66
68
  }
67
69
 
68
70
  void this.#lastSynchedL1Block.set(blocks[blocks.length - 1].l1.blockNumber);
@@ -100,11 +102,12 @@ export class BlockStore {
100
102
  private getBlockFromBlockStorage(blockStorage: BlockStorage) {
101
103
  const header = Header.fromBuffer(blockStorage.header);
102
104
  const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
103
- const body = this.#blockBodyStore.getBlockBody(header.contentCommitment.txsEffectsHash);
104
105
 
105
- if (body === undefined) {
106
- throw new Error('Body is not able to be retrieved from BodyStore');
106
+ const blockBodyBuffer = this.#blockBodies.get(header.contentCommitment.txsEffectsHash.toString('hex'));
107
+ if (blockBodyBuffer === undefined) {
108
+ throw new Error('Body could not be retrieved');
107
109
  }
110
+ const body = Body.fromBuffer(blockBodyBuffer);
108
111
 
109
112
  const l2Block = L2Block.fromFields({ header, archive, body });
110
113
  return { data: l2Block, l1: blockStorage.l1 };
@@ -184,6 +187,10 @@ export class BlockStore {
184
187
  return this.#lastSynchedL1Block.get();
185
188
  }
186
189
 
190
+ setSynchedL1BlockNumber(l1BlockNumber: bigint) {
191
+ void this.#lastSynchedL1Block.set(l1BlockNumber);
192
+ }
193
+
187
194
  #computeBlockRange(start: number, limit: number): Required<Pick<Range<number>, 'start' | 'end'>> {
188
195
  if (limit < 1) {
189
196
  throw new Error(`Invalid limit: ${limit}`);
@@ -1,5 +1,4 @@
1
1
  import {
2
- type Body,
3
2
  type EncryptedL2BlockL2Logs,
4
3
  type EncryptedNoteL2BlockL2Logs,
5
4
  type FromLogType,
@@ -29,7 +28,6 @@ import {
29
28
  import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_store.js';
30
29
  import { type DataRetrieval, type SingletonDataRetrieval } from '../structs/data_retrieval.js';
31
30
  import { type L1Published } from '../structs/published.js';
32
- import { BlockBodyStore } from './block_body_store.js';
33
31
  import { BlockStore } from './block_store.js';
34
32
  import { ContractArtifactsStore } from './contract_artifacts_store.js';
35
33
  import { ContractClassStore } from './contract_class_store.js';
@@ -42,7 +40,6 @@ import { ProvenStore } from './proven_store.js';
42
40
  * LMDB implementation of the ArchiverDataStore interface.
43
41
  */
44
42
  export class KVArchiverDataStore implements ArchiverDataStore {
45
- #blockBodyStore: BlockBodyStore;
46
43
  #blockStore: BlockStore;
47
44
  #provenStore: ProvenStore;
48
45
  #logStore: LogStore;
@@ -54,8 +51,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
54
51
  #log = createDebugLogger('aztec:archiver:data-store');
55
52
 
56
53
  constructor(db: AztecKVStore, logsMaxPageSize: number = 1000) {
57
- this.#blockBodyStore = new BlockBodyStore(db);
58
- this.#blockStore = new BlockStore(db, this.#blockBodyStore);
54
+ this.#blockStore = new BlockStore(db);
59
55
  this.#provenStore = new ProvenStore(db);
60
56
  this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
61
57
  this.#messageStore = new MessageStore(db);
@@ -100,25 +96,6 @@ export class KVArchiverDataStore implements ArchiverDataStore {
100
96
  return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(Boolean);
101
97
  }
102
98
 
103
- /**
104
- * Append new block bodies to the store's list.
105
- * @param blockBodies - The L2 block bodies to be added to the store.
106
- * @returns True if the operation is successful.
107
- */
108
- addBlockBodies(blockBodies: DataRetrieval<Body>): Promise<boolean> {
109
- return this.#blockBodyStore.addBlockBodies(blockBodies);
110
- }
111
-
112
- /**
113
- * Gets block bodies that have the same txHashes as we supply.
114
- *
115
- * @param txsEffectsHashes - A list of txsEffectsHashes (body hashes).
116
- * @returns The requested L2 block bodies
117
- */
118
- getBlockBodies(txsEffectsHashes: Buffer[]): Promise<(Body | undefined)[]> {
119
- return this.#blockBodyStore.getBlockBodies(txsEffectsHashes);
120
- }
121
-
122
99
  /**
123
100
  * Append new blocks to the store's list.
124
101
  * @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
@@ -258,13 +235,22 @@ export class KVArchiverDataStore implements ArchiverDataStore {
258
235
  await this.#provenStore.setProvenL2BlockNumber(blockNumber);
259
236
  }
260
237
 
238
+ setBlockSynchedL1BlockNumber(l1BlockNumber: bigint) {
239
+ this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
240
+ return Promise.resolve();
241
+ }
242
+
243
+ setMessageSynchedL1BlockNumber(l1BlockNumber: bigint) {
244
+ this.#messageStore.setSynchedL1BlockNumber(l1BlockNumber);
245
+ return Promise.resolve();
246
+ }
247
+
261
248
  /**
262
249
  * Gets the last L1 block number processed by the archiver
263
250
  */
264
251
  getSynchPoint(): Promise<ArchiverL1SynchPoint> {
265
252
  return Promise.resolve({
266
253
  blocksSynchedTo: this.#blockStore.getSynchedL1BlockNumber(),
267
- blockBodiesSynchedTo: this.#blockBodyStore.getSynchedL1BlockNumber(),
268
254
  messagesSynchedTo: this.#messageStore.getSynchedL1BlockNumber(),
269
255
  provenLogsSynchedTo: this.#provenStore.getSynchedL1BlockNumber(),
270
256
  });
@@ -16,7 +16,7 @@ import { type DataRetrieval } from '../structs/data_retrieval.js';
16
16
  export class MessageStore {
17
17
  #l1ToL2Messages: AztecMap<string, Buffer>;
18
18
  #l1ToL2MessageIndices: AztecMap<string, bigint[]>; // We store array of bigints here because there can be duplicate messages
19
- #lastL1BlockMessages: AztecSingleton<bigint>;
19
+ #lastSynchedL1Block: AztecSingleton<bigint>;
20
20
 
21
21
  #log = createDebugLogger('aztec:archiver:message_store');
22
22
 
@@ -25,7 +25,7 @@ export class MessageStore {
25
25
  constructor(private db: AztecKVStore) {
26
26
  this.#l1ToL2Messages = db.openMap('archiver_l1_to_l2_messages');
27
27
  this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
28
- this.#lastL1BlockMessages = db.openSingleton('archiver_last_l1_block_new_messages');
28
+ this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_new_messages');
29
29
  }
30
30
 
31
31
  /**
@@ -33,7 +33,11 @@ export class MessageStore {
33
33
  * @returns The last L1 block number processed
34
34
  */
35
35
  getSynchedL1BlockNumber(): bigint | undefined {
36
- return this.#lastL1BlockMessages.get();
36
+ return this.#lastSynchedL1Block.get();
37
+ }
38
+
39
+ setSynchedL1BlockNumber(l1BlockNumber: bigint) {
40
+ void this.#lastSynchedL1Block.set(l1BlockNumber);
37
41
  }
38
42
 
39
43
  /**
@@ -43,12 +47,12 @@ export class MessageStore {
43
47
  */
44
48
  addL1ToL2Messages(messages: DataRetrieval<InboxLeaf>): Promise<boolean> {
45
49
  return this.db.transaction(() => {
46
- const lastL1BlockNumber = this.#lastL1BlockMessages.get() ?? 0n;
50
+ const lastL1BlockNumber = this.#lastSynchedL1Block.get() ?? 0n;
47
51
  if (lastL1BlockNumber >= messages.lastProcessedL1BlockNumber) {
48
52
  return false;
49
53
  }
50
54
 
51
- void this.#lastL1BlockMessages.set(messages.lastProcessedL1BlockNumber);
55
+ void this.#lastSynchedL1Block.set(messages.lastProcessedL1BlockNumber);
52
56
 
53
57
  for (const message of messages.retrievedData) {
54
58
  if (message.index >= this.#l1ToL2MessagesSubtreeSize) {
@@ -1,5 +1,4 @@
1
1
  import {
2
- type Body,
3
2
  type EncryptedL2BlockL2Logs,
4
3
  type EncryptedNoteL2BlockL2Logs,
5
4
  ExtendedUnencryptedL2Log,
@@ -40,11 +39,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
40
39
  */
41
40
  private l2Blocks: L1Published<L2Block>[] = [];
42
41
 
43
- /**
44
- * A mapping of body hash to body
45
- */
46
- private l2BlockBodies: Map<string, Body> = new Map();
47
-
48
42
  /**
49
43
  * An array containing all the tx effects in the L2 blocks that have been fetched so far.
50
44
  */
@@ -84,7 +78,6 @@ export class MemoryArchiverStore implements ArchiverDataStore {
84
78
  private contractInstances: Map<string, ContractInstanceWithAddress> = new Map();
85
79
 
86
80
  private lastL1BlockNewBlocks: bigint | undefined = undefined;
87
- private lastL1BlockNewBlockBodies: bigint | undefined = undefined;
88
81
  private lastL1BlockNewMessages: bigint | undefined = undefined;
89
82
  private lastL1BlockNewProvenLogs: bigint | undefined = undefined;
90
83
 
@@ -163,34 +156,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
163
156
  this.lastL1BlockNewBlocks = blocks[blocks.length - 1].l1.blockNumber;
164
157
  this.l2Blocks.push(...blocks);
165
158
  this.txEffects.push(...blocks.flatMap(b => b.data.body.txEffects));
166
- return Promise.resolve(true);
167
- }
168
159
 
169
- /**
170
- * Append new block bodies to the store's list.
171
- * @param blockBodies - The L2 block bodies to be added to the store.
172
- * @returns True if the operation is successful.
173
- */
174
- addBlockBodies(blockBodies: DataRetrieval<Body>): Promise<boolean> {
175
- for (const body of blockBodies.retrievedData) {
176
- void this.l2BlockBodies.set(body.getTxsEffectsHash().toString('hex'), body);
177
- }
178
- this.lastL1BlockNewBlockBodies = blockBodies.lastProcessedL1BlockNumber;
179
160
  return Promise.resolve(true);
180
161
  }
181
162
 
182
- /**
183
- * Gets block bodies that have the same txHashes as we supply.
184
- *
185
- * @param txsEffectsHashes - A list of txsEffectsHashes (body hashes).
186
- * @returns The requested L2 block bodies
187
- */
188
- getBlockBodies(txsEffectsHashes: Buffer[]): Promise<(Body | undefined)[]> {
189
- return Promise.resolve(
190
- txsEffectsHashes.map(txsEffectsHash => this.l2BlockBodies.get(txsEffectsHash.toString('hex'))),
191
- );
192
- }
193
-
194
163
  /**
195
164
  * Append new logs to the store's list.
196
165
  * @param encryptedLogs - The encrypted logs to be added to the store.
@@ -451,11 +420,20 @@ export class MemoryArchiverStore implements ArchiverDataStore {
451
420
  return Promise.resolve();
452
421
  }
453
422
 
423
+ setBlockSynchedL1BlockNumber(l1BlockNumber: bigint) {
424
+ this.lastL1BlockNewBlocks = l1BlockNumber;
425
+ return Promise.resolve();
426
+ }
427
+
428
+ setMessageSynchedL1BlockNumber(l1BlockNumber: bigint) {
429
+ this.lastL1BlockNewMessages = l1BlockNumber;
430
+ return Promise.resolve();
431
+ }
432
+
454
433
  public getSynchPoint(): Promise<ArchiverL1SynchPoint> {
455
434
  return Promise.resolve({
456
435
  blocksSynchedTo: this.lastL1BlockNewBlocks,
457
436
  messagesSynchedTo: this.lastL1BlockNewMessages,
458
- blockBodiesSynchedTo: this.lastL1BlockNewBlockBodies,
459
437
  provenLogsSynchedTo: this.lastL1BlockNewProvenLogs,
460
438
  });
461
439
  }
package/src/index.ts CHANGED
@@ -15,8 +15,6 @@ export * from './factory.js';
15
15
 
16
16
  export { retrieveL2ProofVerifiedEvents, retrieveBlockFromRollup } from './archiver/data_retrieval.js';
17
17
 
18
- export { getL2BlockProposedLogs } from './archiver/eth_log_handlers.js';
19
-
20
18
  const log = createDebugLogger('aztec:archiver');
21
19
 
22
20
  /**
@@ -1,59 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- import { InboxLeaf, L2Block } from '@aztec/circuit-types';
3
- import { Header, Proof } from '@aztec/circuits.js';
4
- import { type EthAddress } from '@aztec/foundation/eth-address';
5
- import { Fr } from '@aztec/foundation/fields';
6
- import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
7
- import { type Log, type PublicClient } from 'viem';
8
- import { type L1Published } from './structs/published.js';
9
- /**
10
- * Processes newly received MessageSent (L1 to L2) logs.
11
- * @param logs - MessageSent logs.
12
- * @returns Array of all processed MessageSent logs
13
- */
14
- export declare function processMessageSentLogs(logs: Log<bigint, number, false, undefined, true, typeof InboxAbi, 'MessageSent'>[]): InboxLeaf[];
15
- /**
16
- * Processes newly received L2BlockProposed logs.
17
- * @param publicClient - The viem public client to use for transaction retrieval.
18
- * @param expectedL2BlockNumber - The next expected L2 block number.
19
- * @param logs - L2BlockProposed logs.
20
- * @returns - An array blocks.
21
- */
22
- export declare function processL2BlockProposedLogs(publicClient: PublicClient, expectedL2BlockNumber: bigint, logs: Log<bigint, number, false, undefined, true, typeof RollupAbi, 'L2BlockProposed'>[]): Promise<L1Published<L2Block>[]>;
23
- export declare function getL1BlockTime(publicClient: PublicClient, blockNumber: bigint): Promise<bigint>;
24
- /**
25
- * Gets relevant `L2BlockProposed` logs from chain.
26
- * @param publicClient - The viem public client to use for transaction retrieval.
27
- * @param rollupAddress - The address of the rollup contract.
28
- * @param fromBlock - First block to get logs from (inclusive).
29
- * @param toBlock - Last block to get logs from (inclusive).
30
- * @returns An array of `L2BlockProposed` logs.
31
- */
32
- export declare function getL2BlockProposedLogs(publicClient: PublicClient, rollupAddress: EthAddress, fromBlock: bigint, toBlock: bigint): Promise<Log<bigint, number, false, undefined, true, typeof RollupAbi, 'L2BlockProposed'>[]>;
33
- /**
34
- * Get relevant `MessageSent` logs emitted by Inbox on chain.
35
- * @param publicClient - The viem public client to use for transaction retrieval.
36
- * @param inboxAddress - The address of the inbox contract.
37
- * @param fromBlock - First block to get logs from (inclusive).
38
- * @param toBlock - Last block to get logs from (inclusive).
39
- * @returns An array of `MessageSent` logs.
40
- */
41
- export declare function getMessageSentLogs(publicClient: PublicClient, inboxAddress: EthAddress, fromBlock: bigint, toBlock: bigint): Promise<Log<bigint, number, false, undefined, true, typeof InboxAbi, 'MessageSent'>[]>;
42
- export type SubmitBlockProof = {
43
- header: Header;
44
- archiveRoot: Fr;
45
- proverId: Fr;
46
- aggregationObject: Buffer;
47
- proof: Proof;
48
- };
49
- /**
50
- * Gets block metadata (header and archive snapshot) from the calldata of an L1 transaction.
51
- * Assumes that the block was published from an EOA.
52
- * TODO: Add retries and error management.
53
- * @param publicClient - The viem public client to use for transaction retrieval.
54
- * @param txHash - Hash of the tx that published it.
55
- * @param l2BlockNum - L2 block number.
56
- * @returns L2 block metadata (header and archive) from the calldata, deserialized
57
- */
58
- export declare function getBlockProofFromSubmitProofTx(publicClient: PublicClient, txHash: `0x${string}`, l2BlockNum: bigint, expectedProverId: Fr): Promise<SubmitBlockProof>;
59
- //# sourceMappingURL=eth_log_handlers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eth_log_handlers.d.ts","sourceRoot":"","sources":["../../src/archiver/eth_log_handlers.ts"],"names":[],"mappings":";AAAA,OAAO,EAAQ,SAAS,EAAE,OAAO,EAAsB,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAA0B,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAY,KAAK,GAAG,EAAE,KAAK,YAAY,EAA0D,MAAM,MAAM,CAAC;AAErH,OAAO,EAAE,KAAK,WAAW,EAAwB,MAAM,wBAAwB,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,QAAQ,EAAE,aAAa,CAAC,EAAE,GAClF,SAAS,EAAE,CAOb;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,YAAY,EAC1B,qBAAqB,EAAE,MAAM,EAC7B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,SAAS,EAAE,iBAAiB,CAAC,EAAE,GACvF,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAqBjC;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrG;AA8CD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,UAAU,EACzB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,SAAS,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAU7F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,UAAU,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,QAAQ,EAAE,aAAa,CAAC,EAAE,CAAC,CAUxF;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,EAAE,CAAC;IAChB,QAAQ,EAAE,EAAE,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,8BAA8B,CAClD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,KAAK,MAAM,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,EAAE,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA8B3B"}