@aztec/archiver 3.0.3 → 3.9.9-nightly.20260312

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 (212) hide show
  1. package/README.md +156 -22
  2. package/dest/archiver.d.ts +139 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +734 -0
  5. package/dest/{archiver/config.d.ts → config.d.ts} +11 -3
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/{archiver/config.js → config.js} +13 -4
  8. package/dest/errors.d.ts +39 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/errors.js +57 -0
  11. package/dest/factory.d.ts +9 -7
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +93 -11
  14. package/dest/index.d.ts +11 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +9 -3
  17. package/dest/interfaces.d.ts +9 -0
  18. package/dest/interfaces.d.ts.map +1 -0
  19. package/dest/interfaces.js +3 -0
  20. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.d.ts +1 -1
  21. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  22. package/dest/{archiver/l1 → l1}/bin/retrieve-calldata.js +38 -33
  23. package/dest/l1/calldata_retriever.d.ts +135 -0
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/calldata_retriever.js +402 -0
  26. package/dest/l1/data_retrieval.d.ts +85 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver/l1 → l1}/data_retrieval.js +63 -73
  29. package/dest/{archiver/l1 → l1}/debug_tx.d.ts +1 -1
  30. package/dest/l1/debug_tx.d.ts.map +1 -0
  31. package/dest/{archiver/l1 → l1}/spire_proposer.d.ts +5 -5
  32. package/dest/l1/spire_proposer.d.ts.map +1 -0
  33. package/dest/{archiver/l1 → l1}/spire_proposer.js +9 -17
  34. package/dest/{archiver/l1 → l1}/trace_tx.d.ts +1 -1
  35. package/dest/l1/trace_tx.d.ts.map +1 -0
  36. package/dest/l1/types.d.ts +12 -0
  37. package/dest/l1/types.d.ts.map +1 -0
  38. package/dest/{archiver/l1 → l1}/validate_trace.d.ts +6 -3
  39. package/dest/l1/validate_trace.d.ts.map +1 -0
  40. package/dest/{archiver/l1 → l1}/validate_trace.js +14 -10
  41. package/dest/modules/data_source_base.d.ts +89 -0
  42. package/dest/modules/data_source_base.d.ts.map +1 -0
  43. package/dest/modules/data_source_base.js +216 -0
  44. package/dest/modules/data_store_updater.d.ts +83 -0
  45. package/dest/modules/data_store_updater.d.ts.map +1 -0
  46. package/dest/modules/data_store_updater.js +333 -0
  47. package/dest/modules/instrumentation.d.ts +39 -0
  48. package/dest/modules/instrumentation.d.ts.map +1 -0
  49. package/dest/{archiver → modules}/instrumentation.js +33 -67
  50. package/dest/modules/l1_synchronizer.d.ts +71 -0
  51. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  52. package/dest/modules/l1_synchronizer.js +1112 -0
  53. package/dest/modules/validation.d.ts +17 -0
  54. package/dest/modules/validation.d.ts.map +1 -0
  55. package/dest/{archiver → modules}/validation.js +7 -1
  56. package/dest/store/block_store.d.ts +196 -0
  57. package/dest/store/block_store.d.ts.map +1 -0
  58. package/dest/store/block_store.js +755 -0
  59. package/dest/store/contract_class_store.d.ts +18 -0
  60. package/dest/store/contract_class_store.d.ts.map +1 -0
  61. package/dest/{archiver/kv_archiver_store → store}/contract_class_store.js +12 -8
  62. package/dest/store/contract_instance_store.d.ts +24 -0
  63. package/dest/store/contract_instance_store.d.ts.map +1 -0
  64. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +1 -1
  65. package/dest/store/kv_archiver_store.d.ts +353 -0
  66. package/dest/store/kv_archiver_store.d.ts.map +1 -0
  67. package/dest/store/kv_archiver_store.js +464 -0
  68. package/dest/store/l2_tips_cache.d.ts +19 -0
  69. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  70. package/dest/store/l2_tips_cache.js +89 -0
  71. package/dest/store/log_store.d.ts +54 -0
  72. package/dest/store/log_store.d.ts.map +1 -0
  73. package/dest/store/log_store.js +456 -0
  74. package/dest/{archiver/kv_archiver_store → store}/message_store.d.ts +1 -1
  75. package/dest/store/message_store.d.ts.map +1 -0
  76. package/dest/{archiver/kv_archiver_store → store}/message_store.js +1 -1
  77. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  78. package/dest/structs/data_retrieval.d.ts.map +1 -0
  79. package/dest/structs/inbox_message.d.ts +15 -0
  80. package/dest/structs/inbox_message.d.ts.map +1 -0
  81. package/dest/structs/published.d.ts +2 -0
  82. package/dest/structs/published.d.ts.map +1 -0
  83. package/dest/test/fake_l1_state.d.ts +195 -0
  84. package/dest/test/fake_l1_state.d.ts.map +1 -0
  85. package/dest/test/fake_l1_state.js +421 -0
  86. package/dest/test/index.d.ts +2 -1
  87. package/dest/test/index.d.ts.map +1 -1
  88. package/dest/test/index.js +4 -1
  89. package/dest/test/mock_archiver.d.ts +2 -2
  90. package/dest/test/mock_archiver.d.ts.map +1 -1
  91. package/dest/test/mock_archiver.js +3 -3
  92. package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
  93. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  94. package/dest/test/mock_l1_to_l2_message_source.js +12 -3
  95. package/dest/test/mock_l2_block_source.d.ts +47 -17
  96. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  97. package/dest/test/mock_l2_block_source.js +244 -91
  98. package/dest/test/mock_structs.d.ts +81 -3
  99. package/dest/test/mock_structs.d.ts.map +1 -1
  100. package/dest/test/mock_structs.js +152 -7
  101. package/dest/test/noop_l1_archiver.d.ts +26 -0
  102. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  103. package/dest/test/noop_l1_archiver.js +72 -0
  104. package/package.json +16 -17
  105. package/src/archiver.ts +488 -0
  106. package/src/{archiver/config.ts → config.ts} +20 -5
  107. package/src/errors.ts +88 -0
  108. package/src/factory.ts +142 -11
  109. package/src/index.ts +11 -3
  110. package/src/interfaces.ts +9 -0
  111. package/src/l1/README.md +55 -0
  112. package/src/{archiver/l1 → l1}/bin/retrieve-calldata.ts +46 -34
  113. package/src/l1/calldata_retriever.ts +511 -0
  114. package/src/{archiver/l1 → l1}/data_retrieval.ts +93 -99
  115. package/src/{archiver/l1 → l1}/spire_proposer.ts +7 -15
  116. package/src/{archiver/l1 → l1}/validate_trace.ts +25 -7
  117. package/src/modules/data_source_base.ts +328 -0
  118. package/src/modules/data_store_updater.ts +453 -0
  119. package/src/{archiver → modules}/instrumentation.ts +33 -70
  120. package/src/modules/l1_synchronizer.ts +930 -0
  121. package/src/{archiver → modules}/validation.ts +11 -6
  122. package/src/store/block_store.ts +990 -0
  123. package/src/{archiver/kv_archiver_store → store}/contract_class_store.ts +12 -8
  124. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +1 -1
  125. package/src/store/kv_archiver_store.ts +671 -0
  126. package/src/store/l2_tips_cache.ts +89 -0
  127. package/src/store/log_store.ts +637 -0
  128. package/src/{archiver/kv_archiver_store → store}/message_store.ts +1 -1
  129. package/src/{archiver/structs → structs}/published.ts +0 -1
  130. package/src/test/fake_l1_state.ts +657 -0
  131. package/src/test/index.ts +4 -0
  132. package/src/test/mock_archiver.ts +4 -3
  133. package/src/test/mock_l1_to_l2_message_source.ts +10 -4
  134. package/src/test/mock_l2_block_source.ts +294 -98
  135. package/src/test/mock_structs.ts +283 -8
  136. package/src/test/noop_l1_archiver.ts +115 -0
  137. package/dest/archiver/archiver.d.ts +0 -284
  138. package/dest/archiver/archiver.d.ts.map +0 -1
  139. package/dest/archiver/archiver.js +0 -1454
  140. package/dest/archiver/archiver_store.d.ts +0 -249
  141. package/dest/archiver/archiver_store.d.ts.map +0 -1
  142. package/dest/archiver/archiver_store.js +0 -4
  143. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  144. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  145. package/dest/archiver/archiver_store_test_suite.js +0 -1273
  146. package/dest/archiver/config.d.ts.map +0 -1
  147. package/dest/archiver/errors.d.ts +0 -12
  148. package/dest/archiver/errors.d.ts.map +0 -1
  149. package/dest/archiver/errors.js +0 -17
  150. package/dest/archiver/index.d.ts +0 -7
  151. package/dest/archiver/index.d.ts.map +0 -1
  152. package/dest/archiver/index.js +0 -4
  153. package/dest/archiver/instrumentation.d.ts +0 -37
  154. package/dest/archiver/instrumentation.d.ts.map +0 -1
  155. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -125
  156. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  157. package/dest/archiver/kv_archiver_store/block_store.js +0 -371
  158. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  159. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  160. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  161. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  162. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -162
  163. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  164. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -288
  165. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -42
  166. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  167. package/dest/archiver/kv_archiver_store/log_store.js +0 -314
  168. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  169. package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +0 -1
  170. package/dest/archiver/l1/calldata_retriever.d.ts +0 -98
  171. package/dest/archiver/l1/calldata_retriever.d.ts.map +0 -1
  172. package/dest/archiver/l1/calldata_retriever.js +0 -403
  173. package/dest/archiver/l1/data_retrieval.d.ts +0 -87
  174. package/dest/archiver/l1/data_retrieval.d.ts.map +0 -1
  175. package/dest/archiver/l1/debug_tx.d.ts.map +0 -1
  176. package/dest/archiver/l1/spire_proposer.d.ts.map +0 -1
  177. package/dest/archiver/l1/trace_tx.d.ts.map +0 -1
  178. package/dest/archiver/l1/types.d.ts +0 -12
  179. package/dest/archiver/l1/types.d.ts.map +0 -1
  180. package/dest/archiver/l1/validate_trace.d.ts.map +0 -1
  181. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  182. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  183. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  184. package/dest/archiver/structs/published.d.ts +0 -3
  185. package/dest/archiver/structs/published.d.ts.map +0 -1
  186. package/dest/archiver/validation.d.ts +0 -17
  187. package/dest/archiver/validation.d.ts.map +0 -1
  188. package/dest/rpc/index.d.ts +0 -9
  189. package/dest/rpc/index.d.ts.map +0 -1
  190. package/dest/rpc/index.js +0 -15
  191. package/src/archiver/archiver.ts +0 -1906
  192. package/src/archiver/archiver_store.ts +0 -302
  193. package/src/archiver/archiver_store_test_suite.ts +0 -1286
  194. package/src/archiver/errors.ts +0 -26
  195. package/src/archiver/index.ts +0 -6
  196. package/src/archiver/kv_archiver_store/block_store.ts +0 -482
  197. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +0 -413
  198. package/src/archiver/kv_archiver_store/log_store.ts +0 -380
  199. package/src/archiver/l1/README.md +0 -98
  200. package/src/archiver/l1/calldata_retriever.ts +0 -531
  201. package/src/rpc/index.ts +0 -16
  202. /package/dest/{archiver/l1 → l1}/debug_tx.js +0 -0
  203. /package/dest/{archiver/l1 → l1}/trace_tx.js +0 -0
  204. /package/dest/{archiver/l1 → l1}/types.js +0 -0
  205. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  206. /package/dest/{archiver/structs → structs}/inbox_message.js +0 -0
  207. /package/dest/{archiver/structs → structs}/published.js +0 -0
  208. /package/src/{archiver/l1 → l1}/debug_tx.ts +0 -0
  209. /package/src/{archiver/l1 → l1}/trace_tx.ts +0 -0
  210. /package/src/{archiver/l1 → l1}/types.ts +0 -0
  211. /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
  212. /package/src/{archiver/structs → structs}/inbox_message.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import type { BlobClientInterface } from '@aztec/blob-client/client';
1
2
  import {
2
3
  BlobDeserializationError,
3
4
  type CheckpointBlobData,
@@ -5,42 +6,39 @@ import {
5
6
  decodeCheckpointBlobDataFromBlobs,
6
7
  encodeBlockBlobData,
7
8
  } from '@aztec/blob-lib';
8
- import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
9
- import type { EpochProofPublicInputArgs } from '@aztec/ethereum/contracts';
10
- import type { ViemClient, ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
9
+ import type {
10
+ CheckpointProposedLog,
11
+ EpochProofPublicInputArgs,
12
+ InboxContract,
13
+ MessageSentLog,
14
+ RollupContract,
15
+ } from '@aztec/ethereum/contracts';
16
+ import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
11
17
  import { asyncPool } from '@aztec/foundation/async-pool';
12
- import { CheckpointNumber } from '@aztec/foundation/branded-types';
13
- import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
18
+ import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
14
19
  import { Fr } from '@aztec/foundation/curves/bn254';
15
20
  import { EthAddress } from '@aztec/foundation/eth-address';
16
21
  import { type Logger, createLogger } from '@aztec/foundation/log';
17
- import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
18
- import { Body, CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
19
- import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
22
+ import { RollupAbi } from '@aztec/l1-artifacts';
23
+ import { Body, CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
24
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
20
25
  import { Proof } from '@aztec/stdlib/proofs';
21
26
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
22
27
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
23
28
  import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
24
29
 
25
- import {
26
- type GetContractEventsReturnType,
27
- type GetContractReturnType,
28
- type Hex,
29
- decodeFunctionData,
30
- getAbiItem,
31
- hexToBytes,
32
- } from 'viem';
30
+ import { type Hex, decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
33
31
 
34
32
  import { NoBlobBodiesFoundError } from '../errors.js';
35
- import type { ArchiverInstrumentation } from '../instrumentation.js';
33
+ import type { ArchiverInstrumentation } from '../modules/instrumentation.js';
36
34
  import type { DataRetrieval } from '../structs/data_retrieval.js';
37
35
  import type { InboxMessage } from '../structs/inbox_message.js';
38
- import type { L1PublishedData } from '../structs/published.js';
39
36
  import { CalldataRetriever } from './calldata_retriever.js';
40
37
 
41
38
  export type RetrievedCheckpoint = {
42
39
  checkpointNumber: CheckpointNumber;
43
40
  archiveRoot: Fr;
41
+ feeAssetPriceModifier: bigint;
44
42
  header: CheckpointHeader;
45
43
  checkpointBlobData: CheckpointBlobData;
46
44
  l1: L1PublishedData;
@@ -52,6 +50,7 @@ export type RetrievedCheckpoint = {
52
50
  export async function retrievedToPublishedCheckpoint({
53
51
  checkpointNumber,
54
52
  archiveRoot,
53
+ feeAssetPriceModifier,
55
54
  header: checkpointHeader,
56
55
  checkpointBlobData,
57
56
  l1,
@@ -72,7 +71,7 @@ export async function retrievedToPublishedCheckpoint({
72
71
  const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!;
73
72
 
74
73
  const spongeBlob = SpongeBlob.init();
75
- const l2Blocks: L2BlockNew[] = [];
74
+ const l2Blocks: L2Block[] = [];
76
75
  for (let i = 0; i < blocksBlobData.length; i++) {
77
76
  const blockBlobData = blocksBlobData[i];
78
77
  const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } =
@@ -103,7 +102,7 @@ export async function retrievedToPublishedCheckpoint({
103
102
  }),
104
103
  });
105
104
 
106
- const body = Body.fromTxBlobData(checkpointBlobData.blocks[0].txs);
105
+ const body = Body.fromTxBlobData(blockBlobData.txs);
107
106
 
108
107
  const blobFields = encodeBlockBlobData(blockBlobData);
109
108
  await spongeBlob.absorb(blobFields);
@@ -122,7 +121,7 @@ export async function retrievedToPublishedCheckpoint({
122
121
 
123
122
  const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
124
123
 
125
- l2Blocks.push(new L2BlockNew(newArchive, header, body, checkpointNumber, i));
124
+ l2Blocks.push(new L2Block(newArchive, header, body, checkpointNumber, IndexWithinCheckpoint(i)));
126
125
  }
127
126
 
128
127
  const lastBlock = l2Blocks.at(-1)!;
@@ -131,6 +130,7 @@ export async function retrievedToPublishedCheckpoint({
131
130
  header: checkpointHeader,
132
131
  blocks: l2Blocks,
133
132
  number: checkpointNumber,
133
+ feeAssetPriceModifier: feeAssetPriceModifier,
134
134
  });
135
135
 
136
136
  return PublishedCheckpoint.from({ checkpoint, l1, attestations });
@@ -138,28 +138,28 @@ export async function retrievedToPublishedCheckpoint({
138
138
 
139
139
  /**
140
140
  * Fetches new checkpoints.
141
+ * @param rollup - The rollup contract wrapper.
141
142
  * @param publicClient - The viem public client to use for transaction retrieval.
142
143
  * @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
143
- * @param rollupAddress - The address of the rollup contract.
144
+ * @param blobClient - The blob client client for fetching blob data.
144
145
  * @param searchStartBlock - The block number to use for starting the search.
145
146
  * @param searchEndBlock - The highest block number that we should search up to.
146
- * @param expectedNextL2BlockNum - The next L2 block number that we expect to find.
147
- * @returns An array of block; as well as the next eth block to search from.
147
+ * @param contractAddresses - The contract addresses (governanceProposerAddress, slashFactoryAddress, slashingProposerAddress).
148
+ * @param instrumentation - The archiver instrumentation instance.
149
+ * @param logger - The logger instance.
150
+ * @param isHistoricalSync - Whether this is a historical sync.
151
+ * @returns An array of retrieved checkpoints.
148
152
  */
149
153
  export async function retrieveCheckpointsFromRollup(
150
- rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
154
+ rollup: RollupContract,
151
155
  publicClient: ViemPublicClient,
152
156
  debugClient: ViemPublicDebugClient,
153
- blobSinkClient: BlobSinkClientInterface,
157
+ blobClient: BlobClientInterface,
154
158
  searchStartBlock: bigint,
155
159
  searchEndBlock: bigint,
156
- contractAddresses: {
157
- governanceProposerAddress: EthAddress;
158
- slashFactoryAddress?: EthAddress;
159
- slashingProposerAddress: EthAddress;
160
- },
161
160
  instrumentation: ArchiverInstrumentation,
162
161
  logger: Logger = createLogger('archiver'),
162
+ isHistoricalSync: boolean = false,
163
163
  ): Promise<RetrievedCheckpoint[]> {
164
164
  const retrievedCheckpoints: RetrievedCheckpoint[] = [];
165
165
 
@@ -169,15 +169,7 @@ export async function retrieveCheckpointsFromRollup(
169
169
  if (searchStartBlock > searchEndBlock) {
170
170
  break;
171
171
  }
172
- const checkpointProposedLogs = (
173
- await rollup.getEvents.CheckpointProposed(
174
- {},
175
- {
176
- fromBlock: searchStartBlock,
177
- toBlock: searchEndBlock,
178
- },
179
- )
180
- ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
172
+ const checkpointProposedLogs = await rollup.getCheckpointProposedEvents(searchStartBlock, searchEndBlock);
181
173
 
182
174
  if (checkpointProposedLogs.length === 0) {
183
175
  break;
@@ -185,19 +177,19 @@ export async function retrieveCheckpointsFromRollup(
185
177
 
186
178
  const lastLog = checkpointProposedLogs.at(-1)!;
187
179
  logger.debug(
188
- `Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
180
+ `Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
189
181
  );
190
182
 
191
183
  if (rollupConstants === undefined) {
192
184
  const [chainId, version, targetCommitteeSize] = await Promise.all([
193
185
  publicClient.getChainId(),
194
- rollup.read.getVersion(),
195
- rollup.read.getTargetCommitteeSize(),
186
+ rollup.getVersion(),
187
+ rollup.getTargetCommitteeSize(),
196
188
  ]);
197
189
  rollupConstants = {
198
190
  chainId: new Fr(chainId),
199
191
  version: new Fr(version),
200
- targetCommitteeSize: Number(targetCommitteeSize),
192
+ targetCommitteeSize,
201
193
  };
202
194
  }
203
195
 
@@ -205,15 +197,15 @@ export async function retrieveCheckpointsFromRollup(
205
197
  rollup,
206
198
  publicClient,
207
199
  debugClient,
208
- blobSinkClient,
200
+ blobClient,
209
201
  checkpointProposedLogs,
210
202
  rollupConstants,
211
- contractAddresses,
212
203
  instrumentation,
213
204
  logger,
205
+ isHistoricalSync,
214
206
  );
215
207
  retrievedCheckpoints.push(...newCheckpoints);
216
- searchStartBlock = lastLog.blockNumber! + 1n;
208
+ searchStartBlock = lastLog.l1BlockNumber + 1n;
217
209
  } while (searchStartBlock <= searchEndBlock);
218
210
 
219
211
  // The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
@@ -222,26 +214,27 @@ export async function retrieveCheckpointsFromRollup(
222
214
 
223
215
  /**
224
216
  * Processes newly received CheckpointProposed logs.
225
- * @param rollup - The rollup contract
217
+ * @param rollup - The rollup contract wrapper.
226
218
  * @param publicClient - The viem public client to use for transaction retrieval.
227
219
  * @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
220
+ * @param blobClient - The blob client client for fetching blob data.
228
221
  * @param logs - CheckpointProposed logs.
229
- * @returns - An array of checkpoints.
222
+ * @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
223
+ * @param instrumentation - The archiver instrumentation instance.
224
+ * @param logger - The logger instance.
225
+ * @param isHistoricalSync - Whether this is a historical sync.
226
+ * @returns An array of retrieved checkpoints.
230
227
  */
231
228
  async function processCheckpointProposedLogs(
232
- rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
229
+ rollup: RollupContract,
233
230
  publicClient: ViemPublicClient,
234
231
  debugClient: ViemPublicDebugClient,
235
- blobSinkClient: BlobSinkClientInterface,
236
- logs: GetContractEventsReturnType<typeof RollupAbi, 'CheckpointProposed'>,
232
+ blobClient: BlobClientInterface,
233
+ logs: CheckpointProposedLog[],
237
234
  { chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
238
- contractAddresses: {
239
- governanceProposerAddress: EthAddress;
240
- slashFactoryAddress?: EthAddress;
241
- slashingProposerAddress: EthAddress;
242
- },
243
235
  instrumentation: ArchiverInstrumentation,
244
236
  logger: Logger,
237
+ isHistoricalSync: boolean,
245
238
  ): Promise<RetrievedCheckpoint[]> {
246
239
  const retrievedCheckpoints: RetrievedCheckpoint[] = [];
247
240
  const calldataRetriever = new CalldataRetriever(
@@ -250,47 +243,54 @@ async function processCheckpointProposedLogs(
250
243
  targetCommitteeSize,
251
244
  instrumentation,
252
245
  logger,
253
- { ...contractAddresses, rollupAddress: EthAddress.fromString(rollup.address) },
246
+ EthAddress.fromString(rollup.address),
254
247
  );
255
248
 
256
249
  await asyncPool(10, logs, async log => {
257
- const checkpointNumber = CheckpointNumber.fromBigInt(log.args.checkpointNumber!);
258
- const archive = log.args.archive!;
259
- const archiveFromChain = await rollup.read.archiveAt([BigInt(checkpointNumber)]);
260
- const blobHashes = log.args.versionedBlobHashes!.map(blobHash => Buffer.from(blobHash.slice(2), 'hex'));
250
+ const checkpointNumber = log.args.checkpointNumber;
251
+ const archive = log.args.archive;
252
+ const archiveFromChain = await rollup.archiveAt(checkpointNumber);
253
+ const blobHashes = log.args.versionedBlobHashes;
261
254
 
262
255
  // The value from the event and contract will match only if the checkpoint is in the chain.
263
- if (archive === archiveFromChain) {
256
+ if (archive.equals(archiveFromChain)) {
257
+ const expectedHashes = {
258
+ attestationsHash: log.args.attestationsHash.toString() as Hex,
259
+ payloadDigest: log.args.payloadDigest.toString() as Hex,
260
+ };
261
+
264
262
  const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(
265
- log.transactionHash!,
263
+ log.l1TransactionHash,
266
264
  blobHashes,
267
265
  checkpointNumber,
266
+ expectedHashes,
268
267
  );
269
268
  const checkpointBlobData = await getCheckpointBlobDataFromBlobs(
270
- blobSinkClient,
269
+ blobClient,
271
270
  checkpoint.blockHash,
272
271
  blobHashes,
273
272
  checkpointNumber,
274
273
  logger,
274
+ isHistoricalSync,
275
275
  );
276
276
 
277
- const l1: L1PublishedData = {
278
- blockNumber: log.blockNumber,
279
- blockHash: log.blockHash,
280
- timestamp: await getL1BlockTime(publicClient, log.blockNumber),
281
- };
277
+ const l1 = new L1PublishedData(
278
+ log.l1BlockNumber,
279
+ await getL1BlockTime(publicClient, log.l1BlockNumber),
280
+ log.l1BlockHash.toString(),
281
+ );
282
282
 
283
283
  retrievedCheckpoints.push({ ...checkpoint, checkpointBlobData, l1, chainId, version });
284
- logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.transactionHash}`, {
285
- l1BlockNumber: log.blockNumber,
284
+ logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
285
+ l1BlockNumber: log.l1BlockNumber,
286
286
  checkpointNumber,
287
287
  archive: archive.toString(),
288
288
  attestations: checkpoint.attestations,
289
289
  });
290
290
  } else {
291
291
  logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
292
- actual: archive,
293
- expected: archiveFromChain,
292
+ actual: archive.toString(),
293
+ expected: archiveFromChain.toString(),
294
294
  });
295
295
  }
296
296
  });
@@ -304,13 +304,14 @@ export async function getL1BlockTime(publicClient: ViemPublicClient, blockNumber
304
304
  }
305
305
 
306
306
  export async function getCheckpointBlobDataFromBlobs(
307
- blobSinkClient: BlobSinkClientInterface,
307
+ blobClient: BlobClientInterface,
308
308
  blockHash: string,
309
309
  blobHashes: Buffer<ArrayBufferLike>[],
310
310
  checkpointNumber: CheckpointNumber,
311
311
  logger: Logger,
312
+ isHistoricalSync: boolean,
312
313
  ): Promise<CheckpointBlobData> {
313
- const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
314
+ const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, { isHistoricalSync });
314
315
  if (blobBodies.length === 0) {
315
316
  throw new NoBlobBodiesFoundError(checkpointNumber);
316
317
  }
@@ -318,7 +319,7 @@ export async function getCheckpointBlobDataFromBlobs(
318
319
  let checkpointBlobData: CheckpointBlobData;
319
320
  try {
320
321
  // Attempt to decode the checkpoint blob data.
321
- checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies.map(b => b.blob));
322
+ checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies);
322
323
  } catch (err: any) {
323
324
  if (err instanceof BlobDeserializationError) {
324
325
  logger.fatal(err.message);
@@ -334,12 +335,12 @@ export async function getCheckpointBlobDataFromBlobs(
334
335
 
335
336
  /** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
336
337
  export async function retrieveL1ToL2Message(
337
- inbox: GetContractReturnType<typeof InboxAbi, ViemClient>,
338
+ inbox: InboxContract,
338
339
  leaf: Fr,
339
340
  fromBlock: bigint,
340
341
  toBlock: bigint,
341
342
  ): Promise<InboxMessage | undefined> {
342
- const logs = await inbox.getEvents.MessageSent({ hash: leaf.toString() }, { fromBlock, toBlock });
343
+ const logs = await inbox.getMessageSentEventByHash(leaf.toString(), fromBlock, toBlock);
343
344
 
344
345
  const messages = mapLogsInboxMessage(logs);
345
346
  return messages.length > 0 ? messages[0] : undefined;
@@ -347,47 +348,40 @@ export async function retrieveL1ToL2Message(
347
348
 
348
349
  /**
349
350
  * Fetch L1 to L2 messages.
350
- * @param publicClient - The viem public client to use for transaction retrieval.
351
- * @param inboxAddress - The address of the inbox contract to fetch messages from.
352
- * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
351
+ * @param inbox - The inbox contract wrapper.
353
352
  * @param searchStartBlock - The block number to use for starting the search.
354
353
  * @param searchEndBlock - The highest block number that we should search up to.
355
354
  * @returns An array of InboxLeaf and next eth block to search from.
356
355
  */
357
356
  export async function retrieveL1ToL2Messages(
358
- inbox: GetContractReturnType<typeof InboxAbi, ViemClient>,
357
+ inbox: InboxContract,
359
358
  searchStartBlock: bigint,
360
359
  searchEndBlock: bigint,
361
360
  ): Promise<InboxMessage[]> {
362
361
  const retrievedL1ToL2Messages: InboxMessage[] = [];
363
362
  while (searchStartBlock <= searchEndBlock) {
364
- const messageSentLogs = (
365
- await inbox.getEvents.MessageSent({}, { fromBlock: searchStartBlock, toBlock: searchEndBlock })
366
- ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
363
+ const messageSentLogs = await inbox.getMessageSentEvents(searchStartBlock, searchEndBlock);
367
364
 
368
365
  if (messageSentLogs.length === 0) {
369
366
  break;
370
367
  }
371
368
 
372
369
  retrievedL1ToL2Messages.push(...mapLogsInboxMessage(messageSentLogs));
373
- searchStartBlock = messageSentLogs.at(-1)!.blockNumber + 1n;
370
+ searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
374
371
  }
375
372
 
376
373
  return retrievedL1ToL2Messages;
377
374
  }
378
375
 
379
- function mapLogsInboxMessage(logs: GetContractEventsReturnType<typeof InboxAbi, 'MessageSent'>): InboxMessage[] {
380
- return logs.map(log => {
381
- const { index, hash, checkpointNumber, rollingHash } = log.args;
382
- return {
383
- index: index!,
384
- leaf: Fr.fromHexString(hash!),
385
- l1BlockNumber: log.blockNumber,
386
- l1BlockHash: Buffer32.fromString(log.blockHash),
387
- checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber!),
388
- rollingHash: Buffer16.fromString(rollingHash!),
389
- };
390
- });
376
+ function mapLogsInboxMessage(logs: MessageSentLog[]): InboxMessage[] {
377
+ return logs.map(log => ({
378
+ index: log.args.index,
379
+ leaf: log.args.leaf,
380
+ l1BlockNumber: log.l1BlockNumber,
381
+ l1BlockHash: log.l1BlockHash,
382
+ checkpointNumber: log.args.checkpointNumber,
383
+ rollingHash: log.args.rollingHash,
384
+ }));
391
385
  }
392
386
 
393
387
  /** Retrieves L2ProofVerified events from the rollup contract. */
@@ -87,17 +87,17 @@ export async function verifyProxyImplementation(
87
87
  /**
88
88
  * Attempts to decode transaction as a Spire Proposer Multicall.
89
89
  * Spire Proposer is a proxy contract that wraps multiple calls.
90
- * Returns the target address and calldata of the wrapped call if validation succeeds and there is a single call.
90
+ * Returns all wrapped calls if validation succeeds (caller handles hash matching to find the propose call).
91
91
  * @param tx - The transaction to decode
92
92
  * @param publicClient - The viem public client for proxy verification
93
93
  * @param logger - Logger instance
94
- * @returns Object with 'to' and 'data' of the wrapped call, or undefined if validation fails
94
+ * @returns Array of wrapped calls with 'to' and 'data', or undefined if not a valid Spire Proposer tx
95
95
  */
96
- export async function getCallFromSpireProposer(
96
+ export async function getCallsFromSpireProposer(
97
97
  tx: Transaction,
98
98
  publicClient: { getStorageAt: (params: { address: Hex; slot: Hex }) => Promise<Hex | undefined> },
99
99
  logger: Logger,
100
- ): Promise<{ to: Hex; data: Hex } | undefined> {
100
+ ): Promise<{ to: Hex; data: Hex }[] | undefined> {
101
101
  const txHash = tx.hash;
102
102
 
103
103
  try {
@@ -141,17 +141,9 @@ export async function getCallFromSpireProposer(
141
141
 
142
142
  const [calls] = spireArgs;
143
143
 
144
- // Validate exactly ONE call (see ./README.md for rationale)
145
- if (calls.length !== 1) {
146
- logger.warn(`Spire Proposer multicall must contain exactly one call (got ${calls.length})`, { txHash });
147
- return undefined;
148
- }
149
-
150
- const call = calls[0];
151
-
152
- // Successfully extracted the single wrapped call
153
- logger.trace(`Decoded Spire Proposer with single call to ${call.target}`, { txHash });
154
- return { to: call.target, data: call.data };
144
+ // Return all wrapped calls (hash matching in the caller determines which is the propose call)
145
+ logger.trace(`Decoded Spire Proposer with ${calls.length} call(s)`, { txHash });
146
+ return calls.map(call => ({ to: call.target, data: call.data }));
155
147
  } catch (err) {
156
148
  // Any decoding error triggers fallback to trace
157
149
  logger.warn(`Failed to decode Spire Proposer: ${err}`, { txHash });
@@ -1,5 +1,5 @@
1
1
  import type { ViemPublicDebugClient } from '@aztec/ethereum/types';
2
- import { createLogger } from '@aztec/foundation/log';
2
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
3
3
 
4
4
  import type { Hex } from 'viem';
5
5
  import type { ZodSchema } from 'zod';
@@ -7,8 +7,6 @@ import type { ZodSchema } from 'zod';
7
7
  import { callTraceSchema } from './debug_tx.js';
8
8
  import { traceTransactionResponseSchema } from './trace_tx.js';
9
9
 
10
- const logger = createLogger('aztec:archiver:validate_trace');
11
-
12
10
  /**
13
11
  * Helper function to test a trace method with validation
14
12
  *
@@ -17,6 +15,7 @@ const logger = createLogger('aztec:archiver:validate_trace');
17
15
  * @param schema - Zod schema to validate the response
18
16
  * @param method - Name of the RPC method ('debug_traceTransaction' or 'trace_transaction')
19
17
  * @param blockType - Type of block being tested ('recent' or 'old')
18
+ * @param logger - Logger instance
20
19
  * @returns true if the method works and validation passes, false otherwise
21
20
  */
22
21
  async function testTraceMethod(
@@ -25,6 +24,7 @@ async function testTraceMethod(
25
24
  schema: ZodSchema,
26
25
  method: 'debug_traceTransaction' | 'trace_transaction',
27
26
  blockType: string,
27
+ logger: Logger,
28
28
  ): Promise<boolean> {
29
29
  try {
30
30
  // Make request with appropriate params based on method name
@@ -59,9 +59,14 @@ export interface TraceAvailability {
59
59
  * Validates the availability of debug/trace methods on the Ethereum client.
60
60
  *
61
61
  * @param client - The Viem public debug client
62
+ * @param bindings - Optional logger bindings for context
62
63
  * @returns Object indicating which trace methods are available for recent and old blocks
63
64
  */
64
- export async function validateTraceAvailability(client: ViemPublicDebugClient): Promise<TraceAvailability> {
65
+ export async function validateTraceAvailability(
66
+ client: ViemPublicDebugClient,
67
+ bindings?: LoggerBindings,
68
+ ): Promise<TraceAvailability> {
69
+ const logger = createLogger('archiver:validate_trace', bindings);
65
70
  const result: TraceAvailability = {
66
71
  debugTraceRecent: false,
67
72
  traceTransactionRecent: false,
@@ -95,6 +100,7 @@ export async function validateTraceAvailability(client: ViemPublicDebugClient):
95
100
  callTraceSchema,
96
101
  'debug_traceTransaction',
97
102
  'recent',
103
+ logger,
98
104
  );
99
105
 
100
106
  // Test trace_transaction with recent block
@@ -104,6 +110,7 @@ export async function validateTraceAvailability(client: ViemPublicDebugClient):
104
110
  traceTransactionResponseSchema,
105
111
  'trace_transaction',
106
112
  'recent',
113
+ logger,
107
114
  );
108
115
 
109
116
  // Get a block from 512 blocks ago
@@ -132,7 +139,14 @@ export async function validateTraceAvailability(client: ViemPublicDebugClient):
132
139
  const oldTxHash = oldBlock.transactions[0] as Hex;
133
140
 
134
141
  // Test debug_traceTransaction with old block
135
- result.debugTraceOld = await testTraceMethod(client, oldTxHash, callTraceSchema, 'debug_traceTransaction', 'old');
142
+ result.debugTraceOld = await testTraceMethod(
143
+ client,
144
+ oldTxHash,
145
+ callTraceSchema,
146
+ 'debug_traceTransaction',
147
+ 'old',
148
+ logger,
149
+ );
136
150
 
137
151
  // Test trace_transaction with old block
138
152
  result.traceTransactionOld = await testTraceMethod(
@@ -141,6 +155,7 @@ export async function validateTraceAvailability(client: ViemPublicDebugClient):
141
155
  traceTransactionResponseSchema,
142
156
  'trace_transaction',
143
157
  'old',
158
+ logger,
144
159
  );
145
160
  } catch (error) {
146
161
  logger.warn(`Error validating debug_traceTransaction and trace_transaction availability: ${error}`);
@@ -159,15 +174,18 @@ function hasTxs(block: { transactions?: Hex[] }): boolean {
159
174
  *
160
175
  * @param client - The Viem public debug client
161
176
  * @param ethereumAllowNoDebugHosts - If false, throws an error when no trace methods are available
177
+ * @param bindings - Optional logger bindings for context
162
178
  * @throws Error if ethereumAllowNoDebugHosts is false and no trace methods are available
163
179
  */
164
180
  export async function validateAndLogTraceAvailability(
165
181
  client: ViemPublicDebugClient,
166
182
  ethereumAllowNoDebugHosts: boolean,
183
+ bindings?: LoggerBindings,
167
184
  ): Promise<void> {
168
- logger.info('Validating trace/debug method availability...');
185
+ const logger = createLogger('archiver:validate_trace', bindings);
186
+ logger.debug('Validating trace/debug method availability...');
169
187
 
170
- const availability = await validateTraceAvailability(client);
188
+ const availability = await validateTraceAvailability(client, bindings);
171
189
 
172
190
  // Check if we have support for old blocks (either debug or trace)
173
191
  const hasOldBlockSupport = availability.debugTraceOld || availability.traceTransactionOld;