@aztec-labs/simulator 6.0.0-nightly.20260829

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 (215) hide show
  1. package/README.md +57 -0
  2. package/dest/client.d.ts +6 -0
  3. package/dest/client.d.ts.map +1 -0
  4. package/dest/client.js +3 -0
  5. package/dest/common/errors.d.ts +51 -0
  6. package/dest/common/errors.d.ts.map +1 -0
  7. package/dest/common/errors.js +154 -0
  8. package/dest/common/index.d.ts +3 -0
  9. package/dest/common/index.d.ts.map +1 -0
  10. package/dest/common/index.js +2 -0
  11. package/dest/common/stats/index.d.ts +2 -0
  12. package/dest/common/stats/index.d.ts.map +1 -0
  13. package/dest/common/stats/index.js +1 -0
  14. package/dest/common/stats/stats.d.ts +4 -0
  15. package/dest/common/stats/stats.d.ts.map +1 -0
  16. package/dest/common/stats/stats.js +10 -0
  17. package/dest/private/acvm/acvm.d.ts +43 -0
  18. package/dest/private/acvm/acvm.d.ts.map +1 -0
  19. package/dest/private/acvm/acvm.js +65 -0
  20. package/dest/private/acvm/acvm_types.d.ts +10 -0
  21. package/dest/private/acvm/acvm_types.d.ts.map +1 -0
  22. package/dest/private/acvm/acvm_types.js +3 -0
  23. package/dest/private/acvm/deserialize.d.ts +35 -0
  24. package/dest/private/acvm/deserialize.d.ts.map +1 -0
  25. package/dest/private/acvm/deserialize.js +50 -0
  26. package/dest/private/acvm/index.d.ts +5 -0
  27. package/dest/private/acvm/index.d.ts.map +1 -0
  28. package/dest/private/acvm/index.js +4 -0
  29. package/dest/private/acvm/serialize.d.ts +41 -0
  30. package/dest/private/acvm/serialize.d.ts.map +1 -0
  31. package/dest/private/acvm/serialize.js +99 -0
  32. package/dest/private/acvm_native.d.ts +41 -0
  33. package/dest/private/acvm_native.d.ts.map +1 -0
  34. package/dest/private/acvm_native.js +147 -0
  35. package/dest/private/acvm_wasm.d.ts +16 -0
  36. package/dest/private/acvm_wasm.d.ts.map +1 -0
  37. package/dest/private/acvm_wasm.js +67 -0
  38. package/dest/private/acvm_wasm_with_blobs.d.ts +20 -0
  39. package/dest/private/acvm_wasm_with_blobs.d.ts.map +1 -0
  40. package/dest/private/acvm_wasm_with_blobs.js +35 -0
  41. package/dest/private/circuit_simulator.d.ts +35 -0
  42. package/dest/private/circuit_simulator.d.ts.map +1 -0
  43. package/dest/private/circuit_simulator.js +43 -0
  44. package/dest/private/factory.d.ts +12 -0
  45. package/dest/private/factory.d.ts.map +1 -0
  46. package/dest/private/factory.js +30 -0
  47. package/dest/public/avm/testing/account_proof_fetcher.d.ts +2 -0
  48. package/dest/public/avm/testing/account_proof_fetcher.d.ts.map +1 -0
  49. package/dest/public/avm/testing/account_proof_fetcher.js +152 -0
  50. package/dest/public/avm/testing/base_avm_simulation_tester.d.ts +39 -0
  51. package/dest/public/avm/testing/base_avm_simulation_tester.d.ts.map +1 -0
  52. package/dest/public/avm/testing/base_avm_simulation_tester.js +121 -0
  53. package/dest/public/avm/testing/utils.d.ts +32 -0
  54. package/dest/public/avm/testing/utils.d.ts.map +1 -0
  55. package/dest/public/avm/testing/utils.js +66 -0
  56. package/dest/public/avm_simulator.d.ts +28 -0
  57. package/dest/public/avm_simulator.d.ts.map +1 -0
  58. package/dest/public/avm_simulator.js +4 -0
  59. package/dest/public/avm_simulator_pool.d.ts +84 -0
  60. package/dest/public/avm_simulator_pool.d.ts.map +1 -0
  61. package/dest/public/avm_simulator_pool.js +311 -0
  62. package/dest/public/cdb_ipc_server.d.ts +40 -0
  63. package/dest/public/cdb_ipc_server.d.ts.map +1 -0
  64. package/dest/public/cdb_ipc_server.js +153 -0
  65. package/dest/public/contracts_db_checkpoint.d.ts +16 -0
  66. package/dest/public/contracts_db_checkpoint.d.ts.map +1 -0
  67. package/dest/public/contracts_db_checkpoint.js +30 -0
  68. package/dest/public/db_interfaces.d.ts +68 -0
  69. package/dest/public/db_interfaces.d.ts.map +1 -0
  70. package/dest/public/db_interfaces.js +3 -0
  71. package/dest/public/executor_metrics.d.ts +21 -0
  72. package/dest/public/executor_metrics.d.ts.map +1 -0
  73. package/dest/public/executor_metrics.js +64 -0
  74. package/dest/public/executor_metrics_interface.d.ts +10 -0
  75. package/dest/public/executor_metrics_interface.d.ts.map +1 -0
  76. package/dest/public/executor_metrics_interface.js +1 -0
  77. package/dest/public/fixtures/amm_test.d.ts +10 -0
  78. package/dest/public/fixtures/amm_test.d.ts.map +1 -0
  79. package/dest/public/fixtures/amm_test.js +213 -0
  80. package/dest/public/fixtures/bulk_test.d.ts +6 -0
  81. package/dest/public/fixtures/bulk_test.d.ts.map +1 -0
  82. package/dest/public/fixtures/bulk_test.js +289 -0
  83. package/dest/public/fixtures/custom_bytecode_tester.d.ts +34 -0
  84. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -0
  85. package/dest/public/fixtures/custom_bytecode_tester.js +53 -0
  86. package/dest/public/fixtures/index.d.ts +10 -0
  87. package/dest/public/fixtures/index.d.ts.map +1 -0
  88. package/dest/public/fixtures/index.js +9 -0
  89. package/dest/public/fixtures/public_processor_test_env.d.ts +30 -0
  90. package/dest/public/fixtures/public_processor_test_env.d.ts.map +1 -0
  91. package/dest/public/fixtures/public_processor_test_env.js +73 -0
  92. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +77 -0
  93. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -0
  94. package/dest/public/fixtures/public_tx_simulation_tester.js +176 -0
  95. package/dest/public/fixtures/simple_contract_data_source.d.ts +36 -0
  96. package/dest/public/fixtures/simple_contract_data_source.d.ts.map +1 -0
  97. package/dest/public/fixtures/simple_contract_data_source.js +95 -0
  98. package/dest/public/fixtures/token_test.d.ts +12 -0
  99. package/dest/public/fixtures/token_test.d.ts.map +1 -0
  100. package/dest/public/fixtures/token_test.js +96 -0
  101. package/dest/public/fixtures/utils.d.ts +26 -0
  102. package/dest/public/fixtures/utils.d.ts.map +1 -0
  103. package/dest/public/fixtures/utils.js +170 -0
  104. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts +65 -0
  105. package/dest/public/fuzzing/avm_fuzzer_simulator.d.ts.map +1 -0
  106. package/dest/public/fuzzing/avm_fuzzer_simulator.js +181 -0
  107. package/dest/public/fuzzing/avm_simulator_bin.d.ts +2 -0
  108. package/dest/public/fuzzing/avm_simulator_bin.d.ts.map +1 -0
  109. package/dest/public/fuzzing/avm_simulator_bin.js +108 -0
  110. package/dest/public/index.d.ts +10 -0
  111. package/dest/public/index.d.ts.map +1 -0
  112. package/dest/public/index.js +6 -0
  113. package/dest/public/public_db_sources.d.ts +83 -0
  114. package/dest/public/public_db_sources.d.ts.map +1 -0
  115. package/dest/public/public_db_sources.js +297 -0
  116. package/dest/public/public_errors.d.ts +12 -0
  117. package/dest/public/public_errors.d.ts.map +1 -0
  118. package/dest/public/public_errors.js +13 -0
  119. package/dest/public/public_processor/guarded_merkle_tree.d.ts +52 -0
  120. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -0
  121. package/dest/public/public_processor/guarded_merkle_tree.js +116 -0
  122. package/dest/public/public_processor/public_processor.d.ts +71 -0
  123. package/dest/public/public_processor/public_processor.d.ts.map +1 -0
  124. package/dest/public/public_processor/public_processor.js +858 -0
  125. package/dest/public/public_processor/public_processor_metrics.d.ts +30 -0
  126. package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -0
  127. package/dest/public/public_processor/public_processor_metrics.js +116 -0
  128. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.d.ts +17 -0
  129. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.d.ts.map +1 -0
  130. package/dest/public/public_tx_simulator/dumping_public_tx_simulator.js +39 -0
  131. package/dest/public/public_tx_simulator/factories.d.ts +14 -0
  132. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -0
  133. package/dest/public/public_tx_simulator/factories.js +28 -0
  134. package/dest/public/public_tx_simulator/index.d.ts +6 -0
  135. package/dest/public/public_tx_simulator/index.d.ts.map +1 -0
  136. package/dest/public/public_tx_simulator/index.js +3 -0
  137. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +53 -0
  138. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -0
  139. package/dest/public/public_tx_simulator/public_tx_simulator.js +127 -0
  140. package/dest/public/public_tx_simulator/public_tx_simulator_base.d.ts +24 -0
  141. package/dest/public/public_tx_simulator/public_tx_simulator_base.d.ts.map +1 -0
  142. package/dest/public/public_tx_simulator/public_tx_simulator_base.js +31 -0
  143. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts +32 -0
  144. package/dest/public/public_tx_simulator/public_tx_simulator_interface.d.ts.map +1 -0
  145. package/dest/public/public_tx_simulator/public_tx_simulator_interface.js +1 -0
  146. package/dest/public/side_effect_errors.d.ts +44 -0
  147. package/dest/public/side_effect_errors.d.ts.map +1 -0
  148. package/dest/public/side_effect_errors.js +75 -0
  149. package/dest/public/test_executor_metrics.d.ts +56 -0
  150. package/dest/public/test_executor_metrics.d.ts.map +1 -0
  151. package/dest/public/test_executor_metrics.js +305 -0
  152. package/dest/public/unique_class_ids.d.ts +37 -0
  153. package/dest/public/unique_class_ids.d.ts.map +1 -0
  154. package/dest/public/unique_class_ids.js +61 -0
  155. package/dest/public/utils.d.ts +3 -0
  156. package/dest/public/utils.d.ts.map +1 -0
  157. package/dest/public/utils.js +18 -0
  158. package/dest/server.d.ts +7 -0
  159. package/dest/server.d.ts.map +1 -0
  160. package/dest/server.js +5 -0
  161. package/package.json +109 -0
  162. package/src/client.ts +5 -0
  163. package/src/common/errors.ts +219 -0
  164. package/src/common/index.ts +2 -0
  165. package/src/common/stats/index.ts +1 -0
  166. package/src/common/stats/stats.ts +20 -0
  167. package/src/private/acvm/acvm.ts +114 -0
  168. package/src/private/acvm/acvm_types.ts +11 -0
  169. package/src/private/acvm/deserialize.ts +58 -0
  170. package/src/private/acvm/index.ts +4 -0
  171. package/src/private/acvm/serialize.ts +123 -0
  172. package/src/private/acvm_native.ts +200 -0
  173. package/src/private/acvm_wasm.ts +80 -0
  174. package/src/private/acvm_wasm_with_blobs.ts +55 -0
  175. package/src/private/circuit_simulator.ts +91 -0
  176. package/src/private/factory.ts +40 -0
  177. package/src/public/avm/testing/account_proof.json +553 -0
  178. package/src/public/avm/testing/account_proof_fetcher.ts +166 -0
  179. package/src/public/avm/testing/base_avm_simulation_tester.ts +162 -0
  180. package/src/public/avm/testing/utils.ts +114 -0
  181. package/src/public/avm_simulator.ts +29 -0
  182. package/src/public/avm_simulator_pool.ts +355 -0
  183. package/src/public/cdb_ipc_server.ts +198 -0
  184. package/src/public/contracts_db_checkpoint.ts +41 -0
  185. package/src/public/db_interfaces.ts +76 -0
  186. package/src/public/executor_metrics.ts +102 -0
  187. package/src/public/executor_metrics_interface.ts +20 -0
  188. package/src/public/fixtures/amm_test.ts +331 -0
  189. package/src/public/fixtures/bulk_test.ts +194 -0
  190. package/src/public/fixtures/custom_bytecode_tester.ts +83 -0
  191. package/src/public/fixtures/index.ts +13 -0
  192. package/src/public/fixtures/public_processor_test_env.ts +88 -0
  193. package/src/public/fixtures/public_tx_simulation_tester.ts +315 -0
  194. package/src/public/fixtures/simple_contract_data_source.ts +122 -0
  195. package/src/public/fixtures/token_test.ts +148 -0
  196. package/src/public/fixtures/utils.ts +269 -0
  197. package/src/public/fuzzing/avm_fuzzer_simulator.ts +302 -0
  198. package/src/public/fuzzing/avm_simulator_bin.ts +156 -0
  199. package/src/public/index.ts +16 -0
  200. package/src/public/public_db_sources.ts +405 -0
  201. package/src/public/public_errors.ts +14 -0
  202. package/src/public/public_processor/guarded_merkle_tree.ts +161 -0
  203. package/src/public/public_processor/public_processor.ts +657 -0
  204. package/src/public/public_processor/public_processor_metrics.ts +138 -0
  205. package/src/public/public_tx_simulator/dumping_public_tx_simulator.ts +66 -0
  206. package/src/public/public_tx_simulator/factories.ts +61 -0
  207. package/src/public/public_tx_simulator/index.ts +8 -0
  208. package/src/public/public_tx_simulator/public_tx_simulator.ts +190 -0
  209. package/src/public/public_tx_simulator/public_tx_simulator_base.ts +37 -0
  210. package/src/public/public_tx_simulator/public_tx_simulator_interface.ts +33 -0
  211. package/src/public/side_effect_errors.ts +96 -0
  212. package/src/public/test_executor_metrics.ts +399 -0
  213. package/src/public/unique_class_ids.ts +79 -0
  214. package/src/public/utils.ts +16 -0
  215. package/src/server.ts +6 -0
@@ -0,0 +1,858 @@
1
+ function applyDecs2203RFactory() {
2
+ function createAddInitializerMethod(initializers, decoratorFinishedRef) {
3
+ return function addInitializer(initializer) {
4
+ assertNotFinished(decoratorFinishedRef, "addInitializer");
5
+ assertCallable(initializer, "An initializer");
6
+ initializers.push(initializer);
7
+ };
8
+ }
9
+ function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
10
+ var kindStr;
11
+ switch(kind){
12
+ case 1:
13
+ kindStr = "accessor";
14
+ break;
15
+ case 2:
16
+ kindStr = "method";
17
+ break;
18
+ case 3:
19
+ kindStr = "getter";
20
+ break;
21
+ case 4:
22
+ kindStr = "setter";
23
+ break;
24
+ default:
25
+ kindStr = "field";
26
+ }
27
+ var ctx = {
28
+ kind: kindStr,
29
+ name: isPrivate ? "#" + name : name,
30
+ static: isStatic,
31
+ private: isPrivate,
32
+ metadata: metadata
33
+ };
34
+ var decoratorFinishedRef = {
35
+ v: false
36
+ };
37
+ ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
38
+ var get, set;
39
+ if (kind === 0) {
40
+ if (isPrivate) {
41
+ get = desc.get;
42
+ set = desc.set;
43
+ } else {
44
+ get = function() {
45
+ return this[name];
46
+ };
47
+ set = function(v) {
48
+ this[name] = v;
49
+ };
50
+ }
51
+ } else if (kind === 2) {
52
+ get = function() {
53
+ return desc.value;
54
+ };
55
+ } else {
56
+ if (kind === 1 || kind === 3) {
57
+ get = function() {
58
+ return desc.get.call(this);
59
+ };
60
+ }
61
+ if (kind === 1 || kind === 4) {
62
+ set = function(v) {
63
+ desc.set.call(this, v);
64
+ };
65
+ }
66
+ }
67
+ ctx.access = get && set ? {
68
+ get: get,
69
+ set: set
70
+ } : get ? {
71
+ get: get
72
+ } : {
73
+ set: set
74
+ };
75
+ try {
76
+ return dec(value, ctx);
77
+ } finally{
78
+ decoratorFinishedRef.v = true;
79
+ }
80
+ }
81
+ function assertNotFinished(decoratorFinishedRef, fnName) {
82
+ if (decoratorFinishedRef.v) {
83
+ throw new Error("attempted to call " + fnName + " after decoration was finished");
84
+ }
85
+ }
86
+ function assertCallable(fn, hint) {
87
+ if (typeof fn !== "function") {
88
+ throw new TypeError(hint + " must be a function");
89
+ }
90
+ }
91
+ function assertValidReturnValue(kind, value) {
92
+ var type = typeof value;
93
+ if (kind === 1) {
94
+ if (type !== "object" || value === null) {
95
+ throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
96
+ }
97
+ if (value.get !== undefined) {
98
+ assertCallable(value.get, "accessor.get");
99
+ }
100
+ if (value.set !== undefined) {
101
+ assertCallable(value.set, "accessor.set");
102
+ }
103
+ if (value.init !== undefined) {
104
+ assertCallable(value.init, "accessor.init");
105
+ }
106
+ } else if (type !== "function") {
107
+ var hint;
108
+ if (kind === 0) {
109
+ hint = "field";
110
+ } else if (kind === 10) {
111
+ hint = "class";
112
+ } else {
113
+ hint = "method";
114
+ }
115
+ throw new TypeError(hint + " decorators must return a function or void 0");
116
+ }
117
+ }
118
+ function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
119
+ var decs = decInfo[0];
120
+ var desc, init, value;
121
+ if (isPrivate) {
122
+ if (kind === 0 || kind === 1) {
123
+ desc = {
124
+ get: decInfo[3],
125
+ set: decInfo[4]
126
+ };
127
+ } else if (kind === 3) {
128
+ desc = {
129
+ get: decInfo[3]
130
+ };
131
+ } else if (kind === 4) {
132
+ desc = {
133
+ set: decInfo[3]
134
+ };
135
+ } else {
136
+ desc = {
137
+ value: decInfo[3]
138
+ };
139
+ }
140
+ } else if (kind !== 0) {
141
+ desc = Object.getOwnPropertyDescriptor(base, name);
142
+ }
143
+ if (kind === 1) {
144
+ value = {
145
+ get: desc.get,
146
+ set: desc.set
147
+ };
148
+ } else if (kind === 2) {
149
+ value = desc.value;
150
+ } else if (kind === 3) {
151
+ value = desc.get;
152
+ } else if (kind === 4) {
153
+ value = desc.set;
154
+ }
155
+ var newValue, get, set;
156
+ if (typeof decs === "function") {
157
+ newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
158
+ if (newValue !== void 0) {
159
+ assertValidReturnValue(kind, newValue);
160
+ if (kind === 0) {
161
+ init = newValue;
162
+ } else if (kind === 1) {
163
+ init = newValue.init;
164
+ get = newValue.get || value.get;
165
+ set = newValue.set || value.set;
166
+ value = {
167
+ get: get,
168
+ set: set
169
+ };
170
+ } else {
171
+ value = newValue;
172
+ }
173
+ }
174
+ } else {
175
+ for(var i = decs.length - 1; i >= 0; i--){
176
+ var dec = decs[i];
177
+ newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
178
+ if (newValue !== void 0) {
179
+ assertValidReturnValue(kind, newValue);
180
+ var newInit;
181
+ if (kind === 0) {
182
+ newInit = newValue;
183
+ } else if (kind === 1) {
184
+ newInit = newValue.init;
185
+ get = newValue.get || value.get;
186
+ set = newValue.set || value.set;
187
+ value = {
188
+ get: get,
189
+ set: set
190
+ };
191
+ } else {
192
+ value = newValue;
193
+ }
194
+ if (newInit !== void 0) {
195
+ if (init === void 0) {
196
+ init = newInit;
197
+ } else if (typeof init === "function") {
198
+ init = [
199
+ init,
200
+ newInit
201
+ ];
202
+ } else {
203
+ init.push(newInit);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ if (kind === 0 || kind === 1) {
210
+ if (init === void 0) {
211
+ init = function(instance, init) {
212
+ return init;
213
+ };
214
+ } else if (typeof init !== "function") {
215
+ var ownInitializers = init;
216
+ init = function(instance, init) {
217
+ var value = init;
218
+ for(var i = 0; i < ownInitializers.length; i++){
219
+ value = ownInitializers[i].call(instance, value);
220
+ }
221
+ return value;
222
+ };
223
+ } else {
224
+ var originalInitializer = init;
225
+ init = function(instance, init) {
226
+ return originalInitializer.call(instance, init);
227
+ };
228
+ }
229
+ ret.push(init);
230
+ }
231
+ if (kind !== 0) {
232
+ if (kind === 1) {
233
+ desc.get = value.get;
234
+ desc.set = value.set;
235
+ } else if (kind === 2) {
236
+ desc.value = value;
237
+ } else if (kind === 3) {
238
+ desc.get = value;
239
+ } else if (kind === 4) {
240
+ desc.set = value;
241
+ }
242
+ if (isPrivate) {
243
+ if (kind === 1) {
244
+ ret.push(function(instance, args) {
245
+ return value.get.call(instance, args);
246
+ });
247
+ ret.push(function(instance, args) {
248
+ return value.set.call(instance, args);
249
+ });
250
+ } else if (kind === 2) {
251
+ ret.push(value);
252
+ } else {
253
+ ret.push(function(instance, args) {
254
+ return value.call(instance, args);
255
+ });
256
+ }
257
+ } else {
258
+ Object.defineProperty(base, name, desc);
259
+ }
260
+ }
261
+ }
262
+ function applyMemberDecs(Class, decInfos, metadata) {
263
+ var ret = [];
264
+ var protoInitializers;
265
+ var staticInitializers;
266
+ var existingProtoNonFields = new Map();
267
+ var existingStaticNonFields = new Map();
268
+ for(var i = 0; i < decInfos.length; i++){
269
+ var decInfo = decInfos[i];
270
+ if (!Array.isArray(decInfo)) continue;
271
+ var kind = decInfo[1];
272
+ var name = decInfo[2];
273
+ var isPrivate = decInfo.length > 3;
274
+ var isStatic = kind >= 5;
275
+ var base;
276
+ var initializers;
277
+ if (isStatic) {
278
+ base = Class;
279
+ kind = kind - 5;
280
+ staticInitializers = staticInitializers || [];
281
+ initializers = staticInitializers;
282
+ } else {
283
+ base = Class.prototype;
284
+ protoInitializers = protoInitializers || [];
285
+ initializers = protoInitializers;
286
+ }
287
+ if (kind !== 0 && !isPrivate) {
288
+ var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
289
+ var existingKind = existingNonFields.get(name) || 0;
290
+ if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
291
+ throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
292
+ } else if (!existingKind && kind > 2) {
293
+ existingNonFields.set(name, kind);
294
+ } else {
295
+ existingNonFields.set(name, true);
296
+ }
297
+ }
298
+ applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
299
+ }
300
+ pushInitializers(ret, protoInitializers);
301
+ pushInitializers(ret, staticInitializers);
302
+ return ret;
303
+ }
304
+ function pushInitializers(ret, initializers) {
305
+ if (initializers) {
306
+ ret.push(function(instance) {
307
+ for(var i = 0; i < initializers.length; i++){
308
+ initializers[i].call(instance);
309
+ }
310
+ return instance;
311
+ });
312
+ }
313
+ }
314
+ function applyClassDecs(targetClass, classDecs, metadata) {
315
+ if (classDecs.length > 0) {
316
+ var initializers = [];
317
+ var newClass = targetClass;
318
+ var name = targetClass.name;
319
+ for(var i = classDecs.length - 1; i >= 0; i--){
320
+ var decoratorFinishedRef = {
321
+ v: false
322
+ };
323
+ try {
324
+ var nextNewClass = classDecs[i](newClass, {
325
+ kind: "class",
326
+ name: name,
327
+ addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
328
+ metadata
329
+ });
330
+ } finally{
331
+ decoratorFinishedRef.v = true;
332
+ }
333
+ if (nextNewClass !== undefined) {
334
+ assertValidReturnValue(10, nextNewClass);
335
+ newClass = nextNewClass;
336
+ }
337
+ }
338
+ return [
339
+ defineMetadata(newClass, metadata),
340
+ function() {
341
+ for(var i = 0; i < initializers.length; i++){
342
+ initializers[i].call(newClass);
343
+ }
344
+ }
345
+ ];
346
+ }
347
+ }
348
+ function defineMetadata(Class, metadata) {
349
+ return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
350
+ configurable: true,
351
+ enumerable: true,
352
+ value: metadata
353
+ });
354
+ }
355
+ return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
356
+ if (parentClass !== void 0) {
357
+ var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
358
+ }
359
+ var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
360
+ var e = applyMemberDecs(targetClass, memberDecs, metadata);
361
+ if (!classDecs.length) defineMetadata(targetClass, metadata);
362
+ return {
363
+ e: e,
364
+ get c () {
365
+ return applyClassDecs(targetClass, classDecs, metadata);
366
+ }
367
+ };
368
+ };
369
+ }
370
+ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
371
+ return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
372
+ }
373
+ var _dec, _dec1, _dec2, _initProto;
374
+ import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT } from '@aztec-labs/constants';
375
+ import { padArrayEnd } from '@aztec-labs/foundation/collection';
376
+ import { Fr } from '@aztec-labs/foundation/curves/bn254';
377
+ import { createLogger } from '@aztec-labs/foundation/log';
378
+ import { sleep } from '@aztec-labs/foundation/sleep';
379
+ import { DateProvider, Timer, elapsed, execWithSignal } from '@aztec-labs/foundation/timer';
380
+ import { ProtocolContractAddress } from '@aztec-labs/protocol-contracts';
381
+ import { ContractClassPublishedEvent } from '@aztec-labs/protocol-contracts/class-registry';
382
+ import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from '@aztec-labs/protocol-contracts/fee-juice';
383
+ import { AvmCircuitInputs, AvmExecutionHints, PublicDataWrite } from '@aztec-labs/stdlib/avm';
384
+ import { computeTransactionFee } from '@aztec-labs/stdlib/fees';
385
+ import { Gas } from '@aztec-labs/stdlib/gas';
386
+ import { NullDebugLogStore } from '@aztec-labs/stdlib/logs';
387
+ import { ProvingRequestType } from '@aztec-labs/stdlib/proofs';
388
+ import { MerkleTreeId } from '@aztec-labs/stdlib/trees';
389
+ import { NestedProcessReturnValues, makeProcessedTxFromPrivateOnlyTx, makeProcessedTxFromTxWithPublicCalls } from '@aztec-labs/stdlib/tx';
390
+ import { Attributes, getTelemetryClient, trackSpan } from '@aztec-labs/telemetry-client';
391
+ import { ForkCheckpoint } from '@aztec-labs/world-state/native';
392
+ import { AssertionError } from 'assert';
393
+ import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
394
+ import { TelemetryPublicTxSimulator } from '../public_tx_simulator/index.js';
395
+ import { GuardedMerkleTreeOperations } from './guarded_merkle_tree.js';
396
+ import { PublicProcessorMetrics } from './public_processor_metrics.js';
397
+ /**
398
+ * Creates new instances of PublicProcessor given the provided merkle tree db and contract data source.
399
+ */ export class PublicProcessorFactory {
400
+ contractDataSource;
401
+ avmSimulator;
402
+ dateProvider;
403
+ telemetryClient;
404
+ log;
405
+ constructor(contractDataSource, avmSimulator, dateProvider = new DateProvider(), telemetryClient = getTelemetryClient(), bindings){
406
+ this.contractDataSource = contractDataSource;
407
+ this.avmSimulator = avmSimulator;
408
+ this.dateProvider = dateProvider;
409
+ this.telemetryClient = telemetryClient;
410
+ this.log = createLogger('simulator:public-processor-factory', bindings);
411
+ }
412
+ /**
413
+ * Creates a new instance of a PublicProcessor. The simulator it drives reads contract data from the fork's
414
+ * contracts DB, scoped by the fork id so AVM requests route to the right state.
415
+ *
416
+ * @param globalVariables - The global variables for the block being processed.
417
+ * @param contractsDB - Optional pre-populated contracts DB; a fresh one is constructed if omitted.
418
+ * @returns A new instance of a PublicProcessor.
419
+ */ create(merkleTree, globalVariables, config, contractsDB = new PublicContractsDB(this.contractDataSource, this.log.getBindings())) {
420
+ const forkId = merkleTree.getRevision().forkId;
421
+ const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
422
+ const publicTxSimulator = this.createPublicTxSimulator(forkId, globalVariables, contractsDB, config);
423
+ return new PublicProcessor(globalVariables, guardedFork, contractsDB, publicTxSimulator, this.dateProvider, this.telemetryClient, createLogger('simulator:public-processor', this.log.getBindings()));
424
+ }
425
+ createPublicTxSimulator(forkId, globalVariables, contractsDB, config) {
426
+ return new TelemetryPublicTxSimulator(this.avmSimulator, globalVariables, contractsDB, forkId, this.telemetryClient, config, this.log.getBindings());
427
+ }
428
+ }
429
+ class PublicProcessorTimeoutError extends Error {
430
+ constructor(message = 'Timed out while processing tx'){
431
+ super(message);
432
+ this.name = 'PublicProcessorTimeoutError';
433
+ }
434
+ }
435
+ class PublicProcessorAbortError extends Error {
436
+ constructor(message = 'Aborted while processing tx'){
437
+ super(message);
438
+ this.name = 'PublicProcessorAbortError';
439
+ }
440
+ }
441
+ _dec = trackSpan('PublicProcessor.processTx', (tx)=>({
442
+ [Attributes.TX_HASH]: tx.getTxHash().toString()
443
+ })), _dec1 = trackSpan('PublicProcessor.processPrivateOnlyTx', (tx)=>({
444
+ [Attributes.TX_HASH]: tx.getTxHash().toString()
445
+ })), _dec2 = trackSpan('PublicProcessor.processTxWithPublicCalls', (tx)=>({
446
+ [Attributes.TX_HASH]: tx.getTxHash().toString()
447
+ }));
448
+ /**
449
+ * Converts Txs lifted from the P2P module into ProcessedTx objects by executing
450
+ * any public function calls in them. Txs with private calls only are unaffected.
451
+ */ export class PublicProcessor {
452
+ globalVariables;
453
+ guardedMerkleTree;
454
+ contractsDB;
455
+ publicTxSimulator;
456
+ dateProvider;
457
+ log;
458
+ opts;
459
+ debugLogStore;
460
+ static{
461
+ ({ e: [_initProto] } = _apply_decs_2203_r(this, [
462
+ [
463
+ _dec,
464
+ 2,
465
+ "processTx"
466
+ ],
467
+ [
468
+ _dec1,
469
+ 2,
470
+ "processPrivateOnlyTx"
471
+ ],
472
+ [
473
+ _dec2,
474
+ 2,
475
+ "processTxWithPublicCalls"
476
+ ]
477
+ ], []));
478
+ }
479
+ metrics;
480
+ constructor(globalVariables, guardedMerkleTree, contractsDB, publicTxSimulator, dateProvider, telemetryClient = getTelemetryClient(), log, opts = {}, debugLogStore = new NullDebugLogStore()){
481
+ this.globalVariables = globalVariables;
482
+ this.guardedMerkleTree = guardedMerkleTree;
483
+ this.contractsDB = contractsDB;
484
+ this.publicTxSimulator = publicTxSimulator;
485
+ this.dateProvider = dateProvider;
486
+ this.log = log;
487
+ this.opts = opts;
488
+ this.debugLogStore = debugLogStore;
489
+ _initProto(this);
490
+ this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');
491
+ }
492
+ get tracer() {
493
+ return this.metrics.tracer;
494
+ }
495
+ /**
496
+ * Run each tx through the public circuit and the public kernel circuit if needed.
497
+ * @param txs - Txs to process.
498
+ * @param limits - Limits for processing the txs.
499
+ * @param validator - Pre-process validator and nullifier cache to use for processing the txs.
500
+ * @returns The list of processed txs with their circuit simulation outputs.
501
+ */ async process(txs, limits = {}, validator = {}) {
502
+ const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal, signal } = limits;
503
+ const { preprocessValidator, nullifierCache } = validator;
504
+ const result = [];
505
+ const usedTxs = [];
506
+ const failed = [];
507
+ const debugLogs = [];
508
+ const timer = new Timer();
509
+ let totalSizeInBytes = 0;
510
+ let returns = [];
511
+ let totalPublicGas = new Gas(0, 0);
512
+ let totalBlockGas = new Gas(0, 0);
513
+ let totalBlobFields = 0;
514
+ let silentlySkippedCount = 0;
515
+ let totalSilentlySkippedDurationMs = 0;
516
+ for await (const tx of txs){
517
+ // Only process up to the max tx limit
518
+ if (maxTransactions !== undefined && result.length >= maxTransactions) {
519
+ this.log.debug(`Stopping tx processing due to reaching the max tx limit.`);
520
+ break;
521
+ }
522
+ // Bail if we've hit the deadline or have been interrupted.
523
+ if (deadline && this.dateProvider.now() > +deadline) {
524
+ this.log.warn(`Stopping tx processing due to timeout.`);
525
+ break;
526
+ }
527
+ if (signal?.aborted) {
528
+ this.log.warn(`Stopping tx processing due to abort signal.`);
529
+ break;
530
+ }
531
+ const txHash = tx.getTxHash().toString();
532
+ // Skip this tx if its estimated blob fields would exceed the limit.
533
+ // Only done during proposal building: during re-execution we must process the exact txs from the proposal.
534
+ const txBlobFields = tx.getPrivateTxEffectsSizeInFields();
535
+ if (isBuildingProposal && maxBlobFields !== undefined && totalBlobFields + txBlobFields > maxBlobFields) {
536
+ this.log.warn(`Skipping tx ${txHash} with ${txBlobFields} fields from private side effects due to blob fields limit`, {
537
+ txHash,
538
+ txBlobFields,
539
+ totalBlobFields,
540
+ maxBlobFields
541
+ });
542
+ continue;
543
+ }
544
+ // Skip this tx if its gas limit would exceed the block gas limit (either da or l2).
545
+ // Only done during proposal building: during re-execution we must process the exact txs from the proposal.
546
+ const txGasLimit = tx.data.constants.txContext.gasSettings.gasLimits;
547
+ if (isBuildingProposal && maxBlockGas !== undefined && totalBlockGas.add(txGasLimit).gtAny(maxBlockGas)) {
548
+ this.log.warn(`Skipping processing of tx ${txHash} due to block gas limit`, {
549
+ txHash,
550
+ txGasLimit,
551
+ totalBlockGas,
552
+ maxBlockGas
553
+ });
554
+ continue;
555
+ }
556
+ // We validate the tx before processing it, to avoid unnecessary work.
557
+ if (preprocessValidator) {
558
+ const result = await preprocessValidator.validateTx(tx);
559
+ const txHash = tx.getTxHash();
560
+ if (result.result === 'invalid') {
561
+ const reason = result.reason.join(', ');
562
+ this.log.debug(`Rejecting tx ${txHash.toString()} due to pre-process validation fail: ${reason}`);
563
+ failed.push({
564
+ tx,
565
+ error: new Error(`Tx failed preprocess validation: ${reason}`)
566
+ });
567
+ returns.push(new NestedProcessReturnValues([]));
568
+ continue;
569
+ } else {
570
+ this.log.trace(`Tx ${txHash.toString()} is valid before processing.`);
571
+ }
572
+ }
573
+ // We checkpoint the transaction here, then within the try/catch we
574
+ // 1. Revert the checkpoint if the tx fails or needs to be discarded for any reason
575
+ // 2. Commit the transaction in the finally block. Note that by using the ForkCheckpoint lifecycle only the first commit/revert takes effect
576
+ // By doing this, every transaction starts on a fresh checkpoint and it's state updates only make it to the fork if this checkpoint is committed.
577
+ // Note: We use the underlying fork here not the guarded one, this ensures that it's not impacted by stopping the guarded version
578
+ const checkpoint = await ForkCheckpoint.new(this.guardedMerkleTree.getUnderlyingFork());
579
+ const startStateReference = await this.guardedMerkleTree.getUnderlyingFork().getStateReference();
580
+ this.contractsDB.createCheckpoint();
581
+ try {
582
+ const [txProcessingTimeMs, [processedTx, returnValues, txDebugLogs]] = await elapsed(()=>this.processTx(tx, deadline, signal));
583
+ // Inject a fake processing failure after N txs if requested
584
+ const fakeThrowAfter = this.opts.fakeThrowAfterProcessingTxCount;
585
+ if (fakeThrowAfter !== undefined && result.length + failed.length + 1 >= fakeThrowAfter) {
586
+ throw new Error(`Fake error after processing ${fakeThrowAfter} txs`);
587
+ }
588
+ const txBlobFields = processedTx.txEffect.getNumBlobFields();
589
+ const txSize = txBlobFields * Fr.SIZE_IN_BYTES;
590
+ // If the actual blob fields of this tx would exceed the limit, skip it.
591
+ // Note: maxBlobFields already accounts for block end blob fields and previous blocks in checkpoint.
592
+ if (maxBlobFields !== undefined && totalBlobFields + txBlobFields > maxBlobFields) {
593
+ this.log.debug(`Skipping processed tx ${txHash} with ${txBlobFields} blob fields due to max blob fields limit.`, {
594
+ txHash,
595
+ txBlobFields,
596
+ totalBlobFields,
597
+ maxBlobFields,
598
+ txProcessingTimeMs
599
+ });
600
+ silentlySkippedCount += 1;
601
+ totalSilentlySkippedDurationMs += txProcessingTimeMs;
602
+ this.metrics.recordSilentlySkipped(txProcessingTimeMs);
603
+ // Need to revert the checkpoint here and don't go any further
604
+ await checkpoint.revert();
605
+ this.contractsDB.revertCheckpoint();
606
+ continue;
607
+ }
608
+ // During re-execution, check if the actual gas used by this tx would push the block over the gas limit.
609
+ // Unlike the proposal-building check (which uses declared gas limits pessimistically before processing),
610
+ // this uses actual gas and stops processing when the limit is exceeded.
611
+ if (!isBuildingProposal && maxBlockGas !== undefined && totalBlockGas.add(processedTx.gasUsed.totalGas).gtAny(maxBlockGas)) {
612
+ this.log.warn(`Stopping re-execution since tx ${txHash} would push block gas over limit`, {
613
+ txHash,
614
+ txGas: processedTx.gasUsed.totalGas,
615
+ totalBlockGas,
616
+ maxBlockGas
617
+ });
618
+ await checkpoint.revert();
619
+ this.contractsDB.revertCheckpoint();
620
+ break;
621
+ }
622
+ // FIXME(fcarreiro): it's ugly to have to notify the validator of nullifiers.
623
+ // I'd rather pass the validators the processedTx as well and let them deal with it.
624
+ nullifierCache?.addNullifiers(processedTx.txEffect.nullifiers.map((n)=>n.toBuffer()));
625
+ result.push(processedTx);
626
+ usedTxs.push(tx);
627
+ returns = returns.concat(returnValues);
628
+ debugLogs.push(...txDebugLogs);
629
+ this.debugLogStore.storeLogs(processedTx.hash.toString(), txDebugLogs);
630
+ totalPublicGas = totalPublicGas.add(processedTx.gasUsed.publicGas);
631
+ totalBlockGas = totalBlockGas.add(processedTx.gasUsed.totalGas);
632
+ totalSizeInBytes += txSize;
633
+ totalBlobFields += txBlobFields;
634
+ // Commit the tx-level contracts checkpoint on success
635
+ this.contractsDB.commitCheckpoint();
636
+ } catch (err) {
637
+ if (err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError') {
638
+ this.log.warn(`Stopping tx processing due to ${err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort'}.`);
639
+ // We hit the transaction execution deadline or an external abort signal.
640
+ // There may still be a simulation in progress.
641
+ // Signal cancellation AND WAIT for the simulation to actually stop. Cancellation is
642
+ // cooperative: the simulator may be mid slow-operation and won't observe the flag until it
643
+ // completes, and without waiting we'd revert checkpoints while it's still writing to state.
644
+ await this.publicTxSimulator.cancel?.();
645
+ // Now stop the guarded fork to prevent any further TS-side access to the world state.
646
+ await this.guardedMerkleTree.stop();
647
+ // We now know there can't be any further access to world state. The fork is in a state where there is:
648
+ // 1. At least one outstanding checkpoint that has not been committed (the one created before we processed the tx).
649
+ // 2. Possible state updates on that checkpoint or any others created during execution.
650
+ // Revert all checkpoints at or above this checkpoint's depth (inclusive), destroying any outstanding state
651
+ // updates from this tx and any nested checkpoints created during execution. This preserves any checkpoints
652
+ // created by callers below our depth.
653
+ await checkpoint.revertToCheckpoint();
654
+ // Revert any contracts added to the DB for the tx.
655
+ this.contractsDB.revertCheckpoint();
656
+ // Ensure we're at the same state as when we started processing this tx.
657
+ await this.checkWorldStateUnchanged(startStateReference, txHash, err);
658
+ break;
659
+ }
660
+ // Roll back state to start of TX before proceeding to next TX.
661
+ // Reverts all checkpoints at or above this checkpoint's depth, preserving any caller checkpoints below.
662
+ await checkpoint.revertToCheckpoint();
663
+ this.contractsDB.revertCheckpoint();
664
+ const errorMessage = err instanceof Error || err instanceof AssertionError ? err.message : 'Unknown error';
665
+ this.log.warn(`Failed to process tx ${txHash.toString()}: ${errorMessage} ${err?.stack}`);
666
+ failed.push({
667
+ tx,
668
+ error: err instanceof Error ? err : new Error(errorMessage)
669
+ });
670
+ returns.push(new NestedProcessReturnValues([]));
671
+ // Ensure we're at the same state as when we started processing this tx.
672
+ await this.checkWorldStateUnchanged(startStateReference, txHash, err);
673
+ } finally{
674
+ // Base case is we always commit the checkpoint. Using the ForkCheckpoint means this has no effect if the tx was previously reverted
675
+ await checkpoint.commit();
676
+ }
677
+ }
678
+ const duration = timer.s();
679
+ const rate = duration > 0 ? totalPublicGas.l2Gas / duration : 0;
680
+ this.metrics.recordAllTxs(totalPublicGas, rate);
681
+ const silentlySkippedDurationMs = Math.round(totalSilentlySkippedDurationMs);
682
+ this.log.info(`Processed ${result.length} successful txs and ${failed.length} failed txs ` + `(${silentlySkippedCount} silently skipped, ${silentlySkippedDurationMs}ms wasted) ` + `in ${duration}s`, {
683
+ blockNumber: this.globalVariables.blockNumber,
684
+ successfulCount: result.length,
685
+ failedCount: failed.length,
686
+ duration,
687
+ rate,
688
+ totalPublicGas,
689
+ totalBlockGas,
690
+ totalSizeInBytes,
691
+ silentlySkippedCount,
692
+ silentlySkippedDurationMs
693
+ });
694
+ return [
695
+ result,
696
+ failed,
697
+ usedTxs,
698
+ returns,
699
+ debugLogs
700
+ ];
701
+ }
702
+ async checkWorldStateUnchanged(startStateReference, txHash, cause) {
703
+ const endStateReference = await this.guardedMerkleTree.getUnderlyingFork().getStateReference();
704
+ if (!startStateReference.equals(endStateReference)) {
705
+ this.log.warn(`Fork state reference changed by tx ${txHash} after error in public processor`, {
706
+ expected: startStateReference.toInspect(),
707
+ actual: endStateReference.toInspect(),
708
+ cause
709
+ });
710
+ throw new Error(`Fork state reference changed by tx ${txHash} after error in public processor`, {
711
+ cause
712
+ });
713
+ }
714
+ }
715
+ async processTx(tx, deadline, signal) {
716
+ const [time, [processedTx, returnValues, debugLogs]] = await elapsed(()=>this.processTxWithinDeadline(tx, deadline, signal));
717
+ this.log.verbose(!tx.hasPublicCalls() ? `Processed tx ${processedTx.hash} with no public calls in ${time}ms` : `Processed tx ${processedTx.hash} with ${tx.numberOfPublicCalls()} public calls in ${time}ms`, {
718
+ txHash: processedTx.hash,
719
+ txFee: processedTx.txEffect.transactionFee.toBigInt(),
720
+ revertCode: processedTx.txEffect.revertCode.getCode(),
721
+ revertReason: processedTx.revertReason,
722
+ gasUsed: processedTx.gasUsed,
723
+ publicDataWriteCount: processedTx.txEffect.publicDataWrites.length,
724
+ nullifierCount: processedTx.txEffect.nullifiers.length,
725
+ noteHashCount: processedTx.txEffect.noteHashes.length,
726
+ contractClassLogCount: processedTx.txEffect.contractClassLogs.length,
727
+ publicLogCount: processedTx.txEffect.publicLogs.length,
728
+ privateLogCount: processedTx.txEffect.privateLogs.length,
729
+ l2ToL1MessageCount: processedTx.txEffect.l2ToL1Msgs.length,
730
+ durationMs: time
731
+ });
732
+ return [
733
+ processedTx,
734
+ returnValues ?? [],
735
+ debugLogs
736
+ ];
737
+ }
738
+ async doTreeInsertionsForPrivateOnlyTx(processedTx) {
739
+ const treeInsertionStart = process.hrtime.bigint();
740
+ // Update the state so that the next tx in the loop has the correct .startState
741
+ // NB: before this change, all .startStates were actually incorrect, but the issue was never caught because we either:
742
+ // a) had only 1 tx with public calls per block, so this loop had len 1
743
+ // b) always had a txHandler with the same db passed to it as this.db, which updated the db in buildBaseRollupHints in this loop
744
+ // To see how this ^ happens, move back to one shared db in test_context and run orchestrator_multi_public_functions.test.ts
745
+ // The below is taken from buildBaseRollupHints:
746
+ await this.guardedMerkleTree.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, padArrayEnd(processedTx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX));
747
+ try {
748
+ await this.guardedMerkleTree.batchInsert(MerkleTreeId.NULLIFIER_TREE, padArrayEnd(processedTx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map((n)=>n.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
749
+ } catch (cause) {
750
+ throw new Error(`Transaction ${processedTx.hash} failed with duplicate nullifiers`, {
751
+ cause
752
+ });
753
+ }
754
+ const treeInsertionEnd = process.hrtime.bigint();
755
+ this.metrics.recordTreeInsertions(Number(treeInsertionEnd - treeInsertionStart) / 1_000);
756
+ }
757
+ /** Processes the given tx within deadline or until the signal is aborted. */ async processTxWithinDeadline(tx, deadline, signal) {
758
+ const innerProcessFn = tx.hasPublicCalls() ? ()=>this.processTxWithPublicCalls(tx) : ()=>this.processPrivateOnlyTx(tx);
759
+ // Fake a delay per tx if instructed (used for tests)
760
+ const fakeDelayPerTxMs = this.opts.fakeProcessingDelayPerTxMs;
761
+ const processFn = fakeDelayPerTxMs && fakeDelayPerTxMs > 0 ? async ()=>{
762
+ const result = await innerProcessFn();
763
+ this.log.warn(`Sleeping ${fakeDelayPerTxMs}ms after processing tx ${tx.getTxHash().toString()}`);
764
+ await sleep(fakeDelayPerTxMs);
765
+ return result;
766
+ } : innerProcessFn;
767
+ const processingSignal = this.getProcessingSignal(tx, deadline, signal);
768
+ if (!processingSignal) {
769
+ return await processFn();
770
+ }
771
+ return await execWithSignal(()=>processFn(), processingSignal, (signal)=>signal.reason?.name === 'TimeoutError' ? new PublicProcessorTimeoutError() : new PublicProcessorAbortError());
772
+ }
773
+ getProcessingSignal(tx, deadline, signal) {
774
+ if (!deadline) {
775
+ return signal;
776
+ }
777
+ const timeout = +deadline - this.dateProvider.now();
778
+ if (timeout <= 0) {
779
+ throw new PublicProcessorTimeoutError();
780
+ }
781
+ const txHash = tx.getTxHash();
782
+ this.log.debug(`Processing tx ${txHash.toString()} within ${timeout}ms`, {
783
+ deadline: deadline.toISOString(),
784
+ now: new Date(this.dateProvider.now()).toISOString(),
785
+ txHash
786
+ });
787
+ const timeoutSignal = AbortSignal.timeout(timeout);
788
+ return signal ? AbortSignal.any([
789
+ signal,
790
+ timeoutSignal
791
+ ]) : timeoutSignal;
792
+ }
793
+ /**
794
+ * Creates the public data write for paying the tx fee.
795
+ * This is used in private only txs, since for txs with public calls
796
+ * the avm handles the fee payment itself.
797
+ */ async performFeePaymentPublicDataWrite(txFee, feePayer) {
798
+ const feeJuiceAddress = ProtocolContractAddress.FeeJuice;
799
+ const balanceSlot = await computeFeePayerBalanceStorageSlot(feePayer);
800
+ const leafSlot = await computeFeePayerBalanceLeafSlot(feePayer);
801
+ // This high-level db is used as a convenient helper. It could be done with the merkleTree directly.
802
+ const treesDB = new PublicTreesDB(this.guardedMerkleTree);
803
+ this.log.debug(`Deducting ${txFee.toBigInt()} balance in Fee Juice for ${feePayer}`);
804
+ const balance = await treesDB.storageRead(feeJuiceAddress, balanceSlot);
805
+ if (balance.lt(txFee)) {
806
+ throw new Error(`Not enough balance for fee payer to pay for transaction (got ${balance.toBigInt()} needs ${txFee.toBigInt()})`);
807
+ }
808
+ const updatedBalance = balance.sub(txFee);
809
+ await treesDB.storageWrite(feeJuiceAddress, balanceSlot, updatedBalance);
810
+ return new PublicDataWrite(leafSlot, updatedBalance);
811
+ }
812
+ async processPrivateOnlyTx(tx) {
813
+ const gasFees = this.globalVariables.gasFees;
814
+ const transactionFee = computeTransactionFee(gasFees, tx.data.constants.txContext.gasSettings, tx.data.gasUsed);
815
+ const feePaymentPublicDataWrite = await this.performFeePaymentPublicDataWrite(transactionFee, tx.data.feePayer);
816
+ const processedTx = makeProcessedTxFromPrivateOnlyTx(tx, transactionFee, feePaymentPublicDataWrite, this.globalVariables);
817
+ this.metrics.recordClassPublication(...tx.getContractClassLogs().filter((log)=>ContractClassPublishedEvent.isContractClassPublishedEvent(log)).map((log)=>ContractClassPublishedEvent.fromLog(log)));
818
+ // Fee payment insertion has already been done. Do the rest.
819
+ await this.doTreeInsertionsForPrivateOnlyTx(processedTx);
820
+ this.contractsDB.addNewContracts(tx);
821
+ return [
822
+ processedTx,
823
+ undefined,
824
+ []
825
+ ];
826
+ }
827
+ async processTxWithPublicCalls(tx) {
828
+ const timer = new Timer();
829
+ const result = await this.publicTxSimulator.simulate(tx);
830
+ // TODO: use the callStackMetadata here to extract more data about public execution
831
+ const { hints, publicInputs, publicTxEffect, gasUsed, revertCode/*callStackMetadata*/ } = result;
832
+ const contractClassLogs = revertCode.isOK() ? tx.getContractClassLogs() : tx.getSplitContractClassLogs(false);
833
+ this.metrics.recordClassPublication(...contractClassLogs.filter((log)=>ContractClassPublishedEvent.isContractClassPublishedEvent(log)).map((log)=>ContractClassPublishedEvent.fromLog(log)));
834
+ // TODO(fcarreiro): remove phase count metric.
835
+ const durationMs = timer.ms();
836
+ this.metrics.recordTx(/*phaseCount=*/ 1, durationMs, gasUsed.publicGas);
837
+ // Extract the return values from the call stack metadata.
838
+ const appLogicReturnValues = result.getAppLogicReturnValues();
839
+ // Extract the revert reason from the call stack metadata.
840
+ const revertReason = result.findRevertReason();
841
+ // Create proving request if we have hints and public inputs.
842
+ const avmProvingRequest = hints && publicInputs ? PublicProcessor.generateProvingRequest(publicInputs, hints) : undefined;
843
+ const processedTx = makeProcessedTxFromTxWithPublicCalls(tx, this.globalVariables, avmProvingRequest, publicTxEffect, gasUsed, revertCode, revertReason);
844
+ return [
845
+ processedTx,
846
+ appLogicReturnValues,
847
+ result.logs ?? []
848
+ ];
849
+ }
850
+ /**
851
+ * Generate the proving request for the AVM circuit.
852
+ */ static generateProvingRequest(publicInputs, hints = AvmExecutionHints.empty()) {
853
+ return {
854
+ type: ProvingRequestType.PUBLIC_VM,
855
+ inputs: new AvmCircuitInputs(hints, publicInputs)
856
+ };
857
+ }
858
+ }