@aztec/stdlib 0.0.1-commit.3e3d0c9cd → 0.0.1-commit.3f5453c7b

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 (278) hide show
  1. package/dest/abi/abi.d.ts +138 -1
  2. package/dest/abi/abi.d.ts.map +1 -1
  3. package/dest/abi/abi.js +10 -2
  4. package/dest/abi/buffer.d.ts +14 -4
  5. package/dest/abi/buffer.d.ts.map +1 -1
  6. package/dest/abi/buffer.js +25 -4
  7. package/dest/abi/decoder.d.ts +5 -44
  8. package/dest/abi/decoder.d.ts.map +1 -1
  9. package/dest/abi/decoder.js +12 -67
  10. package/dest/abi/function_selector.js +1 -1
  11. package/dest/abi/function_signature_decoder.d.ts +43 -0
  12. package/dest/abi/function_signature_decoder.d.ts.map +1 -0
  13. package/dest/abi/function_signature_decoder.js +66 -0
  14. package/dest/abi/index.d.ts +2 -1
  15. package/dest/abi/index.d.ts.map +1 -1
  16. package/dest/abi/index.js +1 -0
  17. package/dest/abi/selector.d.ts +2 -2
  18. package/dest/abi/selector.d.ts.map +1 -1
  19. package/dest/abi/selector.js +1 -1
  20. package/dest/avm/revert_code.d.ts +8 -18
  21. package/dest/avm/revert_code.d.ts.map +1 -1
  22. package/dest/avm/revert_code.js +15 -30
  23. package/dest/block/l2_block_source.d.ts +84 -5
  24. package/dest/block/l2_block_source.d.ts.map +1 -1
  25. package/dest/block/l2_block_source.js +1 -0
  26. package/dest/block/l2_block_stream/l2_tips_store_base.d.ts +1 -1
  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 +17 -4
  29. package/dest/block/test/l2_tips_store_test_suite.d.ts +1 -1
  30. package/dest/block/test/l2_tips_store_test_suite.d.ts.map +1 -1
  31. package/dest/block/test/l2_tips_store_test_suite.js +3 -2
  32. package/dest/checkpoint/checkpoint.d.ts +7 -1
  33. package/dest/checkpoint/checkpoint.d.ts.map +1 -1
  34. package/dest/checkpoint/checkpoint.js +9 -1
  35. package/dest/checkpoint/checkpoint_data.d.ts +71 -5
  36. package/dest/checkpoint/checkpoint_data.d.ts.map +1 -1
  37. package/dest/checkpoint/checkpoint_data.js +10 -0
  38. package/dest/checkpoint/validate.js +2 -2
  39. package/dest/config/index.d.ts +2 -1
  40. package/dest/config/index.d.ts.map +1 -1
  41. package/dest/config/index.js +1 -0
  42. package/dest/config/pipelining-config.d.ts +19 -0
  43. package/dest/config/pipelining-config.d.ts.map +1 -0
  44. package/dest/config/pipelining-config.js +18 -0
  45. package/dest/config/sequencer-config.d.ts +2 -2
  46. package/dest/config/sequencer-config.d.ts.map +1 -1
  47. package/dest/config/sequencer-config.js +7 -0
  48. package/dest/contract/contract_address.d.ts +3 -3
  49. package/dest/contract/contract_address.js +3 -3
  50. package/dest/contract/contract_class_id.d.ts +2 -2
  51. package/dest/contract/contract_class_id.js +2 -2
  52. package/dest/contract/index.d.ts +1 -3
  53. package/dest/contract/index.d.ts.map +1 -1
  54. package/dest/contract/index.js +0 -2
  55. package/dest/contract/interfaces/contract_class.d.ts +3 -156
  56. package/dest/contract/interfaces/contract_class.d.ts.map +1 -1
  57. package/dest/contract/interfaces/contract_class.js +1 -28
  58. package/dest/epoch-helpers/index.d.ts +7 -1
  59. package/dest/epoch-helpers/index.d.ts.map +1 -1
  60. package/dest/epoch-helpers/index.js +12 -0
  61. package/dest/file-store/factory.d.ts +4 -3
  62. package/dest/file-store/factory.d.ts.map +1 -1
  63. package/dest/file-store/factory.js +2 -2
  64. package/dest/file-store/http.d.ts +9 -2
  65. package/dest/file-store/http.d.ts.map +1 -1
  66. package/dest/file-store/http.js +20 -9
  67. package/dest/file-store/index.d.ts +2 -1
  68. package/dest/file-store/index.d.ts.map +1 -1
  69. package/dest/gas/fee_math.d.ts +49 -0
  70. package/dest/gas/fee_math.d.ts.map +1 -0
  71. package/dest/gas/fee_math.js +80 -0
  72. package/dest/gas/gas_fees.d.ts +1 -1
  73. package/dest/gas/gas_fees.d.ts.map +1 -1
  74. package/dest/gas/gas_fees.js +10 -1
  75. package/dest/gas/gas_settings.d.ts +40 -3
  76. package/dest/gas/gas_settings.d.ts.map +1 -1
  77. package/dest/gas/gas_settings.js +50 -6
  78. package/dest/gas/index.d.ts +2 -1
  79. package/dest/gas/index.d.ts.map +1 -1
  80. package/dest/gas/index.js +1 -0
  81. package/dest/hash/hash.d.ts +19 -1
  82. package/dest/hash/hash.d.ts.map +1 -1
  83. package/dest/hash/hash.js +29 -0
  84. package/dest/interfaces/archiver.d.ts +1 -1
  85. package/dest/interfaces/archiver.d.ts.map +1 -1
  86. package/dest/interfaces/archiver.js +3 -1
  87. package/dest/interfaces/aztec-node-admin.d.ts +4 -17
  88. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  89. package/dest/interfaces/aztec-node-admin.js +3 -3
  90. package/dest/interfaces/aztec-node-debug.d.ts +21 -0
  91. package/dest/interfaces/aztec-node-debug.d.ts.map +1 -0
  92. package/dest/interfaces/aztec-node-debug.js +18 -0
  93. package/dest/interfaces/aztec-node.d.ts +10 -1
  94. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  95. package/dest/interfaces/aztec-node.js +2 -0
  96. package/dest/interfaces/block-builder.d.ts +26 -7
  97. package/dest/interfaces/block-builder.d.ts.map +1 -1
  98. package/dest/interfaces/block-builder.js +1 -4
  99. package/dest/interfaces/client.d.ts +2 -1
  100. package/dest/interfaces/client.d.ts.map +1 -1
  101. package/dest/interfaces/client.js +1 -0
  102. package/dest/interfaces/configs.d.ts +2 -7
  103. package/dest/interfaces/configs.d.ts.map +1 -1
  104. package/dest/interfaces/configs.js +0 -1
  105. package/dest/interfaces/proving-job.d.ts +200 -200
  106. package/dest/interfaces/slasher.d.ts +1 -10
  107. package/dest/interfaces/slasher.d.ts.map +1 -1
  108. package/dest/interfaces/slasher.js +0 -2
  109. package/dest/interfaces/validator.d.ts +4 -15
  110. package/dest/interfaces/validator.d.ts.map +1 -1
  111. package/dest/interfaces/validator.js +0 -1
  112. package/dest/l1-contracts/index.d.ts +2 -2
  113. package/dest/l1-contracts/index.d.ts.map +1 -1
  114. package/dest/l1-contracts/index.js +1 -1
  115. package/dest/logs/extended_directional_app_tagging_secret.d.ts +4 -4
  116. package/dest/logs/extended_directional_app_tagging_secret.d.ts.map +1 -1
  117. package/dest/logs/extended_directional_app_tagging_secret.js +12 -5
  118. package/dest/logs/message_context.d.ts +4 -7
  119. package/dest/logs/message_context.d.ts.map +1 -1
  120. package/dest/logs/message_context.js +23 -9
  121. package/dest/logs/pending_tagged_log.d.ts +2 -3
  122. package/dest/logs/pending_tagged_log.d.ts.map +1 -1
  123. package/dest/logs/pending_tagged_log.js +2 -2
  124. package/dest/logs/shared_secret_derivation.d.ts +11 -10
  125. package/dest/logs/shared_secret_derivation.d.ts.map +1 -1
  126. package/dest/logs/shared_secret_derivation.js +15 -9
  127. package/dest/logs/siloed_tag.d.ts +4 -1
  128. package/dest/logs/siloed_tag.d.ts.map +1 -1
  129. package/dest/logs/siloed_tag.js +7 -3
  130. package/dest/logs/tx_scoped_l2_log.d.ts +3 -1
  131. package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
  132. package/dest/logs/tx_scoped_l2_log.js +7 -0
  133. package/dest/messaging/l1_to_l2_message.d.ts +3 -2
  134. package/dest/messaging/l1_to_l2_message.d.ts.map +1 -1
  135. package/dest/messaging/l1_to_l2_message.js +11 -13
  136. package/dest/noir/index.d.ts +3 -3
  137. package/dest/noir/index.d.ts.map +1 -1
  138. package/dest/note/note_dao.d.ts +1 -1
  139. package/dest/note/note_dao.d.ts.map +1 -1
  140. package/dest/note/note_dao.js +1 -4
  141. package/dest/p2p/checkpoint_proposal.d.ts +2 -2
  142. package/dest/p2p/checkpoint_proposal.d.ts.map +1 -1
  143. package/dest/p2p/checkpoint_proposal.js +3 -13
  144. package/dest/proofs/chonk_proof.d.ts +46 -2
  145. package/dest/proofs/chonk_proof.d.ts.map +1 -1
  146. package/dest/proofs/chonk_proof.js +85 -10
  147. package/dest/slashing/index.d.ts +2 -3
  148. package/dest/slashing/index.d.ts.map +1 -1
  149. package/dest/slashing/index.js +1 -2
  150. package/dest/slashing/serialization.d.ts +2 -6
  151. package/dest/slashing/serialization.d.ts.map +1 -1
  152. package/dest/slashing/serialization.js +0 -60
  153. package/dest/slashing/types.d.ts +4 -90
  154. package/dest/slashing/types.d.ts.map +1 -1
  155. package/dest/slashing/types.js +0 -14
  156. package/dest/slashing/{tally.d.ts → votes.d.ts} +1 -1
  157. package/dest/slashing/{tally.d.ts.map → votes.d.ts.map} +1 -1
  158. package/dest/slashing/{tally.js → votes.js} +1 -1
  159. package/dest/tests/factories.d.ts +2 -4
  160. package/dest/tests/factories.d.ts.map +1 -1
  161. package/dest/tests/factories.js +11 -28
  162. package/dest/tests/mocks.d.ts +1 -1
  163. package/dest/tests/mocks.d.ts.map +1 -1
  164. package/dest/tests/mocks.js +13 -18
  165. package/dest/timetable/index.d.ts +51 -1
  166. package/dest/timetable/index.d.ts.map +1 -1
  167. package/dest/timetable/index.js +204 -14
  168. package/dest/tx/capsule.d.ts +6 -2
  169. package/dest/tx/capsule.d.ts.map +1 -1
  170. package/dest/tx/capsule.js +9 -3
  171. package/dest/tx/fee_provider.d.ts +10 -0
  172. package/dest/tx/fee_provider.d.ts.map +1 -0
  173. package/dest/tx/fee_provider.js +1 -0
  174. package/dest/tx/global_variable_builder.d.ts +3 -4
  175. package/dest/tx/global_variable_builder.d.ts.map +1 -1
  176. package/dest/tx/index.d.ts +2 -1
  177. package/dest/tx/index.d.ts.map +1 -1
  178. package/dest/tx/index.js +1 -0
  179. package/dest/tx/simulated_tx.d.ts +112 -4
  180. package/dest/tx/simulated_tx.d.ts.map +1 -1
  181. package/dest/tx/simulated_tx.js +3 -3
  182. package/dest/tx/tx_receipt.d.ts +8 -4
  183. package/dest/tx/tx_receipt.d.ts.map +1 -1
  184. package/dest/tx/tx_receipt.js +8 -15
  185. package/dest/tx/validator/error_texts.d.ts +5 -1
  186. package/dest/tx/validator/error_texts.d.ts.map +1 -1
  187. package/dest/tx/validator/error_texts.js +6 -0
  188. package/dest/world-state/genesis_data.d.ts +11 -0
  189. package/dest/world-state/genesis_data.d.ts.map +1 -0
  190. package/dest/world-state/genesis_data.js +4 -0
  191. package/dest/world-state/index.d.ts +2 -1
  192. package/dest/world-state/index.d.ts.map +1 -1
  193. package/dest/world-state/index.js +1 -0
  194. package/package.json +8 -8
  195. package/src/abi/abi.ts +25 -2
  196. package/src/abi/buffer.ts +25 -4
  197. package/src/abi/decoder.ts +23 -78
  198. package/src/abi/function_selector.ts +1 -1
  199. package/src/abi/function_signature_decoder.ts +77 -0
  200. package/src/abi/index.ts +1 -0
  201. package/src/abi/selector.ts +1 -1
  202. package/src/avm/revert_code.ts +25 -39
  203. package/src/block/l2_block_source.ts +14 -4
  204. package/src/block/l2_block_stream/l2_tips_store_base.ts +24 -12
  205. package/src/block/test/l2_tips_store_test_suite.ts +8 -1
  206. package/src/checkpoint/checkpoint.ts +11 -1
  207. package/src/checkpoint/checkpoint_data.ts +40 -4
  208. package/src/checkpoint/validate.ts +2 -2
  209. package/src/config/index.ts +1 -0
  210. package/src/config/pipelining-config.ts +31 -0
  211. package/src/config/sequencer-config.ts +11 -1
  212. package/src/contract/contract_address.ts +3 -3
  213. package/src/contract/contract_class_id.ts +2 -2
  214. package/src/contract/index.ts +0 -2
  215. package/src/contract/interfaces/contract_class.ts +2 -82
  216. package/src/epoch-helpers/index.ts +24 -0
  217. package/src/file-store/factory.ts +13 -4
  218. package/src/file-store/http.ts +29 -10
  219. package/src/file-store/index.ts +1 -0
  220. package/src/gas/README.md +31 -0
  221. package/src/gas/fee_math.ts +120 -0
  222. package/src/gas/gas_fees.ts +12 -4
  223. package/src/gas/gas_settings.ts +65 -12
  224. package/src/gas/index.ts +1 -0
  225. package/src/hash/hash.ts +34 -0
  226. package/src/interfaces/archiver.ts +3 -1
  227. package/src/interfaces/aztec-node-admin.ts +5 -7
  228. package/src/interfaces/aztec-node-debug.ts +40 -0
  229. package/src/interfaces/aztec-node.ts +15 -0
  230. package/src/interfaces/block-builder.ts +27 -9
  231. package/src/interfaces/client.ts +1 -0
  232. package/src/interfaces/configs.ts +1 -6
  233. package/src/interfaces/slasher.ts +0 -6
  234. package/src/interfaces/validator.ts +2 -9
  235. package/src/l1-contracts/index.ts +1 -1
  236. package/src/logs/extended_directional_app_tagging_secret.ts +19 -8
  237. package/src/logs/message_context.ts +17 -7
  238. package/src/logs/pending_tagged_log.ts +1 -3
  239. package/src/logs/shared_secret_derivation.ts +21 -10
  240. package/src/logs/siloed_tag.ts +7 -2
  241. package/src/logs/tx_scoped_l2_log.ts +16 -0
  242. package/src/messaging/l1_to_l2_message.ts +12 -9
  243. package/src/noir/index.ts +2 -2
  244. package/src/note/note_dao.ts +1 -4
  245. package/src/p2p/checkpoint_proposal.ts +8 -21
  246. package/src/proofs/chonk_proof.ts +91 -5
  247. package/src/slashing/index.ts +1 -2
  248. package/src/slashing/serialization.ts +1 -81
  249. package/src/slashing/types.ts +3 -35
  250. package/src/slashing/{tally.ts → votes.ts} +1 -1
  251. package/src/tests/factories.ts +5 -34
  252. package/src/tests/mocks.ts +14 -12
  253. package/src/timetable/index.ts +293 -13
  254. package/src/tx/capsule.ts +10 -2
  255. package/src/tx/fee_provider.ts +10 -0
  256. package/src/tx/global_variable_builder.ts +2 -3
  257. package/src/tx/index.ts +1 -0
  258. package/src/tx/simulated_tx.ts +6 -2
  259. package/src/tx/tx_receipt.ts +11 -14
  260. package/src/tx/validator/error_texts.ts +8 -0
  261. package/src/world-state/genesis_data.ts +15 -0
  262. package/src/world-state/index.ts +1 -0
  263. package/dest/contract/private_function_membership_proof.d.ts +0 -32
  264. package/dest/contract/private_function_membership_proof.d.ts.map +0 -1
  265. package/dest/contract/private_function_membership_proof.js +0 -124
  266. package/dest/contract/utility_function_membership_proof.d.ts +0 -27
  267. package/dest/contract/utility_function_membership_proof.d.ts.map +0 -1
  268. package/dest/contract/utility_function_membership_proof.js +0 -87
  269. package/dest/l1-contracts/slash_factory.d.ts +0 -45
  270. package/dest/l1-contracts/slash_factory.d.ts.map +0 -1
  271. package/dest/l1-contracts/slash_factory.js +0 -158
  272. package/dest/slashing/empire.d.ts +0 -31
  273. package/dest/slashing/empire.d.ts.map +0 -1
  274. package/dest/slashing/empire.js +0 -87
  275. package/src/contract/private_function_membership_proof.ts +0 -167
  276. package/src/contract/utility_function_membership_proof.ts +0 -118
  277. package/src/l1-contracts/slash_factory.ts +0 -180
  278. package/src/slashing/empire.ts +0 -104
@@ -25,6 +25,219 @@ export const DEFAULT_L1_PUBLISHING_TIME = 12;
25
25
  /** Minimum execution time for building a block in seconds */
26
26
  export const MIN_EXECUTION_TIME = 2;
27
27
 
28
+ export type CheckpointTimingConfig = {
29
+ aztecSlotDuration: number;
30
+ ethereumSlotDuration?: number;
31
+ blockDuration?: number;
32
+ checkpointAssembleTime?: number;
33
+ checkpointInitializationTime?: number;
34
+ l1PublishingTime?: number;
35
+ minExecutionTime?: number;
36
+ p2pPropagationTime?: number;
37
+ pipelining?: boolean;
38
+ };
39
+
40
+ export interface CheckpointTiming {
41
+ readonly aztecSlotDuration: number;
42
+ readonly blockDuration: number | undefined;
43
+ readonly checkpointAssembleTime: number;
44
+ readonly checkpointInitializationTime: number;
45
+ readonly l1PublishingTime: number;
46
+ readonly minExecutionTime: number;
47
+ readonly p2pPropagationTime: number;
48
+ readonly checkpointFinalizationTime: number;
49
+ readonly pipeliningAttestationGracePeriod: number;
50
+ readonly timeReservedAtEnd: number;
51
+ readonly minimumBuildSlotWork: number;
52
+ readonly initializeDeadline: number;
53
+ readonly checkpointAssemblyDeadline: number;
54
+ readonly checkpointAttestationStartDeadline: number;
55
+ readonly checkpointAttestationDeadline: number;
56
+ readonly checkpointPublishingDeadline: number;
57
+
58
+ calculateMaxBlocksPerSlot(): number;
59
+ }
60
+
61
+ export interface PipelinedCheckpointTiming extends CheckpointTiming {
62
+ readonly proposalWindowIntoTargetSlot: number;
63
+ readonly attestationWindowIntoTargetSlot: number;
64
+ }
65
+
66
+ /**
67
+ * Shared base for checkpoint timing implementations.
68
+ *
69
+ * This class owns the common inputs and formulas used by both pipelined and
70
+ * non-pipelined scheduling. Variant-specific deadline math is delegated to the
71
+ * concrete subclasses below.
72
+ */
73
+ abstract class BaseCheckpointTiming implements CheckpointTiming {
74
+ public readonly aztecSlotDuration: number;
75
+ public readonly blockDuration: number | undefined;
76
+ public readonly checkpointAssembleTime: number;
77
+ public readonly checkpointInitializationTime: number;
78
+ public readonly l1PublishingTime: number;
79
+ public readonly minExecutionTime: number;
80
+ public readonly p2pPropagationTime: number;
81
+
82
+ constructor(opts: CheckpointTimingConfig) {
83
+ this.aztecSlotDuration = opts.aztecSlotDuration;
84
+ this.blockDuration = opts.blockDuration;
85
+
86
+ this.checkpointAssembleTime = opts.checkpointAssembleTime ?? CHECKPOINT_ASSEMBLE_TIME;
87
+ this.checkpointInitializationTime = opts.checkpointInitializationTime ?? CHECKPOINT_INITIALIZATION_TIME;
88
+ this.l1PublishingTime = opts.l1PublishingTime ?? DEFAULT_L1_PUBLISHING_TIME;
89
+ this.minExecutionTime = opts.minExecutionTime ?? MIN_EXECUTION_TIME;
90
+ this.p2pPropagationTime = opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME;
91
+ }
92
+
93
+ public get checkpointFinalizationTime(): number {
94
+ // Allow enough time to
95
+ // - build the checkpoint
96
+ // - Round-trip over p2p
97
+ // - Publish to L1
98
+ return this.checkpointAssembleTime + this.p2pPropagationTime * 2 + this.l1PublishingTime;
99
+ }
100
+
101
+ public get pipeliningAttestationGracePeriod(): number {
102
+ // Allow enough time to
103
+ // - build the block
104
+ // - pass it back over p2p
105
+ return (this.blockDuration ?? 0) + this.p2pPropagationTime;
106
+ }
107
+
108
+ public abstract get timeReservedAtEnd(): number;
109
+ public abstract get minimumBuildSlotWork(): number;
110
+
111
+ public get initializeDeadline(): number {
112
+ return this.aztecSlotDuration - this.minimumBuildSlotWork;
113
+ }
114
+
115
+ public abstract get checkpointAssemblyDeadline(): number;
116
+
117
+ public get checkpointAttestationStartDeadline(): number {
118
+ return this.checkpointAssemblyDeadline;
119
+ }
120
+
121
+ public abstract get checkpointAttestationDeadline(): number;
122
+ public abstract get checkpointPublishingDeadline(): number;
123
+
124
+ public calculateMaxBlocksPerSlot(): number {
125
+ if (!this.blockDuration) {
126
+ return 1;
127
+ }
128
+
129
+ const timeAvailableForBlocks = this.aztecSlotDuration - this.checkpointInitializationTime - this.timeReservedAtEnd;
130
+ return Math.floor(timeAvailableForBlocks / this.blockDuration);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Checkpoint timing model for the non-pipelined sequencer flow.
136
+ *
137
+ * In this mode, checkpoint assembly, attestation collection, and L1 publishing
138
+ * must all complete within the current Aztec slot.
139
+ */
140
+ class StandardCheckpointTimingModel extends BaseCheckpointTiming {
141
+ public get timeReservedAtEnd(): number {
142
+ return (this.blockDuration ?? 0) + this.checkpointFinalizationTime;
143
+ }
144
+
145
+ public get minimumBuildSlotWork(): number {
146
+ return this.checkpointInitializationTime + this.minExecutionTime * 2 + this.checkpointFinalizationTime;
147
+ }
148
+
149
+ public get checkpointAssemblyDeadline(): number {
150
+ return this.aztecSlotDuration - this.l1PublishingTime - 2 * this.p2pPropagationTime;
151
+ }
152
+
153
+ public get checkpointAttestationDeadline(): number {
154
+ return this.aztecSlotDuration - this.l1PublishingTime;
155
+ }
156
+
157
+ public get checkpointPublishingDeadline(): number {
158
+ return this.aztecSlotDuration - this.l1PublishingTime;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Checkpoint timing model for proposer pipelining.
164
+ *
165
+ * In this mode, the build work still starts in the current slot, but checkpoint
166
+ * assembly and attestation collection can extend into the target slot. The extra
167
+ * target-slot window getters are intended for consumers such as P2P validators
168
+ * that need to validate pipelined messages against wallclock time.
169
+ */
170
+ class PipelinedCheckpointTimingModel extends BaseCheckpointTiming implements PipelinedCheckpointTiming {
171
+ public get proposalWindowIntoTargetSlot(): number {
172
+ // Allow the p2p propagation time to receive a checkpoint proposal from leader
173
+ return this.p2pPropagationTime;
174
+ }
175
+
176
+ public get attestationWindowIntoTargetSlot(): number {
177
+ return this.aztecSlotDuration - this.l1PublishingTime;
178
+ }
179
+
180
+ public get timeReservedAtEnd(): number {
181
+ return this.checkpointAssembleTime + this.p2pPropagationTime;
182
+ }
183
+
184
+ public get minimumBuildSlotWork(): number {
185
+ return this.checkpointInitializationTime + this.minExecutionTime * 2;
186
+ }
187
+
188
+ public get checkpointAssemblyDeadline(): number {
189
+ // Allow enough time to
190
+ // - build all blocks
191
+ // - receive attestations
192
+ return this.aztecSlotDuration + this.pipeliningAttestationGracePeriod;
193
+ }
194
+
195
+ public get checkpointAttestationDeadline(): number {
196
+ // Allowed to be into the next wallclock slot minus the allocated l1 publishing time
197
+ return this.aztecSlotDuration * 2 - this.l1PublishingTime;
198
+ }
199
+
200
+ public get checkpointPublishingDeadline(): number {
201
+ // Allowed to be into the next wallclock slot minus the allocated l1 Publishing time
202
+ return this.aztecSlotDuration * 2 - this.l1PublishingTime;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Creates a checkpoint timing model for the requested scheduling mode.
208
+ *
209
+ * Most callers should use this factory and depend only on the shared
210
+ * `CheckpointTiming` interface. The returned implementation is selected from
211
+ * `opts.pipelining`.
212
+ */
213
+ export function createCheckpointTimingModel(opts: CheckpointTimingConfig): CheckpointTiming {
214
+ validateCheckpointTimingConfig(opts);
215
+ const normalizedOpts = normalizeCheckpointTimingConfig(opts);
216
+
217
+ const timing = normalizedOpts.pipelining
218
+ ? new PipelinedCheckpointTimingModel(normalizedOpts)
219
+ : new StandardCheckpointTimingModel(normalizedOpts);
220
+ validateCheckpointTimingModel(timing);
221
+ return timing;
222
+ }
223
+
224
+ /**
225
+ * Creates a pipelined checkpoint timing model with target-slot window accessors.
226
+ *
227
+ * Use this when the caller specifically needs the pipelined-only timing surface,
228
+ * such as proposal or attestation acceptance windows into the target slot.
229
+ */
230
+ export function createPipelinedCheckpointTimingModel(
231
+ opts: Omit<CheckpointTimingConfig, 'pipelining'>,
232
+ ): PipelinedCheckpointTiming {
233
+ validateCheckpointTimingConfig(opts);
234
+ const normalizedOpts = normalizeCheckpointTimingConfig(opts);
235
+
236
+ const timing = new PipelinedCheckpointTimingModel(normalizedOpts);
237
+ validateCheckpointTimingModel(timing);
238
+ return timing;
239
+ }
240
+
28
241
  /**
29
242
  * Calculates the maximum number of blocks that can be built in a slot.
30
243
  * Used by both the sequencer timetable and p2p gossipsub scoring.
@@ -42,25 +255,92 @@ export function calculateMaxBlocksPerSlot(
42
255
  checkpointAssembleTime?: number;
43
256
  p2pPropagationTime?: number;
44
257
  l1PublishingTime?: number;
258
+ pipelining?: boolean;
45
259
  } = {},
46
260
  ): number {
47
- if (!blockDurationSec) {
48
- return 1; // Single block per slot
261
+ return createCheckpointTimingModel({
262
+ aztecSlotDuration: aztecSlotDurationSec,
263
+ blockDuration: blockDurationSec,
264
+ checkpointAssembleTime: opts.checkpointAssembleTime,
265
+ checkpointInitializationTime: opts.checkpointInitializationTime,
266
+ l1PublishingTime: opts.l1PublishingTime,
267
+ p2pPropagationTime: opts.p2pPropagationTime,
268
+ pipelining: opts.pipelining,
269
+ }).calculateMaxBlocksPerSlot();
270
+ }
271
+
272
+ function assertNonNegative(name: string, value: number): void {
273
+ if (value < 0) {
274
+ throw new Error(`${name} must be non-negative (got ${value})`);
49
275
  }
276
+ }
50
277
 
51
- const initOffset = opts.checkpointInitializationTime ?? CHECKPOINT_INITIALIZATION_TIME;
52
- const assembleTime = opts.checkpointAssembleTime ?? CHECKPOINT_ASSEMBLE_TIME;
53
- const p2pTime = opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME;
54
- const l1Time = opts.l1PublishingTime ?? DEFAULT_L1_PUBLISHING_TIME;
278
+ function validateCheckpointTimingConfig(opts: CheckpointTimingConfig): void {
279
+ if (opts.aztecSlotDuration <= 0) {
280
+ throw new Error(`aztecSlotDuration must be positive (got ${opts.aztecSlotDuration})`);
281
+ }
55
282
 
56
- // Calculate checkpoint finalization time (assembly + round-trip propagation + L1 publishing)
57
- const checkpointFinalizationTime = assembleTime + p2pTime * 2 + l1Time;
283
+ if (opts.ethereumSlotDuration !== undefined && opts.ethereumSlotDuration <= 0) {
284
+ throw new Error(`ethereumSlotDuration must be positive when provided (got ${opts.ethereumSlotDuration})`);
285
+ }
58
286
 
59
- // Time reserved at end for last sub-slot (validator re-execution) + finalization
60
- const timeReservedAtEnd = blockDurationSec + checkpointFinalizationTime;
287
+ if (opts.blockDuration !== undefined && opts.blockDuration <= 0) {
288
+ throw new Error(`blockDuration must be positive when provided (got ${opts.blockDuration})`);
289
+ }
61
290
 
62
- // Time available for building blocks
63
- const timeAvailableForBlocks = aztecSlotDurationSec - initOffset - timeReservedAtEnd;
291
+ if (opts.minExecutionTime !== undefined && opts.minExecutionTime <= 0) {
292
+ throw new Error(`minExecutionTime must be positive when provided (got ${opts.minExecutionTime})`);
293
+ }
64
294
 
65
- return Math.max(1, Math.floor(timeAvailableForBlocks / blockDurationSec));
295
+ if (opts.checkpointAssembleTime !== undefined) {
296
+ assertNonNegative('checkpointAssembleTime', opts.checkpointAssembleTime);
297
+ }
298
+ if (opts.checkpointInitializationTime !== undefined) {
299
+ assertNonNegative('checkpointInitializationTime', opts.checkpointInitializationTime);
300
+ }
301
+ if (opts.l1PublishingTime !== undefined) {
302
+ assertNonNegative('l1PublishingTime', opts.l1PublishingTime);
303
+ }
304
+ if (opts.p2pPropagationTime !== undefined) {
305
+ assertNonNegative('p2pPropagationTime', opts.p2pPropagationTime);
306
+ }
307
+ }
308
+
309
+ function normalizeCheckpointTimingConfig(opts: CheckpointTimingConfig): CheckpointTimingConfig {
310
+ let checkpointAssembleTime = opts.checkpointAssembleTime ?? CHECKPOINT_ASSEMBLE_TIME;
311
+ let checkpointInitializationTime = opts.checkpointInitializationTime ?? CHECKPOINT_INITIALIZATION_TIME;
312
+ let minExecutionTime = opts.minExecutionTime ?? MIN_EXECUTION_TIME;
313
+ let p2pPropagationTime = opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME;
314
+
315
+ if (opts.ethereumSlotDuration !== undefined && opts.ethereumSlotDuration < 8) {
316
+ p2pPropagationTime = 0;
317
+ checkpointAssembleTime = 0.5;
318
+ checkpointInitializationTime = 0.5;
319
+ minExecutionTime = 1;
320
+ }
321
+
322
+ if (opts.blockDuration !== undefined && minExecutionTime > opts.blockDuration) {
323
+ minExecutionTime = opts.blockDuration;
324
+ }
325
+
326
+ return {
327
+ ...opts,
328
+ checkpointAssembleTime,
329
+ checkpointInitializationTime,
330
+ minExecutionTime,
331
+ p2pPropagationTime,
332
+ };
333
+ }
334
+
335
+ function validateCheckpointTimingModel(model: CheckpointTiming): void {
336
+ if (model.blockDuration === undefined) {
337
+ return;
338
+ }
339
+
340
+ const timeAvailableForBlocks = model.aztecSlotDuration - model.checkpointInitializationTime - model.timeReservedAtEnd;
341
+ if (timeAvailableForBlocks < model.blockDuration) {
342
+ throw new Error(
343
+ `Invalid timing configuration: only ${timeAvailableForBlocks}s available for block building, which is less than one blockDuration (${model.blockDuration}s).`,
344
+ );
345
+ }
66
346
  }
package/src/tx/capsule.ts CHANGED
@@ -19,6 +19,8 @@ export class Capsule {
19
19
  public readonly storageSlot: Fr,
20
20
  /** Data passed to the contract */
21
21
  public readonly data: Fr[],
22
+ /** Optional namespace for the capsule contents */
23
+ public readonly scope?: AztecAddress,
22
24
  ) {}
23
25
 
24
26
  static get schema() {
@@ -30,12 +32,18 @@ export class Capsule {
30
32
  }
31
33
 
32
34
  toBuffer() {
33
- return serializeToBuffer(this.contractAddress, this.storageSlot, new Vector(this.data));
35
+ return this.scope
36
+ ? serializeToBuffer(this.contractAddress, this.storageSlot, new Vector(this.data), true, this.scope)
37
+ : serializeToBuffer(this.contractAddress, this.storageSlot, new Vector(this.data), false);
34
38
  }
35
39
 
36
40
  static fromBuffer(buffer: Buffer | BufferReader): Capsule {
37
41
  const reader = BufferReader.asReader(buffer);
38
- return new Capsule(AztecAddress.fromBuffer(reader), Fr.fromBuffer(reader), reader.readVector(Fr));
42
+ const contractAddress = AztecAddress.fromBuffer(reader);
43
+ const storageSlot = Fr.fromBuffer(reader);
44
+ const data = reader.readVector(Fr);
45
+ const hasScope = reader.readBoolean();
46
+ return new Capsule(contractAddress, storageSlot, data, hasScope ? AztecAddress.fromBuffer(reader) : undefined);
39
47
  }
40
48
 
41
49
  toString() {
@@ -0,0 +1,10 @@
1
+ import type { ManaUsageEstimate } from '../gas/fee_math.js';
2
+ import type { GasFees } from '../gas/gas_fees.js';
3
+
4
+ /** Provides current and predicted fee information for transaction pricing. */
5
+ export interface FeeProvider {
6
+ /** Returns the current minimum fees for inclusion in the next block. */
7
+ getCurrentMinFees(): Promise<GasFees>;
8
+ /** Returns predicted min fees for each slot in the prediction window. */
9
+ getPredictedMinFees(manaUsage?: ManaUsageEstimate): Promise<GasFees[]>;
10
+ }
@@ -1,8 +1,8 @@
1
+ import type { SimulationOverridesPlan } from '@aztec/ethereum/contracts';
1
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
3
  import type { SlotNumber } from '@aztec/foundation/schemas';
3
4
 
4
5
  import type { AztecAddress } from '../aztec-address/index.js';
5
- import type { GasFees } from '../gas/gas_fees.js';
6
6
  import type { UInt32 } from '../types/index.js';
7
7
  import type { CheckpointGlobalVariables, GlobalVariables } from './global_variables.js';
8
8
 
@@ -10,8 +10,6 @@ import type { CheckpointGlobalVariables, GlobalVariables } from './global_variab
10
10
  * Interface for building global variables for Aztec blocks.
11
11
  */
12
12
  export interface GlobalVariableBuilder {
13
- getCurrentMinFees(): Promise<GasFees>;
14
-
15
13
  /**
16
14
  * Builds global variables for a given block.
17
15
  * @param blockNumber - The block number to build global variables for.
@@ -32,5 +30,6 @@ export interface GlobalVariableBuilder {
32
30
  coinbase: EthAddress,
33
31
  feeRecipient: AztecAddress,
34
32
  slotNumber: SlotNumber,
33
+ simulationOverridesPlan?: SimulationOverridesPlan,
35
34
  ): Promise<CheckpointGlobalVariables>;
36
35
  }
package/src/tx/index.ts CHANGED
@@ -24,6 +24,7 @@ export * from './validator/tx_validator.js';
24
24
  export * from './validator/empty_validator.js';
25
25
  export * from './validator/error_texts.js';
26
26
  export * from './capsule.js';
27
+ export * from './fee_provider.js';
27
28
  export * from './global_variable_builder.js';
28
29
  export * from './hashed_values.js';
29
30
  export * from './indexed_tx_effect.js';
@@ -38,7 +38,11 @@ export type ContractOverrides = Record<
38
38
  * set, it *must* be run without the kernel circuits, or validations will fail
39
39
  */
40
40
  export class SimulationOverrides {
41
- constructor(public contracts?: ContractOverrides) {}
41
+ public contracts?: ContractOverrides;
42
+
43
+ constructor(contracts: ContractOverrides = {}) {
44
+ this.contracts = Object.keys(contracts).length > 0 ? contracts : undefined;
45
+ }
42
46
 
43
47
  static get schema() {
44
48
  return z
@@ -157,7 +161,7 @@ export class TxSimulationResult {
157
161
  }
158
162
 
159
163
  /**
160
- * Recursively accummulate the return values of a call result and its nested executions,
164
+ * Recursively accumulate the return values of a call result and its nested executions,
161
165
  * so they can be retrieved in order.
162
166
  * @param executionResult
163
167
  * @returns
@@ -31,9 +31,16 @@ export const SortedTxStatuses: TxStatus[] = [
31
31
  /** Execution result - only set when tx is in a block. */
32
32
  export enum TxExecutionResult {
33
33
  SUCCESS = 'success',
34
- APP_LOGIC_REVERTED = 'app_logic_reverted',
35
- TEARDOWN_REVERTED = 'teardown_reverted',
36
- BOTH_REVERTED = 'both_reverted',
34
+ REVERTED = 'reverted',
35
+ /** @deprecated Use REVERTED instead. */
36
+ // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
37
+ APP_LOGIC_REVERTED = 'reverted',
38
+ /** @deprecated Use REVERTED instead. */
39
+ // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
40
+ TEARDOWN_REVERTED = 'reverted',
41
+ /** @deprecated Use REVERTED instead. */
42
+ // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
43
+ BOTH_REVERTED = 'reverted',
37
44
  }
38
45
 
39
46
  /**
@@ -143,16 +150,6 @@ export class TxReceipt {
143
150
  }
144
151
 
145
152
  public static executionResultFromRevertCode(revertCode: RevertCode): TxExecutionResult {
146
- if (revertCode.equals(RevertCode.OK)) {
147
- return TxExecutionResult.SUCCESS;
148
- } else if (revertCode.equals(RevertCode.APP_LOGIC_REVERTED)) {
149
- return TxExecutionResult.APP_LOGIC_REVERTED;
150
- } else if (revertCode.equals(RevertCode.TEARDOWN_REVERTED)) {
151
- return TxExecutionResult.TEARDOWN_REVERTED;
152
- } else if (revertCode.equals(RevertCode.BOTH_REVERTED)) {
153
- return TxExecutionResult.BOTH_REVERTED;
154
- } else {
155
- throw new Error(`Unknown revert code: ${revertCode.getCode()}`);
156
- }
153
+ return revertCode.isOK() ? TxExecutionResult.SUCCESS : TxExecutionResult.REVERTED;
157
154
  }
158
155
  }
@@ -41,5 +41,13 @@ export const TX_ERROR_SIZE_ABOVE_LIMIT = 'Transaction size above size limit';
41
41
  // Block header
42
42
  export const TX_ERROR_BLOCK_HEADER = 'Block header not found';
43
43
 
44
+ // Contract instance
45
+ export const TX_ERROR_INCORRECT_CONTRACT_ADDRESS = 'Incorrect contract instance deployment address';
46
+ export const TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG = 'Failed to parse contract instance deployment log';
47
+
48
+ // Contract class
49
+ export const TX_ERROR_INCORRECT_CONTRACT_CLASS_ID = 'Incorrect contract class id';
50
+ export const TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG = 'Failed to parse contract class registration log';
51
+
44
52
  // General
45
53
  export const TX_ERROR_DURING_VALIDATION = 'Unexpected error during validation';
@@ -0,0 +1,15 @@
1
+ import type { PublicDataTreeLeaf } from '../trees/index.js';
2
+
3
+ /** Data used to initialize the genesis block, including prefilled public state and an optional timestamp. */
4
+ export type GenesisData = {
5
+ /** Public data tree leaves to pre-populate in the genesis state (e.g. fee juice balances). */
6
+ prefilledPublicData: PublicDataTreeLeaf[];
7
+ /** Timestamp for the genesis block header. Defaults to 0 (canonical empty genesis) in production. */
8
+ genesisTimestamp: bigint;
9
+ };
10
+
11
+ /** An empty genesis data with no prefilled state and a zero timestamp. */
12
+ export const EMPTY_GENESIS_DATA: GenesisData = {
13
+ prefilledPublicData: [],
14
+ genesisTimestamp: 0n,
15
+ };
@@ -1 +1,2 @@
1
+ export * from './genesis_data.js';
1
2
  export * from './world_state_revision.js';
@@ -1,32 +0,0 @@
1
- import { type ContractArtifact, FunctionSelector } from '../abi/index.js';
2
- import type { ContractClassPublic, ExecutablePrivateFunctionWithMembershipProof, PrivateFunctionMembershipProof } from './interfaces/index.js';
3
- /**
4
- * Creates a membership proof for a private function in a contract class, to be verified via `isValidPrivateFunctionMembershipProof`.
5
- * @param selector - Selector of the function to create the proof for.
6
- * @param artifact - Artifact of the contract class where the function is defined.
7
- */
8
- export declare function createPrivateFunctionMembershipProof(selector: FunctionSelector, artifact: ContractArtifact): Promise<PrivateFunctionMembershipProof>;
9
- /**
10
- * Verifies that a private function with a membership proof as emitted by the ClassRegistry contract is valid,
11
- * as defined in the protocol specs at contract-deployment/classes:
12
- *
13
- * ```
14
- * // Load contract class from local db
15
- * contract_class = db.get_contract_class(contract_class_id)
16
- *
17
- * // Compute function leaf and assert it belongs to the private functions tree
18
- * function_leaf = pedersen([selector as Field, vk_hash], GENERATOR__PRIVATE_FUNCTION_LEAF)
19
- * computed_private_function_tree_root = compute_root(function_leaf, private_function_tree_sibling_path)
20
- * assert computed_private_function_tree_root == contract_class.private_functions_root
21
- *
22
- * // Compute artifact leaf and assert it belongs to the artifact
23
- * artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode))
24
- * computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path)
25
- * computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, utility_functions_artifact_tree_root, artifact_metadata_hash)
26
- * assert computed_artifact_hash == contract_class.artifact_hash
27
- * ```
28
- * @param fn - Function to check membership proof for.
29
- * @param contractClass - In which contract class the function is expected to be.
30
- */
31
- export declare function isValidPrivateFunctionMembershipProof(fn: ExecutablePrivateFunctionWithMembershipProof, contractClass: Pick<ContractClassPublic, 'privateFunctionsRoot' | 'artifactHash'>): Promise<boolean>;
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZV9mdW5jdGlvbl9tZW1iZXJzaGlwX3Byb29mLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29udHJhY3QvcHJpdmF0ZV9mdW5jdGlvbl9tZW1iZXJzaGlwX3Byb29mLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFBRSxLQUFLLGdCQUFnQixFQUFFLGdCQUFnQixFQUFnQixNQUFNLGlCQUFpQixDQUFDO0FBVXhGLE9BQU8sS0FBSyxFQUNWLG1CQUFtQixFQUNuQiw0Q0FBNEMsRUFDNUMsOEJBQThCLEVBQy9CLE1BQU0sdUJBQXVCLENBQUM7QUFHL0I7Ozs7R0FJRztBQUNILHdCQUFzQixvQ0FBb0MsQ0FDeEQsUUFBUSxFQUFFLGdCQUFnQixFQUMxQixRQUFRLEVBQUUsZ0JBQWdCLEdBQ3pCLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxDQTREekM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsd0JBQXNCLHFDQUFxQyxDQUN6RCxFQUFFLEVBQUUsNENBQTRDLEVBQ2hELGFBQWEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsc0JBQXNCLEdBQUcsY0FBYyxDQUFDLG9CQWtEbEYifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"private_function_membership_proof.d.ts","sourceRoot":"","sources":["../../src/contract/private_function_membership_proof.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,gBAAgB,EAAE,gBAAgB,EAAgB,MAAM,iBAAiB,CAAC;AAUxF,OAAO,KAAK,EACV,mBAAmB,EACnB,4CAA4C,EAC5C,8BAA8B,EAC/B,MAAM,uBAAuB,CAAC;AAG/B;;;;GAIG;AACH,wBAAsB,oCAAoC,CACxD,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,8BAA8B,CAAC,CA4DzC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,qCAAqC,CACzD,EAAE,EAAE,4CAA4C,EAChD,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,GAAG,cAAc,CAAC,oBAkDlF"}
@@ -1,124 +0,0 @@
1
- import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
2
- import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { createLogger } from '@aztec/foundation/log';
4
- import { computeRootFromSiblingPath } from '@aztec/foundation/trees';
5
- import { FunctionSelector, FunctionType } from '../abi/index.js';
6
- import { computeArtifactFunctionTree, computeArtifactHash, computeArtifactHashPreimage, computeFunctionArtifactHash, computeFunctionMetadataHash, getArtifactMerkleTreeHasher } from './artifact_hash.js';
7
- import { getContractClassPrivateFunctionFromArtifact } from './contract_class.js';
8
- import { computePrivateFunctionLeaf, computePrivateFunctionsTree } from './private_function.js';
9
- /**
10
- * Creates a membership proof for a private function in a contract class, to be verified via `isValidPrivateFunctionMembershipProof`.
11
- * @param selector - Selector of the function to create the proof for.
12
- * @param artifact - Artifact of the contract class where the function is defined.
13
- */ export async function createPrivateFunctionMembershipProof(selector, artifact) {
14
- const log = createLogger('circuits:function_membership_proof');
15
- // Locate private function definition and artifact
16
- const privateFunctions = artifact.functions.filter((fn)=>fn.functionType === FunctionType.PRIVATE);
17
- const privateFunctionsFromArtifact = await Promise.all(privateFunctions.map(getContractClassPrivateFunctionFromArtifact));
18
- const privateFunction = privateFunctionsFromArtifact.find((fn)=>fn.selector.equals(selector));
19
- const privateFunctionsAndSelectors = await Promise.all(privateFunctions.map(async (fn)=>({
20
- fn,
21
- selector: await FunctionSelector.fromNameAndParameters(fn.name, fn.parameters)
22
- })));
23
- const privateFunctionArtifact = privateFunctionsAndSelectors.find((fnAndSelector)=>selector.equals(fnAndSelector.selector))?.fn;
24
- if (!privateFunction || !privateFunctionArtifact) {
25
- throw new Error(`Private function with selector ${selector.toString()} not found`);
26
- }
27
- // Compute preimage for the artifact hash
28
- const { utilityFunctionRoot: utilityFunctionsTreeRoot, metadataHash: artifactMetadataHash } = await computeArtifactHashPreimage(artifact);
29
- // We need two sibling paths because private function information is split across two trees:
30
- // The "private function tree" captures the selectors and verification keys, and is used in the kernel circuit for verifying the proof generated by the app circuit.
31
- const functionLeaf = await computePrivateFunctionLeaf(privateFunction);
32
- const functionsTree = await computePrivateFunctionsTree(privateFunctionsFromArtifact);
33
- const functionsTreeLeafIndex = functionsTree.getIndex(functionLeaf);
34
- const functionsTreeSiblingPath = functionsTree.getSiblingPath(functionsTreeLeafIndex).map(Fr.fromBuffer);
35
- // And the "artifact tree" captures function bytecode and metadata, and is used by the pxe to check that its executing the code it's supposed to be executing, but it never goes into circuits.
36
- const functionMetadataHash = computeFunctionMetadataHash(privateFunctionArtifact);
37
- const functionArtifactHash = await computeFunctionArtifactHash({
38
- ...privateFunctionArtifact,
39
- functionMetadataHash
40
- });
41
- const artifactTree = await computeArtifactFunctionTree(artifact, FunctionType.PRIVATE);
42
- const artifactTreeLeafIndex = artifactTree.getIndex(functionArtifactHash.toBuffer());
43
- const artifactTreeSiblingPath = artifactTree.getSiblingPath(artifactTreeLeafIndex).map(Fr.fromBuffer);
44
- log.debug(`Computed proof for private function with selector ${selector.toString()}`, {
45
- functionArtifactHash,
46
- functionMetadataHash,
47
- functionLeaf: '0x' + functionLeaf.toString('hex'),
48
- artifactMetadataHash,
49
- privateFunctionsTreeRoot: '0x' + functionsTree.root.toString('hex'),
50
- utilityFunctionsTreeRoot,
51
- artifactFunctionTreeSiblingPath: artifactTreeSiblingPath.map((fr)=>fr.toString()).join(','),
52
- privateFunctionTreeSiblingPath: functionsTreeSiblingPath.map((fr)=>fr.toString()).join(',')
53
- });
54
- return {
55
- artifactTreeSiblingPath,
56
- artifactTreeLeafIndex,
57
- artifactMetadataHash,
58
- functionMetadataHash,
59
- utilityFunctionsTreeRoot,
60
- privateFunctionTreeSiblingPath: functionsTreeSiblingPath,
61
- privateFunctionTreeLeafIndex: functionsTreeLeafIndex
62
- };
63
- }
64
- /**
65
- * Verifies that a private function with a membership proof as emitted by the ClassRegistry contract is valid,
66
- * as defined in the protocol specs at contract-deployment/classes:
67
- *
68
- * ```
69
- * // Load contract class from local db
70
- * contract_class = db.get_contract_class(contract_class_id)
71
- *
72
- * // Compute function leaf and assert it belongs to the private functions tree
73
- * function_leaf = pedersen([selector as Field, vk_hash], GENERATOR__PRIVATE_FUNCTION_LEAF)
74
- * computed_private_function_tree_root = compute_root(function_leaf, private_function_tree_sibling_path)
75
- * assert computed_private_function_tree_root == contract_class.private_functions_root
76
- *
77
- * // Compute artifact leaf and assert it belongs to the artifact
78
- * artifact_function_leaf = sha256(selector, metadata_hash, sha256(bytecode))
79
- * computed_artifact_private_function_tree_root = compute_root(artifact_function_leaf, artifact_function_tree_sibling_path)
80
- * computed_artifact_hash = sha256(computed_artifact_private_function_tree_root, utility_functions_artifact_tree_root, artifact_metadata_hash)
81
- * assert computed_artifact_hash == contract_class.artifact_hash
82
- * ```
83
- * @param fn - Function to check membership proof for.
84
- * @param contractClass - In which contract class the function is expected to be.
85
- */ export async function isValidPrivateFunctionMembershipProof(fn, contractClass) {
86
- const log = createLogger('circuits:function_membership_proof');
87
- // Check private function tree membership
88
- const functionLeaf = await computePrivateFunctionLeaf(fn);
89
- const rootBuffer = await computeRootFromSiblingPath(functionLeaf, fn.privateFunctionTreeSiblingPath.map((fr)=>fr.toBuffer()), fn.privateFunctionTreeLeafIndex, async (left, right)=>(await poseidon2Hash([
90
- left,
91
- right
92
- ])).toBuffer());
93
- const computedPrivateFunctionTreeRoot = Fr.fromBuffer(rootBuffer);
94
- if (!contractClass.privateFunctionsRoot.equals(computedPrivateFunctionTreeRoot)) {
95
- log.debug(`Private function tree root mismatch`, {
96
- expectedPrivateFunctionTreeRoot: contractClass.privateFunctionsRoot,
97
- computedPrivateFunctionTreeRoot: computedPrivateFunctionTreeRoot,
98
- computedFunctionLeaf: '0x' + functionLeaf.toString('hex')
99
- });
100
- return false;
101
- }
102
- // Check artifact hash
103
- const functionArtifactHash = await computeFunctionArtifactHash(fn);
104
- const computedArtifactPrivateFunctionTreeRootBuffer = await computeRootFromSiblingPath(functionArtifactHash.toBuffer(), fn.artifactTreeSiblingPath.map((fr)=>fr.toBuffer()), fn.artifactTreeLeafIndex, getArtifactMerkleTreeHasher());
105
- const computedArtifactPrivateFunctionTreeRoot = Fr.fromBuffer(computedArtifactPrivateFunctionTreeRootBuffer);
106
- const computedArtifactHash = await computeArtifactHash({
107
- privateFunctionRoot: computedArtifactPrivateFunctionTreeRoot,
108
- utilityFunctionRoot: fn.utilityFunctionsTreeRoot,
109
- metadataHash: fn.artifactMetadataHash
110
- });
111
- if (!contractClass.artifactHash.equals(computedArtifactHash)) {
112
- log.debug(`Artifact hash mismatch`, {
113
- expected: contractClass.artifactHash,
114
- computedArtifactHash,
115
- computedFunctionArtifactHash: functionArtifactHash,
116
- computedArtifactPrivateFunctionTreeRoot,
117
- utilityFunctionRoot: fn.utilityFunctionsTreeRoot,
118
- metadataHash: fn.artifactMetadataHash,
119
- artifactFunctionTreeSiblingPath: fn.artifactTreeSiblingPath.map((fr)=>fr.toString()).join(',')
120
- });
121
- return false;
122
- }
123
- return true;
124
- }