@aztec/archiver 0.0.1-commit.d3ec352c → 0.0.1-commit.d58ff9d0

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 (236) hide show
  1. package/README.md +164 -22
  2. package/dest/archiver.d.ts +194 -0
  3. package/dest/archiver.d.ts.map +1 -0
  4. package/dest/archiver.js +949 -0
  5. package/dest/config.d.ts +34 -0
  6. package/dest/config.d.ts.map +1 -0
  7. package/dest/config.js +95 -0
  8. package/dest/errors.d.ts +87 -0
  9. package/dest/errors.d.ts.map +1 -0
  10. package/dest/errors.js +129 -0
  11. package/dest/factory.d.ts +16 -10
  12. package/dest/factory.d.ts.map +1 -1
  13. package/dest/factory.js +117 -20
  14. package/dest/index.d.ts +19 -4
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +17 -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/l1/bin/retrieve-calldata.d.ts +3 -0
  21. package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
  22. package/dest/l1/bin/retrieve-calldata.js +152 -0
  23. package/dest/l1/calldata_retriever.d.ts +143 -0
  24. package/dest/l1/calldata_retriever.d.ts.map +1 -0
  25. package/dest/l1/calldata_retriever.js +413 -0
  26. package/dest/l1/data_retrieval.d.ts +102 -0
  27. package/dest/l1/data_retrieval.d.ts.map +1 -0
  28. package/dest/{archiver → l1}/data_retrieval.js +85 -165
  29. package/dest/l1/debug_tx.d.ts +19 -0
  30. package/dest/l1/debug_tx.d.ts.map +1 -0
  31. package/dest/l1/debug_tx.js +73 -0
  32. package/dest/l1/spire_proposer.d.ts +70 -0
  33. package/dest/l1/spire_proposer.d.ts.map +1 -0
  34. package/dest/l1/spire_proposer.js +149 -0
  35. package/dest/l1/trace_tx.d.ts +43 -0
  36. package/dest/l1/trace_tx.d.ts.map +1 -0
  37. package/dest/l1/trace_tx.js +91 -0
  38. package/dest/l1/types.d.ts +12 -0
  39. package/dest/l1/types.d.ts.map +1 -0
  40. package/dest/l1/types.js +3 -0
  41. package/dest/l1/validate_historical_logs.d.ts +23 -0
  42. package/dest/l1/validate_historical_logs.d.ts.map +1 -0
  43. package/dest/l1/validate_historical_logs.js +108 -0
  44. package/dest/l1/validate_trace.d.ts +32 -0
  45. package/dest/l1/validate_trace.d.ts.map +1 -0
  46. package/dest/l1/validate_trace.js +154 -0
  47. package/dest/modules/contract_data_source_adapter.d.ts +25 -0
  48. package/dest/modules/contract_data_source_adapter.d.ts.map +1 -0
  49. package/dest/modules/contract_data_source_adapter.js +32 -0
  50. package/dest/modules/data_source_base.d.ts +112 -0
  51. package/dest/modules/data_source_base.d.ts.map +1 -0
  52. package/dest/modules/data_source_base.js +322 -0
  53. package/dest/modules/data_store_updater.d.ts +105 -0
  54. package/dest/modules/data_store_updater.d.ts.map +1 -0
  55. package/dest/modules/data_store_updater.js +393 -0
  56. package/dest/modules/instrumentation.d.ts +63 -0
  57. package/dest/modules/instrumentation.d.ts.map +1 -0
  58. package/dest/modules/instrumentation.js +166 -0
  59. package/dest/modules/l1_synchronizer.d.ts +77 -0
  60. package/dest/modules/l1_synchronizer.d.ts.map +1 -0
  61. package/dest/modules/l1_synchronizer.js +1381 -0
  62. package/dest/modules/outbox_trees_resolver.d.ts +62 -0
  63. package/dest/modules/outbox_trees_resolver.d.ts.map +1 -0
  64. package/dest/modules/outbox_trees_resolver.js +162 -0
  65. package/dest/modules/validation.d.ts +40 -0
  66. package/dest/modules/validation.d.ts.map +1 -0
  67. package/dest/{archiver → modules}/validation.js +41 -17
  68. package/dest/store/block_store.d.ts +303 -0
  69. package/dest/store/block_store.d.ts.map +1 -0
  70. package/dest/store/block_store.js +1206 -0
  71. package/dest/store/contract_class_store.d.ts +31 -0
  72. package/dest/store/contract_class_store.d.ts.map +1 -0
  73. package/dest/store/contract_class_store.js +98 -0
  74. package/dest/store/contract_instance_store.d.ts +51 -0
  75. package/dest/store/contract_instance_store.d.ts.map +1 -0
  76. package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +55 -3
  77. package/dest/store/data_stores.d.ts +68 -0
  78. package/dest/store/data_stores.d.ts.map +1 -0
  79. package/dest/store/data_stores.js +54 -0
  80. package/dest/store/function_names_cache.d.ts +17 -0
  81. package/dest/store/function_names_cache.d.ts.map +1 -0
  82. package/dest/store/function_names_cache.js +30 -0
  83. package/dest/store/l2_tips_cache.d.ts +25 -0
  84. package/dest/store/l2_tips_cache.d.ts.map +1 -0
  85. package/dest/store/l2_tips_cache.js +26 -0
  86. package/dest/store/log_store.d.ts +59 -0
  87. package/dest/store/log_store.d.ts.map +1 -0
  88. package/dest/store/log_store.js +310 -0
  89. package/dest/store/log_store_codec.d.ts +78 -0
  90. package/dest/store/log_store_codec.d.ts.map +1 -0
  91. package/dest/store/log_store_codec.js +110 -0
  92. package/dest/store/message_store.d.ts +50 -0
  93. package/dest/store/message_store.d.ts.map +1 -0
  94. package/dest/{archiver/kv_archiver_store → store}/message_store.js +66 -23
  95. package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
  96. package/dest/structs/data_retrieval.d.ts.map +1 -0
  97. package/dest/structs/inbox_message.d.ts +15 -0
  98. package/dest/structs/inbox_message.d.ts.map +1 -0
  99. package/dest/{archiver/structs → structs}/inbox_message.js +6 -6
  100. package/dest/structs/published.d.ts +2 -0
  101. package/dest/structs/published.d.ts.map +1 -0
  102. package/dest/test/fake_l1_state.d.ts +214 -0
  103. package/dest/test/fake_l1_state.d.ts.map +1 -0
  104. package/dest/test/fake_l1_state.js +517 -0
  105. package/dest/test/index.d.ts +2 -1
  106. package/dest/test/index.d.ts.map +1 -1
  107. package/dest/test/index.js +4 -1
  108. package/dest/test/mock_archiver.d.ts +5 -6
  109. package/dest/test/mock_archiver.d.ts.map +1 -1
  110. package/dest/test/mock_archiver.js +8 -12
  111. package/dest/test/mock_l1_to_l2_message_source.d.ts +6 -7
  112. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  113. package/dest/test/mock_l1_to_l2_message_source.js +19 -14
  114. package/dest/test/mock_l2_block_source.d.ts +68 -40
  115. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  116. package/dest/test/mock_l2_block_source.js +347 -145
  117. package/dest/test/mock_structs.d.ts +83 -4
  118. package/dest/test/mock_structs.d.ts.map +1 -1
  119. package/dest/test/mock_structs.js +157 -12
  120. package/dest/test/noop_l1_archiver.d.ts +34 -0
  121. package/dest/test/noop_l1_archiver.d.ts.map +1 -0
  122. package/dest/test/noop_l1_archiver.js +88 -0
  123. package/package.json +18 -18
  124. package/src/archiver.ts +785 -0
  125. package/src/config.ts +125 -0
  126. package/src/errors.ts +203 -0
  127. package/src/factory.ts +185 -22
  128. package/src/index.ts +27 -3
  129. package/src/interfaces.ts +9 -0
  130. package/src/l1/README.md +55 -0
  131. package/src/l1/bin/retrieve-calldata.ts +194 -0
  132. package/src/l1/calldata_retriever.ts +529 -0
  133. package/src/{archiver → l1}/data_retrieval.ts +157 -243
  134. package/src/l1/debug_tx.ts +99 -0
  135. package/src/l1/spire_proposer.ts +152 -0
  136. package/src/l1/trace_tx.ts +128 -0
  137. package/src/l1/types.ts +13 -0
  138. package/src/l1/validate_historical_logs.ts +140 -0
  139. package/src/l1/validate_trace.ts +229 -0
  140. package/src/modules/contract_data_source_adapter.ts +46 -0
  141. package/src/modules/data_source_base.ts +466 -0
  142. package/src/modules/data_store_updater.ts +519 -0
  143. package/src/modules/instrumentation.ts +217 -0
  144. package/src/modules/l1_synchronizer.ts +1320 -0
  145. package/src/modules/outbox_trees_resolver.ts +199 -0
  146. package/src/modules/validation.ts +186 -0
  147. package/src/store/block_store.ts +1551 -0
  148. package/src/store/contract_class_store.ts +126 -0
  149. package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +70 -7
  150. package/src/store/data_stores.ts +104 -0
  151. package/src/store/function_names_cache.ts +37 -0
  152. package/src/store/l2_tips_cache.ts +35 -0
  153. package/src/store/log_store.ts +380 -0
  154. package/src/store/log_store_codec.ts +143 -0
  155. package/src/{archiver/kv_archiver_store → store}/message_store.ts +81 -28
  156. package/src/{archiver/structs → structs}/inbox_message.ts +8 -9
  157. package/src/{archiver/structs → structs}/published.ts +0 -1
  158. package/src/test/fake_l1_state.ts +770 -0
  159. package/src/test/fixtures/debug_traceTransaction-multicall3.json +88 -0
  160. package/src/test/fixtures/debug_traceTransaction-multiplePropose.json +153 -0
  161. package/src/test/fixtures/debug_traceTransaction-proxied.json +122 -0
  162. package/src/test/fixtures/trace_transaction-multicall3.json +65 -0
  163. package/src/test/fixtures/trace_transaction-multiplePropose.json +319 -0
  164. package/src/test/fixtures/trace_transaction-proxied.json +128 -0
  165. package/src/test/fixtures/trace_transaction-randomRevert.json +216 -0
  166. package/src/test/index.ts +4 -0
  167. package/src/test/mock_archiver.ts +10 -14
  168. package/src/test/mock_l1_to_l2_message_source.ts +16 -15
  169. package/src/test/mock_l2_block_source.ts +416 -161
  170. package/src/test/mock_structs.ts +292 -14
  171. package/src/test/noop_l1_archiver.ts +158 -0
  172. package/dest/archiver/archiver.d.ts +0 -290
  173. package/dest/archiver/archiver.d.ts.map +0 -1
  174. package/dest/archiver/archiver.js +0 -1434
  175. package/dest/archiver/archiver_store.d.ts +0 -256
  176. package/dest/archiver/archiver_store.d.ts.map +0 -1
  177. package/dest/archiver/archiver_store.js +0 -4
  178. package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
  179. package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
  180. package/dest/archiver/archiver_store_test_suite.js +0 -1289
  181. package/dest/archiver/config.d.ts +0 -21
  182. package/dest/archiver/config.d.ts.map +0 -1
  183. package/dest/archiver/config.js +0 -55
  184. package/dest/archiver/data_retrieval.d.ts +0 -80
  185. package/dest/archiver/data_retrieval.d.ts.map +0 -1
  186. package/dest/archiver/errors.d.ts +0 -12
  187. package/dest/archiver/errors.d.ts.map +0 -1
  188. package/dest/archiver/errors.js +0 -17
  189. package/dest/archiver/index.d.ts +0 -7
  190. package/dest/archiver/index.d.ts.map +0 -1
  191. package/dest/archiver/index.js +0 -4
  192. package/dest/archiver/instrumentation.d.ts +0 -35
  193. package/dest/archiver/instrumentation.d.ts.map +0 -1
  194. package/dest/archiver/instrumentation.js +0 -140
  195. package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -125
  196. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
  197. package/dest/archiver/kv_archiver_store/block_store.js +0 -371
  198. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
  199. package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
  200. package/dest/archiver/kv_archiver_store/contract_class_store.js +0 -120
  201. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
  202. package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
  203. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -169
  204. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
  205. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -296
  206. package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -49
  207. package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
  208. package/dest/archiver/kv_archiver_store/log_store.js +0 -337
  209. package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -39
  210. package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
  211. package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
  212. package/dest/archiver/structs/inbox_message.d.ts +0 -15
  213. package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
  214. package/dest/archiver/structs/published.d.ts +0 -3
  215. package/dest/archiver/structs/published.d.ts.map +0 -1
  216. package/dest/archiver/validation.d.ts +0 -17
  217. package/dest/archiver/validation.d.ts.map +0 -1
  218. package/dest/rpc/index.d.ts +0 -9
  219. package/dest/rpc/index.d.ts.map +0 -1
  220. package/dest/rpc/index.js +0 -15
  221. package/src/archiver/archiver.ts +0 -1880
  222. package/src/archiver/archiver_store.ts +0 -310
  223. package/src/archiver/archiver_store_test_suite.ts +0 -1295
  224. package/src/archiver/config.ts +0 -79
  225. package/src/archiver/errors.ts +0 -26
  226. package/src/archiver/index.ts +0 -6
  227. package/src/archiver/instrumentation.ts +0 -187
  228. package/src/archiver/kv_archiver_store/block_store.ts +0 -482
  229. package/src/archiver/kv_archiver_store/contract_class_store.ts +0 -176
  230. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +0 -423
  231. package/src/archiver/kv_archiver_store/log_store.ts +0 -407
  232. package/src/archiver/validation.ts +0 -124
  233. package/src/rpc/index.ts +0 -16
  234. /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
  235. /package/dest/{archiver/structs → structs}/published.js +0 -0
  236. /package/src/{archiver/structs → structs}/data_retrieval.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,58 +6,68 @@ import {
5
6
  decodeCheckpointBlobDataFromBlobs,
6
7
  encodeBlockBlobData,
7
8
  } from '@aztec/blob-lib';
8
- import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
9
9
  import type {
10
+ CheckpointProposedLog,
10
11
  EpochProofPublicInputArgs,
11
- ViemClient,
12
+ InboxContract,
13
+ MessageSentLog,
14
+ RollupContract,
12
15
  ViemCommitteeAttestations,
13
16
  ViemHeader,
14
- ViemPublicClient,
15
- } from '@aztec/ethereum';
17
+ } from '@aztec/ethereum/contracts';
18
+ import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
16
19
  import { asyncPool } from '@aztec/foundation/async-pool';
17
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
18
- import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
19
- import type { EthAddress } from '@aztec/foundation/eth-address';
20
- import type { ViemSignature } from '@aztec/foundation/eth-signature';
21
- import { Fr } from '@aztec/foundation/fields';
20
+ import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
21
+ import { Fr } from '@aztec/foundation/curves/bn254';
22
+ import { EthAddress } from '@aztec/foundation/eth-address';
22
23
  import { type Logger, createLogger } from '@aztec/foundation/log';
23
- import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
24
- import { Body, CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
25
- import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
24
+ import { RollupAbi } from '@aztec/l1-artifacts';
25
+ import { Body, CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
26
+ import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
26
27
  import { Proof } from '@aztec/stdlib/proofs';
27
28
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
28
29
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
29
30
  import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
30
31
 
31
- import {
32
- type GetContractEventsReturnType,
33
- type GetContractReturnType,
34
- type Hex,
35
- decodeFunctionData,
36
- getAbiItem,
37
- hexToBytes,
38
- multicall3Abi,
39
- } from 'viem';
40
-
41
- import { NoBlobBodiesFoundError } from './errors.js';
42
- import type { DataRetrieval } from './structs/data_retrieval.js';
43
- import type { InboxMessage } from './structs/inbox_message.js';
44
- import type { L1PublishedData } from './structs/published.js';
45
-
46
- export type RetrievedCheckpoint = {
32
+ import { type Hex, decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
33
+
34
+ import { NoBlobBodiesFoundError } from '../errors.js';
35
+ import type { ArchiverInstrumentation } from '../modules/instrumentation.js';
36
+ import type { DataRetrieval } from '../structs/data_retrieval.js';
37
+ import type { InboxMessage } from '../structs/inbox_message.js';
38
+ import { CalldataRetriever } from './calldata_retriever.js';
39
+
40
+ type RetrievedCheckpointBase = {
47
41
  checkpointNumber: CheckpointNumber;
48
42
  archiveRoot: Fr;
43
+ feeAssetPriceModifier: bigint;
49
44
  header: CheckpointHeader;
50
- checkpointBlobData: CheckpointBlobData;
51
45
  l1: L1PublishedData;
52
46
  chainId: Fr;
53
47
  version: Fr;
54
48
  attestations: CommitteeAttestation[];
55
49
  };
56
50
 
51
+ /** Checkpoint data as retrieved from L1 calldata and blob data. */
52
+ export type RetrievedCheckpoint = RetrievedCheckpointBase & { checkpointBlobData: CheckpointBlobData };
53
+
54
+ /** Checkpoint data retrieved from L1 calldata only, without blob data. */
55
+ export type RetrievedCheckpointFromCalldata = RetrievedCheckpointBase & {
56
+ /** Versioned blob hashes from the checkpoint proposed event. */
57
+ blobHashes: Buffer[];
58
+ /** Parent beacon block root from the L1 block, used for blob fetching. */
59
+ parentBeaconBlockRoot: string | undefined;
60
+ /**
61
+ * The exact packed `CommitteeAttestations` tuple from the propose calldata, carried verbatim so that
62
+ * attestation validation can attach byte-faithful invalidation evidence to a negative result.
63
+ */
64
+ verbatimAttestations: ViemCommitteeAttestations;
65
+ };
66
+
57
67
  export async function retrievedToPublishedCheckpoint({
58
68
  checkpointNumber,
59
69
  archiveRoot,
70
+ feeAssetPriceModifier,
60
71
  header: checkpointHeader,
61
72
  checkpointBlobData,
62
73
  l1,
@@ -72,12 +83,12 @@ export async function retrievedToPublishedCheckpoint({
72
83
  .slice(1)
73
84
  .concat([archiveRoot]);
74
85
 
75
- // `blocksBlobData` is created from `decodeCheckpointBlobDataFromBlobs`. An error will be thrown if it can't read a
76
- // field for the `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
86
+ // An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the
87
+ // `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
77
88
  const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!;
78
89
 
79
90
  const spongeBlob = SpongeBlob.init();
80
- const l2Blocks: L2BlockNew[] = [];
91
+ const l2Blocks: L2Block[] = [];
81
92
  for (let i = 0; i < blocksBlobData.length; i++) {
82
93
  const blockBlobData = blocksBlobData[i];
83
94
  const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } =
@@ -108,7 +119,7 @@ export async function retrievedToPublishedCheckpoint({
108
119
  }),
109
120
  });
110
121
 
111
- const body = Body.fromTxBlobData(checkpointBlobData.blocks[0].txs);
122
+ const body = Body.fromTxBlobData(blockBlobData.txs);
112
123
 
113
124
  const blobFields = encodeBlockBlobData(blockBlobData);
114
125
  await spongeBlob.absorb(blobFields);
@@ -127,7 +138,7 @@ export async function retrievedToPublishedCheckpoint({
127
138
 
128
139
  const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
129
140
 
130
- l2Blocks.push(new L2BlockNew(newArchive, header, body));
141
+ l2Blocks.push(new L2Block(newArchive, header, body, checkpointNumber, IndexWithinCheckpoint(i)));
131
142
  }
132
143
 
133
144
  const lastBlock = l2Blocks.at(-1)!;
@@ -136,29 +147,34 @@ export async function retrievedToPublishedCheckpoint({
136
147
  header: checkpointHeader,
137
148
  blocks: l2Blocks,
138
149
  number: checkpointNumber,
150
+ feeAssetPriceModifier: feeAssetPriceModifier,
139
151
  });
140
152
 
141
153
  return PublishedCheckpoint.from({ checkpoint, l1, attestations });
142
154
  }
143
155
 
144
156
  /**
145
- * Fetches new checkpoints.
157
+ * Fetches checkpoint calldata from the rollup contract without fetching blob data.
158
+ * Returns RetrievedCheckpointFromCalldata objects that preserve the information needed for deferred blob fetching.
159
+ * @param rollup - The rollup contract wrapper.
146
160
  * @param publicClient - The viem public client to use for transaction retrieval.
147
- * @param rollupAddress - The address of the rollup contract.
161
+ * @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
148
162
  * @param searchStartBlock - The block number to use for starting the search.
149
163
  * @param searchEndBlock - The highest block number that we should search up to.
150
- * @param expectedNextL2BlockNum - The next L2 block number that we expect to find.
151
- * @returns An array of block; as well as the next eth block to search from.
164
+ * @param instrumentation - The archiver instrumentation instance.
165
+ * @param logger - The logger instance.
166
+ * @returns An array of calldata-only checkpoints.
152
167
  */
153
- export async function retrieveCheckpointsFromRollup(
154
- rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
168
+ export async function retrieveCheckpointCalldataFromRollup(
169
+ rollup: RollupContract,
155
170
  publicClient: ViemPublicClient,
156
- blobSinkClient: BlobSinkClientInterface,
171
+ debugClient: ViemPublicDebugClient,
157
172
  searchStartBlock: bigint,
158
173
  searchEndBlock: bigint,
174
+ instrumentation: ArchiverInstrumentation,
159
175
  logger: Logger = createLogger('archiver'),
160
- ): Promise<RetrievedCheckpoint[]> {
161
- const retrievedCheckpoints: RetrievedCheckpoint[] = [];
176
+ ): Promise<RetrievedCheckpointFromCalldata[]> {
177
+ const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
162
178
 
163
179
  let rollupConstants: { chainId: Fr; version: Fr; targetCommitteeSize: number } | undefined;
164
180
 
@@ -166,15 +182,7 @@ export async function retrieveCheckpointsFromRollup(
166
182
  if (searchStartBlock > searchEndBlock) {
167
183
  break;
168
184
  }
169
- const checkpointProposedLogs = (
170
- await rollup.getEvents.CheckpointProposed(
171
- {},
172
- {
173
- fromBlock: searchStartBlock,
174
- toBlock: searchEndBlock,
175
- },
176
- )
177
- ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
185
+ const checkpointProposedLogs = await rollup.getCheckpointProposedEvents(searchStartBlock, searchEndBlock);
178
186
 
179
187
  if (checkpointProposedLogs.length === 0) {
180
188
  break;
@@ -182,90 +190,108 @@ export async function retrieveCheckpointsFromRollup(
182
190
 
183
191
  const lastLog = checkpointProposedLogs.at(-1)!;
184
192
  logger.debug(
185
- `Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
193
+ `Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
186
194
  );
187
195
 
188
196
  if (rollupConstants === undefined) {
189
197
  const [chainId, version, targetCommitteeSize] = await Promise.all([
190
198
  publicClient.getChainId(),
191
- rollup.read.getVersion(),
192
- rollup.read.getTargetCommitteeSize(),
199
+ rollup.getVersion(),
200
+ rollup.getTargetCommitteeSize(),
193
201
  ]);
194
202
  rollupConstants = {
195
203
  chainId: new Fr(chainId),
196
204
  version: new Fr(version),
197
- targetCommitteeSize: Number(targetCommitteeSize),
205
+ targetCommitteeSize,
198
206
  };
199
207
  }
200
208
 
201
209
  const newCheckpoints = await processCheckpointProposedLogs(
202
210
  rollup,
203
211
  publicClient,
204
- blobSinkClient,
212
+ debugClient,
205
213
  checkpointProposedLogs,
206
214
  rollupConstants,
215
+ instrumentation,
207
216
  logger,
208
217
  );
209
218
  retrievedCheckpoints.push(...newCheckpoints);
210
- searchStartBlock = lastLog.blockNumber! + 1n;
219
+ searchStartBlock = lastLog.l1BlockNumber + 1n;
211
220
  } while (searchStartBlock <= searchEndBlock);
212
221
 
213
- // The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
214
222
  return retrievedCheckpoints.sort((a, b) => Number(a.l1.blockNumber - b.l1.blockNumber));
215
223
  }
216
224
 
217
225
  /**
218
- * Processes newly received CheckpointProposed logs.
219
- * @param rollup - The rollup contract
226
+ * Processes CheckpointProposed logs, fetching only calldata (no blobs).
227
+ * @param rollup - The rollup contract wrapper.
220
228
  * @param publicClient - The viem public client to use for transaction retrieval.
229
+ * @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
221
230
  * @param logs - CheckpointProposed logs.
222
- * @returns - An array of checkpoints.
231
+ * @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
232
+ * @param instrumentation - The archiver instrumentation instance.
233
+ * @param logger - The logger instance.
234
+ * @returns An array of calldata-only checkpoints.
223
235
  */
224
236
  async function processCheckpointProposedLogs(
225
- rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
237
+ rollup: RollupContract,
226
238
  publicClient: ViemPublicClient,
227
- blobSinkClient: BlobSinkClientInterface,
228
- logs: GetContractEventsReturnType<typeof RollupAbi, 'CheckpointProposed'>,
239
+ debugClient: ViemPublicDebugClient,
240
+ logs: CheckpointProposedLog[],
229
241
  { chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
242
+ instrumentation: ArchiverInstrumentation,
230
243
  logger: Logger,
231
- ): Promise<RetrievedCheckpoint[]> {
232
- const retrievedCheckpoints: RetrievedCheckpoint[] = [];
244
+ ): Promise<RetrievedCheckpointFromCalldata[]> {
245
+ const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
246
+ const calldataRetriever = new CalldataRetriever(
247
+ publicClient,
248
+ debugClient,
249
+ targetCommitteeSize,
250
+ instrumentation,
251
+ logger,
252
+ EthAddress.fromString(rollup.address),
253
+ );
254
+
233
255
  await asyncPool(10, logs, async log => {
234
- const checkpointNumber = CheckpointNumber.fromBigInt(log.args.checkpointNumber!);
235
- const archive = log.args.archive!;
236
- const archiveFromChain = await rollup.read.archiveAt([BigInt(checkpointNumber)]);
237
- const blobHashes = log.args.versionedBlobHashes!.map(blobHash => Buffer.from(blobHash.slice(2), 'hex'));
238
-
239
- // The value from the event and contract will match only if the checkpoint is in the chain.
240
- if (archive === archiveFromChain) {
241
- const checkpoint = await getCheckpointFromRollupTx(
242
- publicClient,
243
- blobSinkClient,
244
- log.transactionHash!,
256
+ const checkpointNumber = log.args.checkpointNumber;
257
+ const archive = log.args.archive;
258
+ const archiveFromChain = await rollup.archiveAt(checkpointNumber);
259
+ const blobHashes = log.args.versionedBlobHashes;
260
+
261
+ if (archive.equals(archiveFromChain)) {
262
+ const expectedHashes = {
263
+ attestationsHash: log.args.attestationsHash.toString() as Hex,
264
+ payloadDigest: log.args.payloadDigest.toString() as Hex,
265
+ };
266
+
267
+ const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(
268
+ log.l1TransactionHash,
245
269
  blobHashes,
246
270
  checkpointNumber,
247
- rollup.address,
248
- targetCommitteeSize,
249
- logger,
271
+ expectedHashes,
250
272
  );
273
+ const { timestamp, parentBeaconBlockRoot } = await getL1Block(publicClient, log.l1BlockNumber);
274
+ const l1 = new L1PublishedData(log.l1BlockNumber, timestamp, log.l1BlockHash.toString());
275
+
276
+ retrievedCheckpoints.push({
277
+ ...checkpoint,
278
+ l1,
279
+ chainId,
280
+ version,
281
+ blobHashes,
282
+ parentBeaconBlockRoot,
283
+ });
251
284
 
252
- const l1: L1PublishedData = {
253
- blockNumber: log.blockNumber,
254
- blockHash: log.blockHash,
255
- timestamp: await getL1BlockTime(publicClient, log.blockNumber),
256
- };
257
-
258
- retrievedCheckpoints.push({ ...checkpoint, l1, chainId, version });
259
- logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.transactionHash}`, {
260
- l1BlockNumber: log.blockNumber,
285
+ logger.trace(`Retrieved checkpoint calldata ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
286
+ l1BlockNumber: log.l1BlockNumber,
261
287
  checkpointNumber,
262
288
  archive: archive.toString(),
263
289
  attestations: checkpoint.attestations,
264
290
  });
265
291
  } else {
266
292
  logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
267
- actual: archive,
268
- expected: archiveFromChain,
293
+ actual: archive.toString(),
294
+ expected: archiveFromChain.toString(),
269
295
  });
270
296
  }
271
297
  });
@@ -273,123 +299,29 @@ async function processCheckpointProposedLogs(
273
299
  return retrievedCheckpoints;
274
300
  }
275
301
 
276
- export async function getL1BlockTime(publicClient: ViemPublicClient, blockNumber: bigint): Promise<bigint> {
302
+ export async function getL1Block(
303
+ publicClient: ViemPublicClient,
304
+ blockNumber: bigint,
305
+ ): Promise<{ timestamp: bigint; parentBeaconBlockRoot: string | undefined }> {
277
306
  const block = await publicClient.getBlock({ blockNumber, includeTransactions: false });
278
- return block.timestamp;
279
- }
280
-
281
- /**
282
- * Extracts the first 'propose' method calldata from a multicall3 transaction's data.
283
- * @param multicall3Data - The multicall3 transaction input data
284
- * @param rollupAddress - The address of the rollup contract
285
- * @returns The calldata for the first 'propose' method call to the rollup contract
286
- */
287
- function extractRollupProposeCalldata(multicall3Data: Hex, rollupAddress: Hex): Hex {
288
- const { functionName: multicall3FunctionName, args: multicall3Args } = decodeFunctionData({
289
- abi: multicall3Abi,
290
- data: multicall3Data,
291
- });
292
-
293
- if (multicall3FunctionName !== 'aggregate3') {
294
- throw new Error(`Unexpected multicall3 method called ${multicall3FunctionName}`);
295
- }
296
-
297
- if (multicall3Args.length !== 1) {
298
- throw new Error(`Unexpected number of arguments for multicall3`);
299
- }
300
-
301
- const [calls] = multicall3Args;
302
-
303
- // Find all rollup calls
304
- const rollupAddressLower = rollupAddress.toLowerCase();
305
-
306
- for (let i = 0; i < calls.length; i++) {
307
- const addr = calls[i].target;
308
- if (addr.toLowerCase() !== rollupAddressLower) {
309
- continue;
310
- }
311
- const callData = calls[i].callData;
312
-
313
- try {
314
- const { functionName: rollupFunctionName } = decodeFunctionData({
315
- abi: RollupAbi,
316
- data: callData,
317
- });
318
-
319
- if (rollupFunctionName === 'propose') {
320
- return callData;
321
- }
322
- } catch {
323
- // Skip invalid function data
324
- continue;
325
- }
326
- }
327
-
328
- throw new Error(`Rollup address not found in multicall3 args`);
307
+ return { timestamp: block.timestamp, parentBeaconBlockRoot: block.parentBeaconBlockRoot };
329
308
  }
330
309
 
331
- /**
332
- * Gets checkpoint from the calldata of an L1 transaction.
333
- * Assumes that the checkpoint was published from an EOA.
334
- * TODO: Add retries and error management.
335
- * @param publicClient - The viem public client to use for transaction retrieval.
336
- * @param txHash - Hash of the tx that published it.
337
- * @param checkpointNumber - Checkpoint number.
338
- * @returns Checkpoint from the calldata, deserialized
339
- */
340
- async function getCheckpointFromRollupTx(
341
- publicClient: ViemPublicClient,
342
- blobSinkClient: BlobSinkClientInterface,
343
- txHash: `0x${string}`,
344
- blobHashes: Buffer[], // TODO(md): buffer32?
310
+ export async function getCheckpointBlobDataFromBlobs(
311
+ blobClient: BlobClientInterface,
312
+ blockHash: string,
313
+ blobHashes: Buffer<ArrayBufferLike>[],
345
314
  checkpointNumber: CheckpointNumber,
346
- rollupAddress: Hex,
347
- targetCommitteeSize: number,
348
315
  logger: Logger,
349
- ): Promise<Omit<RetrievedCheckpoint, 'l1' | 'chainId' | 'version'>> {
350
- logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}`);
351
- const { input: forwarderData, blockHash } = await publicClient.getTransaction({ hash: txHash });
352
-
353
- const rollupData = extractRollupProposeCalldata(forwarderData, rollupAddress);
354
- const { functionName: rollupFunctionName, args: rollupArgs } = decodeFunctionData({
355
- abi: RollupAbi,
356
- data: rollupData,
316
+ isHistoricalSync: boolean,
317
+ parentBeaconBlockRoot?: string,
318
+ l1BlockTimestamp?: bigint,
319
+ ): Promise<CheckpointBlobData> {
320
+ const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, {
321
+ isHistoricalSync,
322
+ parentBeaconBlockRoot,
323
+ l1BlockTimestamp,
357
324
  });
358
-
359
- if (rollupFunctionName !== 'propose') {
360
- throw new Error(`Unexpected rollup method called ${rollupFunctionName}`);
361
- }
362
-
363
- const [decodedArgs, packedAttestations, _signers, _blobInput] = rollupArgs! as readonly [
364
- {
365
- archive: Hex;
366
- oracleInput: {
367
- feeAssetPriceModifier: bigint;
368
- };
369
- header: ViemHeader;
370
- txHashes: readonly Hex[];
371
- },
372
- ViemCommitteeAttestations,
373
- Hex[],
374
- ViemSignature,
375
- Hex,
376
- ];
377
-
378
- const attestations = CommitteeAttestation.fromPacked(packedAttestations, targetCommitteeSize);
379
-
380
- logger.trace(`Recovered propose calldata from tx ${txHash}`, {
381
- checkpointNumber,
382
- archive: decodedArgs.archive,
383
- header: decodedArgs.header,
384
- l1BlockHash: blockHash,
385
- blobHashes,
386
- attestations,
387
- packedAttestations,
388
- targetCommitteeSize,
389
- });
390
-
391
- const header = CheckpointHeader.fromViem(decodedArgs.header);
392
- const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
393
325
  if (blobBodies.length === 0) {
394
326
  throw new NoBlobBodiesFoundError(checkpointNumber);
395
327
  }
@@ -397,83 +329,65 @@ async function getCheckpointFromRollupTx(
397
329
  let checkpointBlobData: CheckpointBlobData;
398
330
  try {
399
331
  // Attempt to decode the checkpoint blob data.
400
- checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies.map(b => b.blob));
332
+ checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies);
401
333
  } catch (err: any) {
402
334
  if (err instanceof BlobDeserializationError) {
403
335
  logger.fatal(err.message);
404
336
  } else {
405
337
  logger.fatal('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
406
338
  }
339
+ // Throwing an error since this is most likely caused by a bug.
407
340
  throw err;
408
341
  }
409
342
 
410
- const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
411
-
412
- return {
413
- checkpointNumber,
414
- archiveRoot,
415
- header,
416
- checkpointBlobData,
417
- attestations,
418
- };
343
+ return checkpointBlobData;
419
344
  }
420
345
 
421
346
  /** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
422
347
  export async function retrieveL1ToL2Message(
423
- inbox: GetContractReturnType<typeof InboxAbi, ViemClient>,
424
- leaf: Fr,
425
- fromBlock: bigint,
426
- toBlock: bigint,
348
+ inbox: InboxContract,
349
+ message: InboxMessage,
427
350
  ): Promise<InboxMessage | undefined> {
428
- const logs = await inbox.getEvents.MessageSent({ hash: leaf.toString() }, { fromBlock, toBlock });
429
-
430
- const messages = mapLogsInboxMessage(logs);
431
- return messages.length > 0 ? messages[0] : undefined;
351
+ const log = await inbox.getMessageSentEventByHash(message.leaf.toString(), message.l1BlockNumber);
352
+ return log && mapLogInboxMessage(log);
432
353
  }
433
354
 
434
355
  /**
435
356
  * Fetch L1 to L2 messages.
436
- * @param publicClient - The viem public client to use for transaction retrieval.
437
- * @param inboxAddress - The address of the inbox contract to fetch messages from.
438
- * @param blockUntilSynced - If true, blocks until the archiver has fully synced.
357
+ * @param inbox - The inbox contract wrapper.
439
358
  * @param searchStartBlock - The block number to use for starting the search.
440
359
  * @param searchEndBlock - The highest block number that we should search up to.
441
360
  * @returns An array of InboxLeaf and next eth block to search from.
442
361
  */
443
362
  export async function retrieveL1ToL2Messages(
444
- inbox: GetContractReturnType<typeof InboxAbi, ViemClient>,
363
+ inbox: InboxContract,
445
364
  searchStartBlock: bigint,
446
365
  searchEndBlock: bigint,
447
366
  ): Promise<InboxMessage[]> {
448
367
  const retrievedL1ToL2Messages: InboxMessage[] = [];
449
368
  while (searchStartBlock <= searchEndBlock) {
450
- const messageSentLogs = (
451
- await inbox.getEvents.MessageSent({}, { fromBlock: searchStartBlock, toBlock: searchEndBlock })
452
- ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
369
+ const messageSentLogs = await inbox.getMessageSentEvents(searchStartBlock, searchEndBlock);
453
370
 
454
371
  if (messageSentLogs.length === 0) {
455
372
  break;
456
373
  }
457
374
 
458
- retrievedL1ToL2Messages.push(...mapLogsInboxMessage(messageSentLogs));
459
- searchStartBlock = messageSentLogs.at(-1)!.blockNumber + 1n;
375
+ retrievedL1ToL2Messages.push(...messageSentLogs.map(mapLogInboxMessage));
376
+ searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
460
377
  }
461
378
 
462
379
  return retrievedL1ToL2Messages;
463
380
  }
464
381
 
465
- function mapLogsInboxMessage(logs: GetContractEventsReturnType<typeof InboxAbi, 'MessageSent'>): InboxMessage[] {
466
- return logs.map(log => {
467
- const { index, hash, checkpointNumber, rollingHash } = log.args;
468
- return {
469
- index: index!,
470
- leaf: Fr.fromHexString(hash!),
471
- l1BlockNumber: log.blockNumber,
472
- l1BlockHash: Buffer32.fromString(log.blockHash),
473
- l2BlockNumber: BlockNumber(Number(checkpointNumber!)),
474
- rollingHash: Buffer16.fromString(rollingHash!),
475
- };
476
- });
382
+ function mapLogInboxMessage(log: MessageSentLog): InboxMessage {
383
+ return {
384
+ index: log.args.index,
385
+ leaf: log.args.leaf,
386
+ l1BlockNumber: log.l1BlockNumber,
387
+ l1BlockHash: log.l1BlockHash,
388
+ checkpointNumber: log.args.checkpointNumber,
389
+ rollingHash: log.args.rollingHash,
390
+ };
477
391
  }
478
392
 
479
393
  /** Retrieves L2ProofVerified events from the rollup contract. */
@@ -553,7 +467,7 @@ export async function getProofFromSubmitProofTx(
553
467
  start: bigint;
554
468
  end: bigint;
555
469
  args: EpochProofPublicInputArgs;
556
- fees: readonly Hex[];
470
+ headers: readonly ViemHeader[];
557
471
  proof: Hex;
558
472
  },
559
473
  ];