@aztec/archiver 0.0.1-commit.e3c1de76 → 0.0.1-commit.e558bd1c

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.
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
- import { createPublicClient, http } from 'viem';
5
+ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
6
+ import { createPublicClient, getAbiItem, http, toEventSelector } from 'viem';
6
7
  import { mainnet } from 'viem/chains';
7
8
  import { CalldataRetriever } from '../calldata_retriever.js';
8
9
  const logger = createLogger('archiver:calldata-test');
@@ -86,35 +87,33 @@ async function main() {
86
87
  slashingProposerAddress,
87
88
  slashFactoryAddress
88
89
  });
89
- // Extract L2 block number from transaction logs
90
- logger.info('Decoding transaction to extract L2 block number...');
90
+ // Extract checkpoint number from transaction logs
91
+ logger.info('Decoding transaction to extract checkpoint number...');
91
92
  const receipt = await publicClient.getTransactionReceipt({
92
93
  hash: txHash
93
94
  });
94
- const l2BlockProposedEvent = receipt.logs.find((log)=>{
95
+ // Look for CheckpointProposed event (emitted when a checkpoint is proposed to the rollup)
96
+ // Event signature: CheckpointProposed(uint256 indexed checkpointNumber, bytes32 indexed archive, bytes32[], bytes32, bytes32)
97
+ // Hash: keccak256("CheckpointProposed(uint256,bytes32,bytes32[],bytes32,bytes32)")
98
+ const checkpointProposedEvent = receipt.logs.find((log)=>{
95
99
  try {
96
- // Try to match the L2BlockProposed event
97
- return log.address.toLowerCase() === rollupAddress.toString().toLowerCase() && log.topics[0] === '0x2f1d0e696fa5186494a2f2f89a0e0bcbb15d607f6c5eac4637e07e1e5e7d3c00' // L2BlockProposed event signature
98
- ;
100
+ return log.address.toLowerCase() === rollupAddress.toString().toLowerCase() && log.topics[0] === toEventSelector(getAbiItem({
101
+ abi: RollupAbi,
102
+ name: 'CheckpointProposed'
103
+ }));
99
104
  } catch {
100
105
  return false;
101
106
  }
102
107
  });
103
- let l2BlockNumber;
104
- if (l2BlockProposedEvent && l2BlockProposedEvent.topics[1]) {
105
- // L2 block number is typically the first indexed parameter
106
- l2BlockNumber = Number(BigInt(l2BlockProposedEvent.topics[1]));
107
- logger.info(`L2 Block Number (from event): ${l2BlockNumber}`);
108
- } else {
109
- // Fallback: try to extract from transaction data or use a default
110
- logger.warn('Could not extract L2 block number from event, using block number as fallback');
111
- l2BlockNumber = Number(tx.blockNumber);
108
+ if (!checkpointProposedEvent || checkpointProposedEvent.topics[1] === undefined) {
109
+ throw new Error(`Checkpoint proposed event not found`);
112
110
  }
111
+ const checkpointNumber = CheckpointNumber.fromBigInt(BigInt(checkpointProposedEvent.topics[1]));
113
112
  logger.info('');
114
- logger.info('Retrieving block header from rollup transaction...');
113
+ logger.info('Retrieving checkpoint from rollup transaction...');
115
114
  logger.info('');
116
115
  // For this script, we don't have blob hashes or expected hashes, so pass empty arrays/objects
117
- const result = await retriever.getCheckpointFromRollupTx(txHash, [], CheckpointNumber.fromBlockNumber(BlockNumber(l2BlockNumber)), {});
116
+ const result = await retriever.getCheckpointFromRollupTx(txHash, [], checkpointNumber, {});
118
117
  logger.info(' Successfully retrieved block header!');
119
118
  logger.info('');
120
119
  logger.info('Block Header Details:');
@@ -46,7 +46,7 @@ export async function retrievedToPublishedCheckpoint({ checkpointNumber, archive
46
46
  publicDataTree: new AppendOnlyTreeSnapshot(publicDataRoot, blockEndStateField.publicDataNextAvailableLeafIndex)
47
47
  })
48
48
  });
49
- const body = Body.fromTxBlobData(checkpointBlobData.blocks[0].txs);
49
+ const body = Body.fromTxBlobData(blockBlobData.txs);
50
50
  const blobFields = encodeBlockBlobData(blockBlobData);
51
51
  await spongeBlob.absorb(blobFields);
52
52
  const clonedSpongeBlob = spongeBlob.clone();
@@ -51,4 +51,4 @@ export declare class LogStore {
51
51
  */
52
52
  getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse>;
53
53
  }
54
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nX3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmUvbG9nX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sRUFBYSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNHLE9BQU8sRUFJTCxLQUFLLFNBQVMsRUFHZCxLQUFLLFNBQVMsRUFDZCxHQUFHLEVBQ0gsYUFBYSxFQUNkLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbkQ7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQWFqQixPQUFPLENBQUMsRUFBRTtJQUNWLE9BQU8sQ0FBQyxVQUFVO0lBRnBCLFlBQ1UsRUFBRSxFQUFFLGlCQUFpQixFQUNyQixVQUFVLEVBQUUsVUFBVSxFQUM5QixlQUFlLEdBQUUsTUFBYSxFQVUvQjtJQTRNRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBUzNDO0lBZ0JELFVBQVUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQTJCOUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0csb0JBQW9CLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLElBQUksR0FBRSxNQUFVLEdBQUcsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FRMUY7SUFFRDs7Ozs7Ozs7T0FRRztJQUNHLCtCQUErQixDQUNuQyxlQUFlLEVBQUUsWUFBWSxFQUM3QixJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQ1gsSUFBSSxHQUFFLE1BQVUsR0FDZixPQUFPLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQWE1QjtJQUVEOzs7O09BSUc7SUFDSCxhQUFhLENBQUMsTUFBTSxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FRL0Q7SUE2RUQ7Ozs7T0FJRztJQUNILG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLEdBQUcsT0FBTyxDQUFDLDRCQUE0QixDQUFDLENBUTdFO0NBNkdGIn0=
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nX3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmUvbG9nX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2hFLE9BQU8sRUFBYSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV6RCxPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNHLE9BQU8sRUFJTCxLQUFLLFNBQVMsRUFHZCxLQUFLLFNBQVMsRUFDZCxHQUFHLEVBQ0gsYUFBYSxFQUNkLE1BQU0sb0JBQW9CLENBQUM7QUFHNUIsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbkQ7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQWFqQixPQUFPLENBQUMsRUFBRTtJQUNWLE9BQU8sQ0FBQyxVQUFVO0lBRnBCLFlBQ1UsRUFBRSxFQUFFLGlCQUFpQixFQUNyQixVQUFVLEVBQUUsVUFBVSxFQUM5QixlQUFlLEdBQUUsTUFBYSxFQVUvQjtJQThNRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBUzNDO0lBZ0JELFVBQVUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQTJCOUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0csb0JBQW9CLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLElBQUksR0FBRSxNQUFVLEdBQUcsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FRMUY7SUFFRDs7Ozs7Ozs7T0FRRztJQUNHLCtCQUErQixDQUNuQyxlQUFlLEVBQUUsWUFBWSxFQUM3QixJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQ1gsSUFBSSxHQUFFLE1BQVUsR0FDZixPQUFPLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQWE1QjtJQUVEOzs7O09BSUc7SUFDSCxhQUFhLENBQUMsTUFBTSxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FRL0Q7SUErRkQ7Ozs7T0FJRztJQUNILG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLEdBQUcsT0FBTyxDQUFDLDRCQUE0QixDQUFDLENBUTdFO0NBc0pGIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../src/store/log_store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAa,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAIL,KAAK,SAAS,EAGd,KAAK,SAAS,EACd,GAAG,EACH,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,QAAQ;;IAajB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,UAAU;IAFpB,YACU,EAAE,EAAE,iBAAiB,EACrB,UAAU,EAAE,UAAU,EAC9B,eAAe,GAAE,MAAa,EAU/B;IA4MD;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3C;IAgBD,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA2B9C;IAED;;;;;;;OAOG;IACG,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,GAAE,MAAU,GAAG,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAQ1F;IAED;;;;;;;;OAQG;IACG,+BAA+B,CACnC,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,GAAG,EAAE,EACX,IAAI,GAAE,MAAU,GACf,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAa5B;IAED;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ/D;IA6ED;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAQ7E;CA6GF"}
1
+ {"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../src/store/log_store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAa,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAIL,KAAK,SAAS,EAGd,KAAK,SAAS,EACd,GAAG,EACH,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,QAAQ;;IAajB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,UAAU;IAFpB,YACU,EAAE,EAAE,iBAAiB,EACrB,UAAU,EAAE,UAAU,EAC9B,eAAe,GAAE,MAAa,EAU/B;IA8MD;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3C;IAgBD,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA2B9C;IAED;;;;;;;OAOG;IACG,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,GAAE,MAAU,GAAG,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAQ1F;IAED;;;;;;;;OAQG;IACG,+BAA+B,CACnC,eAAe,EAAE,YAAY,EAC7B,IAAI,EAAE,GAAG,EAAE,EACX,IAAI,GAAE,MAAU,GACf,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAa5B;IAED;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ/D;IA+FD;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAQ7E;CAsJF"}
@@ -7,6 +7,7 @@ import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
7
7
  import { BlockHash } from '@aztec/stdlib/block';
8
8
  import { MAX_LOGS_PER_TAG } from '@aztec/stdlib/interfaces/api-limit';
9
9
  import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
10
+ import { TxHash } from '@aztec/stdlib/tx';
10
11
  /**
11
12
  * A store for logs
12
13
  */ export class LogStore {
@@ -142,6 +143,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
142
143
  await this.#publicLogKeysByBlock.set(block.number, publicTagsInBlock);
143
144
  const publicLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
144
145
  numToUInt32BE(txIndex),
146
+ txEffect.txHash.toBuffer(),
145
147
  numToUInt32BE(txEffect.publicLogs.length),
146
148
  txEffect.publicLogs.map((log)=>log.toBuffer())
147
149
  ].flat()).flat();
@@ -154,6 +156,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
154
156
  const blockHash = await block.hash();
155
157
  const contractClassLogsInBlock = block.body.txEffects.map((txEffect, txIndex)=>[
156
158
  numToUInt32BE(txIndex),
159
+ txEffect.txHash.toBuffer(),
157
160
  numToUInt32BE(txEffect.contractClassLogs.length),
158
161
  txEffect.contractClassLogs.map((log)=>log.toBuffer())
159
162
  ].flat()).flat();
@@ -261,22 +264,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
261
264
  };
262
265
  }
263
266
  const buffer = await this.#publicLogsByBlock.getAsync(blockNumber) ?? Buffer.alloc(0);
264
- const publicLogsInBlock = [
265
- []
266
- ];
267
+ const publicLogsInBlock = [];
267
268
  const reader = new BufferReader(buffer);
268
269
  const blockHash = this.#unpackBlockHash(reader);
269
270
  while(reader.remainingBytes() > 0){
270
271
  const indexOfTx = reader.readNumber();
272
+ const txHash = reader.readObject(TxHash);
271
273
  const numLogsInTx = reader.readNumber();
272
- publicLogsInBlock[indexOfTx] = [];
274
+ publicLogsInBlock[indexOfTx] = {
275
+ txHash,
276
+ logs: []
277
+ };
273
278
  for(let i = 0; i < numLogsInTx; i++){
274
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
279
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
275
280
  }
276
281
  }
277
- const txLogs = publicLogsInBlock[txIndex];
282
+ const txData = publicLogsInBlock[txIndex];
278
283
  const logs = [];
279
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
284
+ const maxLogsHit = this.#accumulatePublicLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
280
285
  return {
281
286
  logs,
282
287
  maxLogsHit
@@ -297,22 +302,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
297
302
  start,
298
303
  end
299
304
  })){
300
- const publicLogsInBlock = [
301
- []
302
- ];
305
+ const publicLogsInBlock = [];
303
306
  const reader = new BufferReader(logBuffer);
304
307
  const blockHash = this.#unpackBlockHash(reader);
305
308
  while(reader.remainingBytes() > 0){
306
309
  const indexOfTx = reader.readNumber();
310
+ const txHash = reader.readObject(TxHash);
307
311
  const numLogsInTx = reader.readNumber();
308
- publicLogsInBlock[indexOfTx] = [];
312
+ publicLogsInBlock[indexOfTx] = {
313
+ txHash,
314
+ logs: []
315
+ };
309
316
  for(let i = 0; i < numLogsInTx; i++){
310
- publicLogsInBlock[indexOfTx].push(reader.readObject(PublicLog));
317
+ publicLogsInBlock[indexOfTx].logs.push(reader.readObject(PublicLog));
311
318
  }
312
319
  }
313
320
  for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++){
314
- const txLogs = publicLogsInBlock[txIndex];
315
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
321
+ const txData = publicLogsInBlock[txIndex];
322
+ maxLogsHit = this.#accumulatePublicLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
316
323
  if (maxLogsHit) {
317
324
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
318
325
  break loopOverBlocks;
@@ -349,22 +356,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
349
356
  };
350
357
  }
351
358
  const contractClassLogsBuffer = await this.#contractClassLogsByBlock.getAsync(blockNumber) ?? Buffer.alloc(0);
352
- const contractClassLogsInBlock = [
353
- []
354
- ];
359
+ const contractClassLogsInBlock = [];
355
360
  const reader = new BufferReader(contractClassLogsBuffer);
356
361
  const blockHash = this.#unpackBlockHash(reader);
357
362
  while(reader.remainingBytes() > 0){
358
363
  const indexOfTx = reader.readNumber();
364
+ const txHash = reader.readObject(TxHash);
359
365
  const numLogsInTx = reader.readNumber();
360
- contractClassLogsInBlock[indexOfTx] = [];
366
+ contractClassLogsInBlock[indexOfTx] = {
367
+ txHash,
368
+ logs: []
369
+ };
361
370
  for(let i = 0; i < numLogsInTx; i++){
362
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
371
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
363
372
  }
364
373
  }
365
- const txLogs = contractClassLogsInBlock[txIndex];
374
+ const txData = contractClassLogsInBlock[txIndex];
366
375
  const logs = [];
367
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
376
+ const maxLogsHit = this.#accumulateContractClassLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
368
377
  return {
369
378
  logs,
370
379
  maxLogsHit
@@ -385,22 +394,24 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
385
394
  start,
386
395
  end
387
396
  })){
388
- const contractClassLogsInBlock = [
389
- []
390
- ];
397
+ const contractClassLogsInBlock = [];
391
398
  const reader = new BufferReader(logBuffer);
392
399
  const blockHash = this.#unpackBlockHash(reader);
393
400
  while(reader.remainingBytes() > 0){
394
401
  const indexOfTx = reader.readNumber();
402
+ const txHash = reader.readObject(TxHash);
395
403
  const numLogsInTx = reader.readNumber();
396
- contractClassLogsInBlock[indexOfTx] = [];
404
+ contractClassLogsInBlock[indexOfTx] = {
405
+ txHash,
406
+ logs: []
407
+ };
397
408
  for(let i = 0; i < numLogsInTx; i++){
398
- contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
409
+ contractClassLogsInBlock[indexOfTx].logs.push(reader.readObject(ContractClassLog));
399
410
  }
400
411
  }
401
412
  for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++){
402
- const txLogs = contractClassLogsInBlock[txIndex];
403
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
413
+ const txData = contractClassLogsInBlock[txIndex];
414
+ maxLogsHit = this.#accumulateContractClassLogs(logs, blockNumber, blockHash, txIndex, txData.txHash, txData.logs, filter);
404
415
  if (maxLogsHit) {
405
416
  this.#log.debug(`Max logs hit at block ${blockNumber}`);
406
417
  break loopOverBlocks;
@@ -412,19 +423,28 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
412
423
  maxLogsHit
413
424
  };
414
425
  }
415
- #accumulateLogs(results, blockNumber, blockHash, txIndex, txLogs, filter = {}) {
426
+ #accumulatePublicLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
416
427
  let maxLogsHit = false;
417
428
  let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
418
429
  for(; logIndex < txLogs.length; logIndex++){
419
430
  const log = txLogs[logIndex];
420
431
  if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
421
- if (log instanceof ContractClassLog) {
422
- results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
423
- } else if (log instanceof PublicLog) {
424
- results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
425
- } else {
426
- throw new Error('Unknown log type');
432
+ results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log));
433
+ if (results.length >= this.#logsMaxPageSize) {
434
+ maxLogsHit = true;
435
+ break;
427
436
  }
437
+ }
438
+ }
439
+ return maxLogsHit;
440
+ }
441
+ #accumulateContractClassLogs(results, blockNumber, blockHash, txIndex, txHash, txLogs, filter = {}) {
442
+ let maxLogsHit = false;
443
+ let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
444
+ for(; logIndex < txLogs.length; logIndex++){
445
+ const log = txLogs[logIndex];
446
+ if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
447
+ results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txHash, txIndex, logIndex), log));
428
448
  if (results.length >= this.#logsMaxPageSize) {
429
449
  maxLogsHit = true;
430
450
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/archiver",
3
- "version": "0.0.1-commit.e3c1de76",
3
+ "version": "0.0.1-commit.e558bd1c",
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.e3c1de76",
69
- "@aztec/blob-lib": "0.0.1-commit.e3c1de76",
70
- "@aztec/constants": "0.0.1-commit.e3c1de76",
71
- "@aztec/epoch-cache": "0.0.1-commit.e3c1de76",
72
- "@aztec/ethereum": "0.0.1-commit.e3c1de76",
73
- "@aztec/foundation": "0.0.1-commit.e3c1de76",
74
- "@aztec/kv-store": "0.0.1-commit.e3c1de76",
75
- "@aztec/l1-artifacts": "0.0.1-commit.e3c1de76",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.e3c1de76",
77
- "@aztec/protocol-contracts": "0.0.1-commit.e3c1de76",
78
- "@aztec/stdlib": "0.0.1-commit.e3c1de76",
79
- "@aztec/telemetry-client": "0.0.1-commit.e3c1de76",
68
+ "@aztec/blob-client": "0.0.1-commit.e558bd1c",
69
+ "@aztec/blob-lib": "0.0.1-commit.e558bd1c",
70
+ "@aztec/constants": "0.0.1-commit.e558bd1c",
71
+ "@aztec/epoch-cache": "0.0.1-commit.e558bd1c",
72
+ "@aztec/ethereum": "0.0.1-commit.e558bd1c",
73
+ "@aztec/foundation": "0.0.1-commit.e558bd1c",
74
+ "@aztec/kv-store": "0.0.1-commit.e558bd1c",
75
+ "@aztec/l1-artifacts": "0.0.1-commit.e558bd1c",
76
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.e558bd1c",
77
+ "@aztec/protocol-contracts": "0.0.1-commit.e558bd1c",
78
+ "@aztec/stdlib": "0.0.1-commit.e558bd1c",
79
+ "@aztec/telemetry-client": "0.0.1-commit.e558bd1c",
80
80
  "lodash.groupby": "^4.6.0",
81
81
  "lodash.omit": "^4.5.0",
82
82
  "tslib": "^2.5.0",
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
3
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
3
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
+ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
6
7
 
7
- import { type Hex, createPublicClient, http } from 'viem';
8
+ import { type Hex, createPublicClient, getAbiItem, http, toEventSelector } from 'viem';
8
9
  import { mainnet } from 'viem/chains';
9
10
 
10
11
  import { CalldataRetriever } from '../calldata_retriever.js';
@@ -111,43 +112,36 @@ async function main() {
111
112
  },
112
113
  );
113
114
 
114
- // Extract L2 block number from transaction logs
115
- logger.info('Decoding transaction to extract L2 block number...');
115
+ // Extract checkpoint number from transaction logs
116
+ logger.info('Decoding transaction to extract checkpoint number...');
116
117
  const receipt = await publicClient.getTransactionReceipt({ hash: txHash });
117
- const l2BlockProposedEvent = receipt.logs.find(log => {
118
+
119
+ // Look for CheckpointProposed event (emitted when a checkpoint is proposed to the rollup)
120
+ // Event signature: CheckpointProposed(uint256 indexed checkpointNumber, bytes32 indexed archive, bytes32[], bytes32, bytes32)
121
+ // Hash: keccak256("CheckpointProposed(uint256,bytes32,bytes32[],bytes32,bytes32)")
122
+ const checkpointProposedEvent = receipt.logs.find(log => {
118
123
  try {
119
- // Try to match the L2BlockProposed event
120
124
  return (
121
125
  log.address.toLowerCase() === rollupAddress.toString().toLowerCase() &&
122
- log.topics[0] === '0x2f1d0e696fa5186494a2f2f89a0e0bcbb15d607f6c5eac4637e07e1e5e7d3c00' // L2BlockProposed event signature
126
+ log.topics[0] === toEventSelector(getAbiItem({ abi: RollupAbi, name: 'CheckpointProposed' }))
123
127
  );
124
128
  } catch {
125
129
  return false;
126
130
  }
127
131
  });
128
132
 
129
- let l2BlockNumber: number;
130
- if (l2BlockProposedEvent && l2BlockProposedEvent.topics[1]) {
131
- // L2 block number is typically the first indexed parameter
132
- l2BlockNumber = Number(BigInt(l2BlockProposedEvent.topics[1]));
133
- logger.info(`L2 Block Number (from event): ${l2BlockNumber}`);
134
- } else {
135
- // Fallback: try to extract from transaction data or use a default
136
- logger.warn('Could not extract L2 block number from event, using block number as fallback');
137
- l2BlockNumber = Number(tx.blockNumber);
133
+ if (!checkpointProposedEvent || checkpointProposedEvent.topics[1] === undefined) {
134
+ throw new Error(`Checkpoint proposed event not found`);
138
135
  }
139
136
 
137
+ const checkpointNumber = CheckpointNumber.fromBigInt(BigInt(checkpointProposedEvent.topics[1]));
138
+
140
139
  logger.info('');
141
- logger.info('Retrieving block header from rollup transaction...');
140
+ logger.info('Retrieving checkpoint from rollup transaction...');
142
141
  logger.info('');
143
142
 
144
143
  // For this script, we don't have blob hashes or expected hashes, so pass empty arrays/objects
145
- const result = await retriever.getCheckpointFromRollupTx(
146
- txHash,
147
- [],
148
- CheckpointNumber.fromBlockNumber(BlockNumber(l2BlockNumber)),
149
- {},
150
- );
144
+ const result = await retriever.getCheckpointFromRollupTx(txHash, [], checkpointNumber, {});
151
145
 
152
146
  logger.info(' Successfully retrieved block header!');
153
147
  logger.info('');
@@ -100,7 +100,7 @@ export async function retrievedToPublishedCheckpoint({
100
100
  }),
101
101
  });
102
102
 
103
- const body = Body.fromTxBlobData(checkpointBlobData.blocks[0].txs);
103
+ const body = Body.fromTxBlobData(blockBlobData.txs);
104
104
 
105
105
  const blobFields = encodeBlockBlobData(blockBlobData);
106
106
  await spongeBlob.absorb(blobFields);
@@ -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(),
@@ -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: [PublicLog[]] = [[]];
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 txLogs = publicLogsInBlock[txIndex];
407
+ const txData = publicLogsInBlock[txIndex];
404
408
 
405
409
  const logs: ExtendedPublicLog[] = [];
406
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
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: [PublicLog[]] = [[]];
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 txLogs = publicLogsInBlock[txIndex];
442
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
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: [ContractClassLog[]] = [[]];
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 txLogs = contractClassLogsInBlock[txIndex];
514
+ const txData = contractClassLogsInBlock[txIndex];
493
515
 
494
516
  const logs: ExtendedContractClassLog[] = [];
495
- const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
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: [ContractClassLog[]] = [[]];
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 txLogs = contractClassLogsInBlock[txIndex];
532
- maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
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
- #accumulateLogs(
544
- results: (ExtendedContractClassLog | ExtendedPublicLog)[],
582
+ #accumulatePublicLogs(
583
+ results: ExtendedPublicLog[],
545
584
  blockNumber: number,
546
585
  blockHash: BlockHash,
547
586
  txIndex: number,
548
- txLogs: (ContractClassLog | PublicLog)[],
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
- if (log instanceof ContractClassLog) {
557
- results.push(
558
- new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log),
559
- );
560
- } else if (log instanceof PublicLog) {
561
- results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
562
- } else {
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;