@aztec/stdlib 5.0.0-rc.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/dest/abi/buffer.d.ts +6 -2
  2. package/dest/abi/buffer.d.ts.map +1 -1
  3. package/dest/abi/buffer.js +13 -1
  4. package/dest/avm/avm.js +1 -1
  5. package/dest/aztec-address/index.d.ts +35 -5
  6. package/dest/aztec-address/index.d.ts.map +1 -1
  7. package/dest/aztec-address/index.js +32 -8
  8. package/dest/block/attestation_info.d.ts +1 -1
  9. package/dest/block/attestation_info.d.ts.map +1 -1
  10. package/dest/block/attestation_info.js +7 -4
  11. package/dest/block/l2_block_source.d.ts +44 -27
  12. package/dest/block/l2_block_source.d.ts.map +1 -1
  13. package/dest/block/l2_block_source.js +15 -1
  14. package/dest/block/l2_block_stream/event_driven_l2_block_stream.d.ts +39 -0
  15. package/dest/block/l2_block_stream/event_driven_l2_block_stream.d.ts.map +1 -0
  16. package/dest/block/l2_block_stream/event_driven_l2_block_stream.js +165 -0
  17. package/dest/block/l2_block_stream/index.d.ts +2 -1
  18. package/dest/block/l2_block_stream/index.d.ts.map +1 -1
  19. package/dest/block/l2_block_stream/index.js +1 -0
  20. package/dest/block/l2_block_stream/interfaces.d.ts +40 -6
  21. package/dest/block/l2_block_stream/interfaces.d.ts.map +1 -1
  22. package/dest/block/l2_block_stream/interfaces.js +25 -1
  23. package/dest/block/l2_block_stream/l2_block_stream.d.ts +23 -15
  24. package/dest/block/l2_block_stream/l2_block_stream.d.ts.map +1 -1
  25. package/dest/block/l2_block_stream/l2_block_stream.js +140 -152
  26. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts +10 -2
  27. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts.map +1 -1
  28. package/dest/block/l2_block_stream/l2_tips_store_base.js +33 -15
  29. package/dest/block/proposal/attestations_and_signers.d.ts +19 -1
  30. package/dest/block/proposal/attestations_and_signers.d.ts.map +1 -1
  31. package/dest/block/proposal/attestations_and_signers.js +47 -7
  32. package/dest/block/test/l2_tips_store_test_suite.d.ts +1 -1
  33. package/dest/block/test/l2_tips_store_test_suite.d.ts.map +1 -1
  34. package/dest/block/test/l2_tips_store_test_suite.js +94 -3
  35. package/dest/block/validate_block_result.d.ts +16 -1
  36. package/dest/block/validate_block_result.d.ts.map +1 -1
  37. package/dest/block/validate_block_result.js +18 -3
  38. package/dest/checkpoint/index.d.ts +2 -1
  39. package/dest/checkpoint/index.d.ts.map +1 -1
  40. package/dest/checkpoint/index.js +1 -0
  41. package/dest/checkpoint/simulation_overrides.d.ts +61 -0
  42. package/dest/checkpoint/simulation_overrides.d.ts.map +1 -0
  43. package/dest/checkpoint/simulation_overrides.js +98 -0
  44. package/dest/config/network-consensus-config.d.ts +1 -1
  45. package/dest/config/network-consensus-config.d.ts.map +1 -1
  46. package/dest/config/network-consensus-config.js +2 -10
  47. package/dest/contract/contract_address.d.ts +5 -4
  48. package/dest/contract/contract_address.d.ts.map +1 -1
  49. package/dest/contract/contract_instance.d.ts +16 -2
  50. package/dest/contract/contract_instance.d.ts.map +1 -1
  51. package/dest/contract/contract_instance.js +45 -0
  52. package/dest/contract/interfaces/contract_data_source.d.ts +3 -5
  53. package/dest/contract/interfaces/contract_data_source.d.ts.map +1 -1
  54. package/dest/contract/interfaces/contract_instance.d.ts +71 -10
  55. package/dest/contract/interfaces/contract_instance.d.ts.map +1 -1
  56. package/dest/contract/interfaces/contract_instance.js +7 -2
  57. package/dest/contract/partial_address.d.ts +9 -3
  58. package/dest/contract/partial_address.d.ts.map +1 -1
  59. package/dest/contract/partial_address.js +8 -2
  60. package/dest/database-version/version_manager.d.ts +18 -4
  61. package/dest/database-version/version_manager.d.ts.map +1 -1
  62. package/dest/database-version/version_manager.js +76 -6
  63. package/dest/file-store/factory.d.ts +1 -1
  64. package/dest/file-store/factory.d.ts.map +1 -1
  65. package/dest/file-store/factory.js +7 -0
  66. package/dest/file-store/index.d.ts +2 -1
  67. package/dest/file-store/index.d.ts.map +1 -1
  68. package/dest/file-store/index.js +1 -0
  69. package/dest/file-store/memory.d.ts +24 -0
  70. package/dest/file-store/memory.d.ts.map +1 -0
  71. package/dest/file-store/memory.js +80 -0
  72. package/dest/ha-signing/config.d.ts +19 -5
  73. package/dest/ha-signing/config.d.ts.map +1 -1
  74. package/dest/ha-signing/config.js +9 -3
  75. package/dest/ha-signing/local_config.d.ts +10 -2
  76. package/dest/ha-signing/local_config.d.ts.map +1 -1
  77. package/dest/ha-signing/local_config.js +8 -2
  78. package/dest/hash/hash.d.ts +1 -2
  79. package/dest/hash/hash.d.ts.map +1 -1
  80. package/dest/hash/hash.js +0 -7
  81. package/dest/interfaces/archiver.d.ts +8 -1
  82. package/dest/interfaces/archiver.d.ts.map +1 -1
  83. package/dest/interfaces/archiver.js +3 -2
  84. package/dest/interfaces/aztec-node-admin.d.ts +5 -2
  85. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  86. package/dest/interfaces/aztec-node-debug.d.ts +26 -1
  87. package/dest/interfaces/aztec-node-debug.d.ts.map +1 -1
  88. package/dest/interfaces/aztec-node-debug.js +20 -0
  89. package/dest/interfaces/aztec-node.d.ts +20 -20
  90. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  91. package/dest/interfaces/aztec-node.js +8 -15
  92. package/dest/interfaces/chain_tips.d.ts +8 -47
  93. package/dest/interfaces/chain_tips.d.ts.map +1 -1
  94. package/dest/interfaces/chain_tips.js +1 -6
  95. package/dest/interfaces/checkpoint_parameter.d.ts +3 -3
  96. package/dest/interfaces/checkpoint_parameter.d.ts.map +1 -1
  97. package/dest/interfaces/checkpoint_parameter.js +3 -3
  98. package/dest/interfaces/configs.d.ts +4 -1
  99. package/dest/interfaces/configs.d.ts.map +1 -1
  100. package/dest/interfaces/configs.js +1 -0
  101. package/dest/interfaces/private_kernel_prover.d.ts +9 -11
  102. package/dest/interfaces/private_kernel_prover.d.ts.map +1 -1
  103. package/dest/interfaces/prover-node.d.ts +6 -7
  104. package/dest/interfaces/prover-node.d.ts.map +1 -1
  105. package/dest/interfaces/prover-node.js +15 -10
  106. package/dest/interfaces/proving-job.d.ts +87 -74
  107. package/dest/interfaces/proving-job.d.ts.map +1 -1
  108. package/dest/interfaces/proving-job.js +13 -4
  109. package/dest/interfaces/server_circuit_prover.d.ts +3 -3
  110. package/dest/interfaces/server_circuit_prover.d.ts.map +1 -1
  111. package/dest/interfaces/validator.d.ts +7 -3
  112. package/dest/interfaces/validator.d.ts.map +1 -1
  113. package/dest/interfaces/world_state.d.ts +14 -1
  114. package/dest/interfaces/world_state.d.ts.map +1 -1
  115. package/dest/kernel/hints/find_private_kernel_reset_dimensions.d.ts +8 -2
  116. package/dest/kernel/hints/find_private_kernel_reset_dimensions.d.ts.map +1 -1
  117. package/dest/kernel/hints/find_private_kernel_reset_dimensions.js +12 -74
  118. package/dest/kernel/hints/read_request.js +1 -1
  119. package/dest/kernel/index.d.ts +2 -2
  120. package/dest/kernel/index.d.ts.map +1 -1
  121. package/dest/kernel/index.js +1 -1
  122. package/dest/kernel/log_hash.d.ts +1 -1
  123. package/dest/kernel/log_hash.d.ts.map +1 -1
  124. package/dest/kernel/log_hash.js +2 -2
  125. package/dest/kernel/note_hash.js +1 -1
  126. package/dest/kernel/nullifier.js +1 -1
  127. package/dest/kernel/private_circuit_public_inputs.d.ts +13 -3
  128. package/dest/kernel/private_circuit_public_inputs.d.ts.map +1 -1
  129. package/dest/kernel/private_circuit_public_inputs.js +14 -7
  130. package/dest/kernel/private_context_inputs.d.ts +4 -3
  131. package/dest/kernel/private_context_inputs.d.ts.map +1 -1
  132. package/dest/kernel/private_context_inputs.js +7 -3
  133. package/dest/kernel/private_kernel_circuit_public_inputs.d.ts +7 -1
  134. package/dest/kernel/private_kernel_circuit_public_inputs.d.ts.map +1 -1
  135. package/dest/kernel/private_kernel_circuit_public_inputs.js +7 -0
  136. package/dest/kernel/private_kernel_init_2_circuit_private_inputs.d.ts +2 -3
  137. package/dest/kernel/private_kernel_init_2_circuit_private_inputs.d.ts.map +1 -1
  138. package/dest/kernel/private_kernel_init_2_circuit_private_inputs.js +3 -5
  139. package/dest/kernel/private_kernel_init_3_circuit_private_inputs.d.ts +2 -3
  140. package/dest/kernel/private_kernel_init_3_circuit_private_inputs.d.ts.map +1 -1
  141. package/dest/kernel/private_kernel_init_3_circuit_private_inputs.js +3 -5
  142. package/dest/kernel/private_kernel_init_circuit_private_inputs.d.ts +1 -9
  143. package/dest/kernel/private_kernel_init_circuit_private_inputs.d.ts.map +1 -1
  144. package/dest/kernel/private_kernel_init_circuit_private_inputs.js +2 -6
  145. package/dest/kernel/private_kernel_reset_dimensions.d.ts +7 -8
  146. package/dest/kernel/private_kernel_reset_dimensions.d.ts.map +1 -1
  147. package/dest/kernel/private_kernel_reset_tail_circuit_private_inputs.d.ts +29 -0
  148. package/dest/kernel/private_kernel_reset_tail_circuit_private_inputs.d.ts.map +1 -0
  149. package/dest/kernel/private_kernel_reset_tail_circuit_private_inputs.js +36 -0
  150. package/dest/kernel/private_log_data.d.ts +1 -1
  151. package/dest/kernel/private_log_data.d.ts.map +1 -1
  152. package/dest/kernel/private_log_data.js +1 -1
  153. package/dest/keys/derivation.d.ts +41 -6
  154. package/dest/keys/derivation.d.ts.map +1 -1
  155. package/dest/keys/derivation.js +49 -26
  156. package/dest/logs/app_tagging_secret.d.ts +30 -7
  157. package/dest/logs/app_tagging_secret.d.ts.map +1 -1
  158. package/dest/logs/app_tagging_secret.js +46 -39
  159. package/dest/logs/contract_class_log.d.ts +1 -2
  160. package/dest/logs/contract_class_log.d.ts.map +1 -1
  161. package/dest/logs/contract_class_log.js +0 -4
  162. package/dest/logs/index.d.ts +1 -3
  163. package/dest/logs/index.d.ts.map +1 -1
  164. package/dest/logs/index.js +0 -2
  165. package/dest/logs/shared_secret_derivation.d.ts +19 -6
  166. package/dest/logs/shared_secret_derivation.d.ts.map +1 -1
  167. package/dest/logs/shared_secret_derivation.js +26 -11
  168. package/dest/messaging/l1_to_l2_message.d.ts +23 -2
  169. package/dest/messaging/l1_to_l2_message.d.ts.map +1 -1
  170. package/dest/messaging/l1_to_l2_message.js +36 -11
  171. package/dest/p2p/attestation_utils.d.ts +1 -1
  172. package/dest/p2p/attestation_utils.d.ts.map +1 -1
  173. package/dest/p2p/attestation_utils.js +8 -1
  174. package/dest/p2p/checkpoint_attestation.d.ts +10 -1
  175. package/dest/p2p/checkpoint_attestation.d.ts.map +1 -1
  176. package/dest/p2p/checkpoint_attestation.js +10 -0
  177. package/dest/p2p/checkpoint_proposal.d.ts +2 -1
  178. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  179. package/dest/p2p/consensus_payload.d.ts +2 -1
  180. package/dest/p2p/consensus_payload.d.ts.map +1 -1
  181. package/dest/p2p/signature_utils.d.ts +10 -1
  182. package/dest/p2p/signature_utils.d.ts.map +1 -1
  183. package/dest/p2p/signature_utils.js +9 -1
  184. package/dest/rollup/avm_proof_data.d.ts +3 -3
  185. package/dest/rollup/avm_proof_data.d.ts.map +1 -1
  186. package/dest/rollup/checkpoint_header.d.ts +8 -3
  187. package/dest/rollup/checkpoint_header.d.ts.map +1 -1
  188. package/dest/rollup/checkpoint_header.js +20 -10
  189. package/dest/stats/stats.d.ts +2 -2
  190. package/dest/stats/stats.d.ts.map +1 -1
  191. package/dest/tests/factories.d.ts +1 -1
  192. package/dest/tests/factories.d.ts.map +1 -1
  193. package/dest/tests/factories.js +7 -15
  194. package/dest/trees/nullifier_membership_witness.d.ts +5 -8
  195. package/dest/trees/nullifier_membership_witness.d.ts.map +1 -1
  196. package/dest/trees/nullifier_membership_witness.js +0 -9
  197. package/dest/trees/public_data_witness.d.ts +7 -17
  198. package/dest/trees/public_data_witness.d.ts.map +1 -1
  199. package/dest/trees/public_data_witness.js +0 -27
  200. package/dest/tx/execution_payload.d.ts +1 -1
  201. package/dest/tx/execution_payload.d.ts.map +1 -1
  202. package/dest/tx/execution_payload.js +1 -1
  203. package/dest/tx/global_variable_builder.d.ts +2 -12
  204. package/dest/tx/global_variable_builder.d.ts.map +1 -1
  205. package/dest/tx/global_variables.js +2 -2
  206. package/dest/tx/private_tx_constant_data.d.ts +18 -2
  207. package/dest/tx/private_tx_constant_data.d.ts.map +1 -1
  208. package/dest/tx/private_tx_constant_data.js +13 -4
  209. package/dest/tx/simulated_tx.d.ts +10 -6
  210. package/dest/tx/simulated_tx.d.ts.map +1 -1
  211. package/dest/world-state/genesis_data.d.ts +9 -1
  212. package/dest/world-state/genesis_data.d.ts.map +1 -1
  213. package/dest/world-state/genesis_data.js +1 -0
  214. package/package.json +8 -8
  215. package/src/abi/buffer.ts +13 -1
  216. package/src/avm/avm.ts +1 -1
  217. package/src/aztec-address/index.ts +36 -6
  218. package/src/block/attestation_info.ts +7 -2
  219. package/src/block/l2_block_source.ts +64 -17
  220. package/src/block/l2_block_stream/event_driven_l2_block_stream.ts +207 -0
  221. package/src/block/l2_block_stream/index.ts +1 -0
  222. package/src/block/l2_block_stream/interfaces.ts +60 -6
  223. package/src/block/l2_block_stream/l2_block_stream.ts +201 -178
  224. package/src/block/l2_block_stream/l2_tips_store_base.ts +36 -15
  225. package/src/block/proposal/attestations_and_signers.ts +53 -7
  226. package/src/block/test/l2_tips_store_test_suite.ts +73 -4
  227. package/src/block/validate_block_result.ts +48 -2
  228. package/src/checkpoint/index.ts +1 -0
  229. package/src/checkpoint/simulation_overrides.ts +171 -0
  230. package/src/config/network-consensus-config.ts +2 -13
  231. package/src/contract/contract_address.ts +4 -3
  232. package/src/contract/contract_instance.ts +62 -1
  233. package/src/contract/interfaces/contract_data_source.ts +2 -4
  234. package/src/contract/interfaces/contract_instance.ts +26 -8
  235. package/src/contract/partial_address.ts +8 -2
  236. package/src/database-version/version_manager.ts +96 -6
  237. package/src/file-store/factory.ts +7 -0
  238. package/src/file-store/index.ts +1 -0
  239. package/src/file-store/memory.ts +94 -0
  240. package/src/ha-signing/config.ts +23 -5
  241. package/src/ha-signing/local_config.ts +20 -1
  242. package/src/hash/hash.ts +0 -8
  243. package/src/interfaces/archiver.ts +9 -1
  244. package/src/interfaces/aztec-node-debug.ts +37 -0
  245. package/src/interfaces/aztec-node.ts +30 -33
  246. package/src/interfaces/chain_tips.ts +8 -16
  247. package/src/interfaces/checkpoint_parameter.ts +3 -3
  248. package/src/interfaces/configs.ts +3 -0
  249. package/src/interfaces/private_kernel_prover.ts +10 -12
  250. package/src/interfaces/prover-node.ts +19 -11
  251. package/src/interfaces/proving-job.ts +15 -3
  252. package/src/interfaces/server_circuit_prover.ts +2 -2
  253. package/src/interfaces/world_state.ts +14 -0
  254. package/src/kernel/hints/find_private_kernel_reset_dimensions.ts +22 -112
  255. package/src/kernel/hints/read_request.ts +1 -1
  256. package/src/kernel/index.ts +1 -1
  257. package/src/kernel/log_hash.ts +5 -2
  258. package/src/kernel/note_hash.ts +1 -1
  259. package/src/kernel/nullifier.ts +1 -1
  260. package/src/kernel/private_circuit_public_inputs.ts +12 -1
  261. package/src/kernel/private_context_inputs.ts +10 -3
  262. package/src/kernel/private_kernel_circuit_public_inputs.ts +9 -0
  263. package/src/kernel/private_kernel_init_2_circuit_private_inputs.ts +0 -3
  264. package/src/kernel/private_kernel_init_3_circuit_private_inputs.ts +0 -3
  265. package/src/kernel/private_kernel_init_circuit_private_inputs.ts +0 -6
  266. package/src/kernel/private_kernel_reset_dimensions.ts +15 -5
  267. package/src/kernel/private_kernel_reset_tail_circuit_private_inputs.ts +69 -0
  268. package/src/kernel/private_log_data.ts +4 -1
  269. package/src/keys/derivation.ts +69 -24
  270. package/src/logs/app_tagging_secret.ts +62 -39
  271. package/src/logs/contract_class_log.ts +0 -9
  272. package/src/logs/index.ts +0 -2
  273. package/src/logs/shared_secret_derivation.ts +31 -15
  274. package/src/messaging/l1_to_l2_message.ts +51 -13
  275. package/src/p2p/attestation_utils.ts +8 -1
  276. package/src/p2p/checkpoint_attestation.ts +12 -0
  277. package/src/p2p/signature_utils.ts +9 -0
  278. package/src/rollup/avm_proof_data.ts +2 -2
  279. package/src/rollup/checkpoint_header.ts +16 -2
  280. package/src/stats/stats.ts +2 -2
  281. package/src/tests/factories.ts +6 -12
  282. package/src/trees/nullifier_membership_witness.ts +0 -11
  283. package/src/trees/public_data_witness.ts +0 -31
  284. package/src/tx/execution_payload.ts +2 -1
  285. package/src/tx/global_variable_builder.ts +1 -17
  286. package/src/tx/global_variables.ts +2 -2
  287. package/src/tx/private_tx_constant_data.ts +25 -2
  288. package/src/world-state/genesis_data.ts +10 -0
  289. package/dest/kernel/private_kernel_tail_circuit_private_inputs.d.ts +0 -47
  290. package/dest/kernel/private_kernel_tail_circuit_private_inputs.d.ts.map +0 -1
  291. package/dest/kernel/private_kernel_tail_circuit_private_inputs.js +0 -38
  292. package/dest/logs/message_context.d.ts +0 -27
  293. package/dest/logs/message_context.d.ts.map +0 -1
  294. package/dest/logs/message_context.js +0 -74
  295. package/dest/logs/pending_tagged_log.d.ts +0 -13
  296. package/dest/logs/pending_tagged_log.d.ts.map +0 -1
  297. package/dest/logs/pending_tagged_log.js +0 -34
  298. package/src/kernel/private_kernel_tail_circuit_private_inputs.ts +0 -58
  299. package/src/logs/message_context.ts +0 -76
  300. package/src/logs/pending_tagged_log.ts +0 -39
@@ -94,14 +94,18 @@ export function testL2TipsStore(makeTipsStore: () => Promise<L2TipsStore>) {
94
94
  return new PublishedCheckpoint(checkpoint, L1PublishedData.random(), []);
95
95
  };
96
96
 
97
- /** Creates a chain-checkpointed event with the required block field */
98
- const makeCheckpointedEvent = async (checkpoint: PublishedCheckpoint) => {
99
- const lastBlock = checkpoint.checkpoint.blocks.at(-1)!;
97
+ /** Creates a thin chain-checkpointed event carrying the block + checkpoint ids of the checkpoint's last block. */
98
+ const makeCheckpointedEvent = async (published: PublishedCheckpoint) => {
99
+ const lastBlock = published.checkpoint.blocks.at(-1)!;
100
100
  const blockId: L2BlockId = {
101
101
  number: lastBlock.number,
102
102
  hash: (await lastBlock.hash()).toString(),
103
103
  };
104
- return { type: 'chain-checkpointed' as const, checkpoint, block: blockId };
104
+ const checkpointId = {
105
+ number: published.checkpoint.number,
106
+ hash: published.checkpoint.hash().toString(),
107
+ };
108
+ return { type: 'chain-checkpointed' as const, checkpoint: checkpointId, block: blockId };
105
109
  };
106
110
 
107
111
  it('returns zero if no tips are stored', async () => {
@@ -123,6 +127,71 @@ export function testL2TipsStore(makeTipsStore: () => Promise<L2TipsStore>) {
123
127
  expect(await tipsStore.getL2BlockHash(3)).toEqual(blockHashes.get(3));
124
128
  });
125
129
 
130
+ it('records the proposed tip number and hash from a chain-proposed event', async () => {
131
+ // chain-proposed is the sole writer of proposed-tip history in tips-only mode: no preceding blocks-added.
132
+ await tipsStore.handleBlockStreamEvent({
133
+ type: 'chain-proposed',
134
+ block: { number: BlockNumber(5), hash: new Fr(500).toString() },
135
+ });
136
+
137
+ const tips = await tipsStore.getL2Tips();
138
+ expect(tips.proposed).toEqual({ number: BlockNumber(5), hash: new Fr(500).toString() });
139
+ // The hash is recorded in the same index the walk-back reads, so it resolves as a sparse anchor.
140
+ expect(await tipsStore.getL2BlockHash(5)).toEqual(new Fr(500).toString());
141
+ });
142
+
143
+ it('serves sparse proposed anchors from chain-proposed events for the walk-back', async () => {
144
+ // Two tip-moving polls in tips-only mode, with no blocks in between (sparse history).
145
+ await tipsStore.handleBlockStreamEvent({
146
+ type: 'chain-proposed',
147
+ block: { number: BlockNumber(4), hash: new Fr(400).toString() },
148
+ });
149
+ await tipsStore.handleBlockStreamEvent({
150
+ type: 'chain-proposed',
151
+ block: { number: BlockNumber(9), hash: new Fr(900).toString() },
152
+ });
153
+
154
+ // Both recorded heights resolve; the heights between them were never seen and stay undefined.
155
+ expect(await tipsStore.getL2BlockHash(4)).toEqual(new Fr(400).toString());
156
+ expect(await tipsStore.getL2BlockHash(9)).toEqual(new Fr(900).toString());
157
+ expect(await tipsStore.getL2BlockHash(6)).toBeUndefined();
158
+
159
+ const tips = await tipsStore.getL2Tips();
160
+ expect(tips.proposed).toEqual({ number: BlockNumber(9), hash: new Fr(900).toString() });
161
+ });
162
+
163
+ it('records block-hash witnesses without moving any tip cursor', async () => {
164
+ // Establish a proposed tip at 9 in tips-only fashion (sole writer of proposed history).
165
+ await tipsStore.handleBlockStreamEvent({
166
+ type: 'chain-proposed',
167
+ block: { number: BlockNumber(9), hash: new Fr(900).toString() },
168
+ });
169
+
170
+ // Record sparse witnesses at heights below the tip (e.g. a consumer materializing per-height state).
171
+ await tipsStore.recordBlockHashes([
172
+ { number: BlockNumber(4), hash: new Fr(404).toString() },
173
+ { number: BlockNumber(6), hash: new Fr(606).toString() },
174
+ ]);
175
+
176
+ // Each recorded height resolves; an unrecorded gap stays undefined.
177
+ expect(await tipsStore.getL2BlockHash(4)).toEqual(new Fr(404).toString());
178
+ expect(await tipsStore.getL2BlockHash(6)).toEqual(new Fr(606).toString());
179
+ expect(await tipsStore.getL2BlockHash(5)).toBeUndefined();
180
+
181
+ // No tip cursor moved: the proposed tip is still 9, and every other tier is at genesis.
182
+ const tips = await tipsStore.getL2Tips();
183
+ expect(tips.proposed).toEqual({ number: BlockNumber(9), hash: new Fr(900).toString() });
184
+ expect(tips.checkpointed.block).toEqual(makeTip(0));
185
+ expect(tips.proven.block).toEqual(makeTip(0));
186
+ expect(tips.finalized.block).toEqual(makeTip(0));
187
+ });
188
+
189
+ it('skips witnesses with no hash and tolerates an empty list', async () => {
190
+ await tipsStore.recordBlockHashes([]);
191
+ await tipsStore.recordBlockHashes([{ number: BlockNumber(3), hash: '' }]);
192
+ expect(await tipsStore.getL2BlockHash(3)).toBeUndefined();
193
+ });
194
+
126
195
  it('checkpoints all proposed blocks', async () => {
127
196
  // Propose blocks 1-5
128
197
  const blocks = await Promise.all(times(5, i => makeBlock(i + 1)));
@@ -1,7 +1,9 @@
1
+ import type { ViemCommitteeAttestations } from '@aztec/ethereum/contracts';
1
2
  import { EpochNumber, EpochNumberSchema } from '@aztec/foundation/branded-types';
2
3
  import { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import { type ZodFor, schemas } from '@aztec/foundation/schemas';
4
5
  import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
6
+ import { bufferToHex, hexToBuffer } from '@aztec/foundation/string';
5
7
 
6
8
  import { z } from 'zod';
7
9
 
@@ -30,6 +32,14 @@ export type ValidateCheckpointNegativeResult =
30
32
  attestors: EthAddress[];
31
33
  /** Committee attestations for this checkpoint as they were posted to L1 */
32
34
  attestations: CommitteeAttestation[];
35
+ /**
36
+ * The exact packed `CommitteeAttestations` tuple as posted to L1 calldata, carried verbatim so the
37
+ * invalidation evidence is byte-faithful to the stored `attestationsHash`. A repack via
38
+ * `packAttestations` is not a round-trip inverse of `fromPacked`, so it would diverge from the hash
39
+ * and revert `invalidateBadAttestation`/`invalidateInsufficientAttestations`. Always populated on the
40
+ * calldata validation path, the only production source of invalidation evidence.
41
+ */
42
+ verbatimAttestations: ViemCommitteeAttestations;
33
43
  /** Reason for the checkpoint being invalid: not enough attestations were posted */
34
44
  reason: 'insufficient-attestations';
35
45
  }
@@ -47,6 +57,12 @@ export type ValidateCheckpointNegativeResult =
47
57
  attestors: EthAddress[];
48
58
  /** Committee attestations for this checkpoint as they were posted to L1 */
49
59
  attestations: CommitteeAttestation[];
60
+ /**
61
+ * The exact packed `CommitteeAttestations` tuple as posted to L1 calldata, carried verbatim so the
62
+ * invalidation evidence is byte-faithful to the stored `attestationsHash`. See the same field on the
63
+ * insufficient-attestations variant for why a repack cannot be used.
64
+ */
65
+ verbatimAttestations: ViemCommitteeAttestations;
50
66
  /** Reason for the checkpoint being invalid: an invalid attestation was posted */
51
67
  reason: 'invalid-attestation';
52
68
  /** Index in the attestations array of the invalid attestation posted */
@@ -56,6 +72,12 @@ export type ValidateCheckpointNegativeResult =
56
72
  /** Result type for validating checkpoint attestations */
57
73
  export type ValidateCheckpointResult = { valid: true } | ValidateCheckpointNegativeResult;
58
74
 
75
+ /** Zod schema for the raw packed `CommitteeAttestations` viem tuple (two 0x-prefixed hex strings). */
76
+ const ViemCommitteeAttestationsSchema: ZodFor<ViemCommitteeAttestations> = z.object({
77
+ signatureIndices: schemas.HexStringWith0x,
78
+ signaturesOrAddresses: schemas.HexStringWith0x,
79
+ });
80
+
59
81
  export const ValidateCheckpointResultSchema: ZodFor<ValidateCheckpointResult> = z.union([
60
82
  z.object({ valid: z.literal(true) }),
61
83
  z.object({
@@ -66,6 +88,7 @@ export const ValidateCheckpointResultSchema: ZodFor<ValidateCheckpointResult> =
66
88
  seed: schemas.BigInt,
67
89
  attestors: z.array(schemas.EthAddress),
68
90
  attestations: z.array(CommitteeAttestation.schema),
91
+ verbatimAttestations: ViemCommitteeAttestationsSchema,
69
92
  reason: z.literal('insufficient-attestations'),
70
93
  }),
71
94
  z.object({
@@ -76,6 +99,7 @@ export const ValidateCheckpointResultSchema: ZodFor<ValidateCheckpointResult> =
76
99
  seed: schemas.BigInt,
77
100
  attestors: z.array(schemas.EthAddress),
78
101
  attestations: z.array(CommitteeAttestation.schema),
102
+ verbatimAttestations: ViemCommitteeAttestationsSchema,
79
103
  reason: z.literal('invalid-attestation'),
80
104
  invalidIndex: z.number(),
81
105
  }),
@@ -87,6 +111,8 @@ export function serializeValidateCheckpointResult(result: ValidateCheckpointResu
87
111
  }
88
112
 
89
113
  const checkpointBuffer = serializeCheckpointInfo(result.checkpoint);
114
+ const signatureIndices = hexToBuffer(result.verbatimAttestations.signatureIndices);
115
+ const signaturesOrAddresses = hexToBuffer(result.verbatimAttestations.signaturesOrAddresses);
90
116
  return serializeToBuffer(
91
117
  result.valid,
92
118
  result.reason,
@@ -101,6 +127,10 @@ export function serializeValidateCheckpointResult(result: ValidateCheckpointResu
101
127
  result.attestations.length,
102
128
  result.attestations,
103
129
  result.reason === 'invalid-attestation' ? result.invalidIndex : 0,
130
+ signatureIndices.length,
131
+ signatureIndices,
132
+ signaturesOrAddresses.length,
133
+ signaturesOrAddresses,
104
134
  );
105
135
  }
106
136
 
@@ -118,10 +148,26 @@ export function deserializeValidateCheckpointResult(bufferOrReader: Buffer | Buf
118
148
  const attestors = reader.readVector(EthAddress, MAX_COMMITTEE_SIZE);
119
149
  const attestations = reader.readVector(CommitteeAttestation, MAX_COMMITTEE_SIZE);
120
150
  const invalidIndex = reader.readNumber();
151
+ const verbatimAttestations: ViemCommitteeAttestations = {
152
+ signatureIndices: bufferToHex(reader.readBuffer()),
153
+ signaturesOrAddresses: bufferToHex(reader.readBuffer()),
154
+ };
155
+
121
156
  if (reason === 'insufficient-attestations') {
122
- return { valid, reason, checkpoint, committee, epoch, seed, attestors, attestations };
157
+ return { valid, reason, checkpoint, committee, epoch, seed, attestors, attestations, verbatimAttestations };
123
158
  } else if (reason === 'invalid-attestation') {
124
- return { valid, reason, checkpoint, committee, epoch, seed, attestors, invalidIndex, attestations };
159
+ return {
160
+ valid,
161
+ reason,
162
+ checkpoint,
163
+ committee,
164
+ epoch,
165
+ seed,
166
+ attestors,
167
+ invalidIndex,
168
+ attestations,
169
+ verbatimAttestations,
170
+ };
125
171
  } else {
126
172
  const _: never = reason;
127
173
  throw new Error(`Unknown reason: ${reason}`);
@@ -5,4 +5,5 @@ export * from './checkpoint_reexecution_tracker.js';
5
5
  export * from './digest.js';
6
6
  export * from './previous_checkpoint_out_hashes.js';
7
7
  export * from './published_checkpoint.js';
8
+ export * from './simulation_overrides.js';
8
9
  export * from './validate.js';
@@ -0,0 +1,171 @@
1
+ import {
2
+ type FeeHeader,
3
+ RollupContract,
4
+ SimulationOverridesBuilder,
5
+ type SimulationOverridesPlan,
6
+ } from '@aztec/ethereum/contracts';
7
+ import { CheckpointNumber } from '@aztec/foundation/branded-types';
8
+ import type { Logger } from '@aztec/foundation/log';
9
+
10
+ import type { CoordinationSignatureContext } from '../p2p/signature_utils.js';
11
+ import type { ProposedCheckpointData } from './checkpoint_data.js';
12
+ import { computeCheckpointPayloadDigest } from './digest.js';
13
+
14
+ type CheckpointSimulationOverridesPlanInput = {
15
+ /** Target rollup contract. */
16
+ rollup: RollupContract;
17
+ /** Checkpoint number to be proposed. */
18
+ checkpointNumber: CheckpointNumber;
19
+ /** Logger instance. */
20
+ log: Logger;
21
+ /**
22
+ * The proposed parent checkpoint when pipelining. Its `checkpointNumber` must equal
23
+ * `checkpointNumber - 1`; the helper enforces this. Mutually exclusive with
24
+ * `invalidateToPendingCheckpointNumber`.
25
+ */
26
+ proposedCheckpointData?: ProposedCheckpointData;
27
+ /**
28
+ * The pending checkpoint number we'll end up at after invalidation lands. Mutually exclusive
29
+ * with `proposedCheckpointData`.
30
+ */
31
+ invalidateToPendingCheckpointNumber?: CheckpointNumber;
32
+ /**
33
+ * The real on-chain pending checkpoint number (typically `syncedTo.checkpointedCheckpointNumber`).
34
+ * Used as the snapshot we pin both `pending` and `proven` to avoid prunes in simulation.
35
+ */
36
+ checkpointedCheckpointNumber: CheckpointNumber;
37
+ /**
38
+ * Chain-level consensus signature context. Used to recompute the parent's `payloadDigest` for the
39
+ * pipelined simulation override so it matches what `propose` will write into `tempCheckpointLogs[parent]`
40
+ * once the parent lands.
41
+ */
42
+ signatureContext: CoordinationSignatureContext;
43
+ };
44
+
45
+ /**
46
+ * Builds the SimulationOverridesPlan describing the simulated L1 rollup state for a checkpoint's
47
+ * enqueue-time simulations: `canProposeAt` (in Sequencer.doWork) and the propose-related sims
48
+ * (validateBlockHeader, simulateProposeTx). The plan reflects "as if our pipelined parent
49
+ * checkpoint has landed and any required invalidation has executed" — the gap that needs to be
50
+ * bridged at enqueue time.
51
+ *
52
+ * Pipelining (`proposedCheckpointData`) and invalidation (`invalidateToPendingCheckpointNumber`)
53
+ * are mutually exclusive; passing both throws.
54
+ */
55
+ export async function buildCheckpointSimulationOverridesPlan(
56
+ input: CheckpointSimulationOverridesPlanInput,
57
+ ): Promise<SimulationOverridesPlan | undefined> {
58
+ if (input.proposedCheckpointData && input.invalidateToPendingCheckpointNumber !== undefined) {
59
+ throw new Error(
60
+ 'Error in buildCheckpointSimulationOverridesPlan: proposedCheckpointData and invalidateToPendingCheckpointNumber are mutually exclusive',
61
+ );
62
+ }
63
+
64
+ const builder = new SimulationOverridesBuilder();
65
+ const pendingCheckpointNumber = derivePendingCheckpointNumber(input);
66
+
67
+ // Override the latest checkpoint number when invalidating or pipelining, so our checkpoint
68
+ // follows from it. We also override the proven chain tip so we dont need to worry about
69
+ // prunes kicking in that would break out simulation if there's a prune pending. We always
70
+ // assume that a proof will land in time. If we don't have a pending checkpoint number to force,
71
+ // we still set both tips to the current checkpoint number to avoid the prune trigger.
72
+ const overridenChainTip = pendingCheckpointNumber ?? input.checkpointedCheckpointNumber;
73
+ builder.withChainTips({ pending: overridenChainTip, proven: overridenChainTip });
74
+
75
+ if (input.proposedCheckpointData) {
76
+ const { header, archive, checkpointOutHash, feeAssetPriceModifier } = input.proposedCheckpointData;
77
+ builder.withPendingArchive(archive.root);
78
+ // Override every locally-derivable `tempCheckpointLogs[parent]` field that L1 will eventually
79
+ // write. `slotNumber` is load-bearing for `STFLib.canPruneAtTime`: without it the cell reads
80
+ // slotNumber 0, the contract treats the pending tip as belonging to an expired epoch, and
81
+ // `getEffectivePendingCheckpointNumber` silently collapses pending back to proven — producing
82
+ // a spurious `Rollup__InvalidArchive` against the on-chain genesis archive. The other fields
83
+ // (headerHash, outHash, payloadDigest) are not strictly load-bearing for `canProposeAt` /
84
+ // `validateBlockHeader`, but mirroring the full cell keeps the simulation byte-faithful with
85
+ // what the actual `propose()` send will observe, which is a defense against future reads
86
+ // taking dependencies on them.
87
+ builder.withPendingTempCheckpointLogFields({
88
+ headerHash: header.hash(),
89
+ outHash: checkpointOutHash,
90
+ slotNumber: header.slotNumber,
91
+ payloadDigest: computeCheckpointPayloadDigest({
92
+ header,
93
+ archiveRoot: archive.root,
94
+ feeAssetPriceModifier,
95
+ signatureContext: input.signatureContext,
96
+ }),
97
+ });
98
+
99
+ const feeHeader = await computePipelinedParentFeeHeader({
100
+ checkpointNumber: input.checkpointNumber,
101
+ proposedCheckpointData: input.proposedCheckpointData,
102
+ rollup: input.rollup,
103
+ log: input.log,
104
+ });
105
+ if (feeHeader) {
106
+ builder.withPendingFeeHeader(feeHeader);
107
+ }
108
+ }
109
+
110
+ return builder.build();
111
+ }
112
+
113
+ function derivePendingCheckpointNumber(input: CheckpointSimulationOverridesPlanInput): CheckpointNumber | undefined {
114
+ if (input.invalidateToPendingCheckpointNumber !== undefined) {
115
+ return input.invalidateToPendingCheckpointNumber;
116
+ }
117
+ if (!input.proposedCheckpointData) {
118
+ return undefined;
119
+ }
120
+ if (input.checkpointNumber < 1) {
121
+ throw new Error(`Cannot build simulation override for checkpoint ${input.checkpointNumber}: no parent exists`);
122
+ }
123
+ const expectedParent = CheckpointNumber(input.checkpointNumber - 1);
124
+ if (input.proposedCheckpointData.checkpointNumber !== expectedParent) {
125
+ throw new Error(
126
+ `Cannot build simulation override for checkpoint ${input.checkpointNumber}: proposedCheckpointData.checkpointNumber (${input.proposedCheckpointData.checkpointNumber}) does not match expected parent ${expectedParent}`,
127
+ );
128
+ }
129
+ return expectedParent;
130
+ }
131
+
132
+ type PipelinedParentFeeHeaderInput = {
133
+ checkpointNumber: CheckpointNumber;
134
+ proposedCheckpointData: ProposedCheckpointData;
135
+ rollup: RollupContract;
136
+ log: Logger;
137
+ };
138
+
139
+ /**
140
+ * Derives the pending parent fee header used during pipelined proposal simulation. Returns
141
+ * `undefined` only when no grandparent exists (i.e. the proposed parent is the genesis
142
+ * checkpoint); all other failure modes (missing grandparent state, missing fee header, RPC
143
+ * errors) throw so callers don't silently desync the fee-header override.
144
+ */
145
+ export async function computePipelinedParentFeeHeader(
146
+ input: PipelinedParentFeeHeaderInput,
147
+ ): Promise<FeeHeader | undefined> {
148
+ if (input.checkpointNumber < 2) {
149
+ return undefined;
150
+ }
151
+
152
+ const grandparentCheckpointNumber = CheckpointNumber(input.checkpointNumber - 2);
153
+
154
+ const [grandparentCheckpoint, manaTarget] = await Promise.all([
155
+ input.rollup.getCheckpoint(grandparentCheckpointNumber),
156
+ input.rollup.getManaTarget(),
157
+ ]);
158
+
159
+ if (!grandparentCheckpoint?.feeHeader) {
160
+ throw new Error(
161
+ `Grandparent checkpoint or feeHeader missing for checkpoint ${grandparentCheckpointNumber.toString()}`,
162
+ );
163
+ }
164
+
165
+ return RollupContract.computeChildFeeHeader(
166
+ grandparentCheckpoint.feeHeader,
167
+ input.proposedCheckpointData.totalManaUsed,
168
+ input.proposedCheckpointData.feeAssetPriceModifier,
169
+ manaTarget,
170
+ );
171
+ }
@@ -1,4 +1,4 @@
1
- import { type L1ContractsConfig, l1ContractsConfigMappings } from '@aztec/ethereum/config';
1
+ import { type L1ContractsConfig, l1ContractsConfigMappings, validateSlotDurations } from '@aztec/ethereum/config';
2
2
  import { type EnvVar, pickConfigMappings } from '@aztec/foundation/config';
3
3
 
4
4
  import type { SequencerConfig } from '../interfaces/configs.js';
@@ -156,21 +156,10 @@ export function validateNetworkConsensusConfig(config: NetworkConsensusConfig):
156
156
  return errors;
157
157
  }
158
158
 
159
- if (config.ethereumSlotDuration <= 0) {
160
- errors.push(`ethereumSlotDuration must be positive (got ${config.ethereumSlotDuration})`);
161
- }
159
+ errors.push(...validateSlotDurations(config));
162
160
  if (config.blockDurationMs <= 0) {
163
161
  errors.push(`blockDurationMs must be positive (got ${config.blockDurationMs})`);
164
162
  }
165
- if (config.aztecSlotDuration <= 0) {
166
- errors.push(`aztecSlotDuration must be positive (got ${config.aztecSlotDuration})`);
167
- }
168
- if (config.ethereumSlotDuration > 0 && config.aztecSlotDuration % config.ethereumSlotDuration !== 0) {
169
- errors.push(
170
- `aztecSlotDuration (${config.aztecSlotDuration}s) must be a multiple of ethereumSlotDuration ` +
171
- `(${config.ethereumSlotDuration}s)`,
172
- );
173
- }
174
163
  if (config.blockDurationMs / 1000 > config.aztecSlotDuration) {
175
164
  errors.push(
176
165
  `blockDurationMs (${config.blockDurationMs}ms) exceeds aztecSlotDuration (${config.aztecSlotDuration}s)`,
@@ -6,7 +6,8 @@ import { type FunctionAbi, FunctionSelector, encodeArguments } from '../abi/inde
6
6
  import type { AztecAddress } from '../aztec-address/index.js';
7
7
  import { computeVarArgsHash } from '../hash/hash.js';
8
8
  import { computeAddress } from '../keys/index.js';
9
- import type { ContractInstance } from './interfaces/contract_instance.js';
9
+ import type { ContractInstance, ContractInstancePreimage } from './interfaces/contract_instance.js';
10
+ import type { PartialAddress } from './partial_address.js';
10
11
 
11
12
  // TODO(@spalladino): Review all generator indices in this file
12
13
 
@@ -21,7 +22,7 @@ import type { ContractInstance } from './interfaces/contract_instance.js';
21
22
  */
22
23
  export async function computeContractAddressFromInstance(
23
24
  instance:
24
- | ContractInstance
25
+ | ContractInstancePreimage
25
26
  | ({ originalContractClassId: Fr; saltedInitializationHash: Fr } & Pick<ContractInstance, 'publicKeys'>),
26
27
  ): Promise<AztecAddress> {
27
28
  const partialAddress = await computePartialAddress(instance);
@@ -36,7 +37,7 @@ export async function computePartialAddress(
36
37
  instance:
37
38
  | Pick<ContractInstance, 'originalContractClassId' | 'initializationHash' | 'salt' | 'deployer' | 'immutablesHash'>
38
39
  | { originalContractClassId: Fr; saltedInitializationHash: Fr },
39
- ): Promise<Fr> {
40
+ ): Promise<PartialAddress> {
40
41
  const saltedInitializationHash =
41
42
  'saltedInitializationHash' in instance
42
43
  ? instance.saltedInitializationHash
@@ -18,7 +18,12 @@ import {
18
18
  computeInitializationHash,
19
19
  computeInitializationHashFromEncodedArgs,
20
20
  } from './contract_address.js';
21
- import type { ContractInstance, ContractInstanceWithAddress } from './interfaces/contract_instance.js';
21
+ import type {
22
+ ContractInstance,
23
+ ContractInstancePreimage,
24
+ ContractInstancePreimageWithAddress,
25
+ ContractInstanceWithAddress,
26
+ } from './interfaces/contract_instance.js';
22
27
 
23
28
  const VERSION = 2 as const;
24
29
 
@@ -115,6 +120,62 @@ export class SerializableContractInstance {
115
120
  }
116
121
  }
117
122
 
123
+ export class SerializableContractInstancePreimage {
124
+ public readonly version = VERSION;
125
+ public readonly salt: Fr;
126
+ public readonly deployer: AztecAddress;
127
+ public readonly originalContractClassId: Fr;
128
+ public readonly initializationHash: Fr;
129
+ public readonly immutablesHash: Fr;
130
+ public readonly publicKeys: PublicKeys;
131
+
132
+ constructor(instance: ContractInstancePreimage) {
133
+ if (instance.version !== VERSION) {
134
+ throw new Error(`Unexpected contract class version ${instance.version}`);
135
+ }
136
+ this.salt = instance.salt;
137
+ this.deployer = instance.deployer;
138
+ this.originalContractClassId = instance.originalContractClassId;
139
+ this.initializationHash = instance.initializationHash;
140
+ this.immutablesHash = instance.immutablesHash;
141
+ this.publicKeys = instance.publicKeys;
142
+ }
143
+
144
+ public toBuffer() {
145
+ return serializeToBuffer(
146
+ numToUInt8(this.version),
147
+ this.salt,
148
+ this.deployer,
149
+ this.originalContractClassId,
150
+ this.initializationHash,
151
+ this.immutablesHash,
152
+ this.publicKeys,
153
+ );
154
+ }
155
+
156
+ /** Returns a copy of this object with its address included. */
157
+ withAddress(address: AztecAddress): ContractInstancePreimageWithAddress {
158
+ return { ...this, address };
159
+ }
160
+
161
+ static fromBuffer(bufferOrReader: Buffer | BufferReader): SerializableContractInstancePreimage {
162
+ const reader = BufferReader.asReader(bufferOrReader);
163
+ const version = reader.readUInt8();
164
+ if (version !== VERSION) {
165
+ throw new Error(`Unexpected contract instance preimage version ${version}`);
166
+ }
167
+ return new SerializableContractInstancePreimage({
168
+ version: VERSION,
169
+ salt: reader.readObject(Fr),
170
+ deployer: reader.readObject(AztecAddress),
171
+ originalContractClassId: reader.readObject(Fr),
172
+ initializationHash: reader.readObject(Fr),
173
+ immutablesHash: reader.readObject(Fr),
174
+ publicKeys: reader.readObject(PublicKeys),
175
+ });
176
+ }
177
+ }
178
+
118
179
  /**
119
180
  * Generates a Contract Instance from some instantiation params.
120
181
  * @param artifact - The account contract build artifact.
@@ -25,11 +25,9 @@ export interface ContractDataSource {
25
25
  /**
26
26
  * Returns a publicly deployed contract instance given its address.
27
27
  * @param address - Address of the deployed contract.
28
- * @param timestamp - Timestamp at which to retrieve the contract instance. If not provided, the latest block should
29
- * be used.
30
- * TODO(#15170): Fix the implementations ignoring the timestamp param and make timestamp required.
28
+ * @param timestamp - Timestamp at which to resolve the contract instance's current class id.
31
29
  */
32
- getContract(address: AztecAddress, timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined>;
30
+ getContract(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined>;
33
31
 
34
32
  /**
35
33
  * Returns the list of all class ids known.
@@ -9,19 +9,19 @@ import { schemas, zodFor } from '../../schemas/index.js';
9
9
  const VERSION = 2 as const;
10
10
 
11
11
  /**
12
- * A contract instance is a concrete deployment of a contract class. It always references a contract class,
13
- * which dictates what code it executes when called. It has state (both private and public), as well as an
14
- * address that acts as its identifier. It can be called into. It may have encryption and nullifying public keys.
12
+ * The address preimage of a contract instance: the immutable data that hashes to its address, i.e. everything a
13
+ * contract deployment commits to.
14
+ *
15
+ * Note that `originaContractClassId` is not necessarily the instance's _current_ class id, in case of upgrades: that
16
+ * one is not part of the preimage and is instead derived from chain state.
15
17
  */
16
- export interface ContractInstance {
18
+ export interface ContractInstancePreimage {
17
19
  /** Version identifier. Initially one, bumped for any changes to the contract instance struct. */
18
20
  version: typeof VERSION;
19
21
  /** User-generated pseudorandom value for uniqueness. */
20
22
  salt: Fr;
21
23
  /** Optional deployer address or zero if this was a universal deploy. */
22
24
  deployer: AztecAddress;
23
- /** Identifier of the contract class for this instance. */
24
- currentContractClassId: Fr;
25
25
  /** Identifier of the original (at deployment) contract class for this instance */
26
26
  originalContractClassId: Fr;
27
27
  /** Hash of the selector and arguments to the constructor. */
@@ -32,14 +32,24 @@ export interface ContractInstance {
32
32
  publicKeys: PublicKeys;
33
33
  }
34
34
 
35
+ /**
36
+ * The address preimage plus the current contract class id, which is chain-tracked state derived from the
37
+ * ContractInstanceRegistry (it equals the original class id unless the contract has been upgraded).
38
+ */
39
+ export interface ContractInstance extends ContractInstancePreimage {
40
+ /** Identifier of the contract class this instance currently runs (as of some block). */
41
+ currentContractClassId: Fr;
42
+ }
43
+
44
+ export type ContractInstancePreimageWithAddress = ContractInstancePreimage & { address: AztecAddress };
45
+
35
46
  export type ContractInstanceWithAddress = ContractInstance & { address: AztecAddress };
36
47
 
37
- export const ContractInstanceSchema = zodFor<ContractInstance>()(
48
+ export const ContractInstancePreimageSchema = zodFor<ContractInstancePreimage>()(
38
49
  z.object({
39
50
  version: z.literal(VERSION),
40
51
  salt: schemas.Fr,
41
52
  deployer: schemas.AztecAddress,
42
- currentContractClassId: schemas.Fr,
43
53
  originalContractClassId: schemas.Fr,
44
54
  initializationHash: schemas.Fr,
45
55
  immutablesHash: schemas.Fr,
@@ -47,6 +57,14 @@ export const ContractInstanceSchema = zodFor<ContractInstance>()(
47
57
  }),
48
58
  );
49
59
 
60
+ export const ContractInstanceSchema = zodFor<ContractInstance>()(
61
+ ContractInstancePreimageSchema.and(z.object({ currentContractClassId: schemas.Fr })),
62
+ );
63
+
64
+ export const ContractInstancePreimageWithAddressSchema = zodFor<ContractInstancePreimageWithAddress>()(
65
+ ContractInstancePreimageSchema.and(z.object({ address: schemas.AztecAddress })),
66
+ );
67
+
50
68
  export const ContractInstanceWithAddressSchema = zodFor<ContractInstanceWithAddress>()(
51
69
  ContractInstanceSchema.and(z.object({ address: schemas.AztecAddress })),
52
70
  );
@@ -1,7 +1,13 @@
1
1
  import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
 
3
3
  /**
4
- * A type which along with public key forms a preimage of a contract address. See the link below for more details
5
- * https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys
4
+ * The contract-side preimage of an Aztec address, i.e. the commitment to a specific contract instance.
5
+ *
6
+ * A partial address commits to a contract's code and initialization
7
+ * (`hash(contract_class_id, salted_initialization_hash)`) but not to its keys. Combined with an account's `PublicKeys`,
8
+ * it fully determines the address: `address = (hash(public_keys_hash, partial_address) * G + Ivpk_m).x`. Two accounts
9
+ * therefore share an address only if they share both their public keys and their partial address.
10
+ *
11
+ * See `computePartialAddress` for the derivation.
6
12
  */
7
13
  export type PartialAddress = Fr;