Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
gas.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <cstdint>
5
21
22namespace bb::avm2::constraining {
23namespace {
24
25using tracegen::ExecutionTraceBuilder;
26using tracegen::PrecomputedTraceBuilder;
27using tracegen::TestTraceContainer;
29using C = Column;
30using gas = bb::avm2::gas<FF>;
32
33TEST(GasConstrainingTest, EmptyRow)
34{
35 check_relation<gas>(testing::empty_trace());
36}
37
38TEST(GasConstrainingTest, AllSubrelations)
39{
40 uint32_t opcode_l2_gas = 100;
41 uint32_t addressing_gas = 50;
42 uint32_t base_da_gas = 3;
43 uint32_t dynamic_l2_gas = 10;
44 uint32_t dynamic_da_gas = 5;
45 uint32_t dynamic_l2_gas_factor = 2;
46 uint32_t dynamic_da_gas_factor = 1;
47 uint32_t l2_gas_limit = 1000;
48 uint32_t da_gas_limit = 800;
49 uint32_t prev_l2_gas_used = 500;
50 uint32_t prev_da_gas_used = 200;
51 uint64_t total_gas_l2 =
52 prev_l2_gas_used + opcode_l2_gas + addressing_gas + (dynamic_l2_gas * dynamic_l2_gas_factor);
53 uint64_t total_gas_da = prev_da_gas_used + base_da_gas + (dynamic_da_gas * dynamic_da_gas_factor);
54
55 TestTraceContainer trace({ {
56 { C::execution_sel_should_check_gas, 1 },
57 // looked up in execution.pil
58 { C::execution_opcode_gas, opcode_l2_gas },
59 { C::execution_addressing_gas, addressing_gas },
60 { C::execution_base_da_gas, base_da_gas },
61 { C::execution_dynamic_l2_gas, dynamic_l2_gas },
62 { C::execution_dynamic_da_gas, dynamic_da_gas },
63 // event
64 { C::execution_l2_gas_limit, l2_gas_limit },
65 { C::execution_da_gas_limit, da_gas_limit },
66 { C::execution_prev_l2_gas_used, prev_l2_gas_used },
67 { C::execution_prev_da_gas_used, prev_da_gas_used },
68 { C::execution_dynamic_l2_gas_factor, dynamic_l2_gas_factor },
69 { C::execution_dynamic_da_gas_factor, dynamic_da_gas_factor },
70 // Derived cumulative gas used.
71 { C::execution_total_gas_l2, total_gas_l2 },
72 { C::execution_total_gas_da, total_gas_da },
73 // out
74 { C::execution_out_of_gas_l2, 0 },
75 { C::execution_out_of_gas_da, 0 },
76 { C::execution_sel_out_of_gas, 0 },
77 } });
78
79 // Add GT lookup values
80 // L2 gas
81 trace.set(0,
82 { {
83 { C::gt_sel, 1 },
84 { C::gt_input_a, total_gas_l2 },
85 { C::gt_input_b, l2_gas_limit },
86 { C::gt_res, 0 },
87 } });
88 // DA gas
89 trace.set(1,
90 { {
91 { C::gt_sel, 1 },
92 { C::gt_input_a, total_gas_da },
93 { C::gt_input_b, da_gas_limit },
94 { C::gt_res, 0 },
95 } });
96
97 check_relation<gas>(trace);
98 check_interaction<ExecutionTraceBuilder,
101
102 // Can't cheat OOG.
103 trace.set(0,
104 { {
105 { C::execution_out_of_gas_l2, 0 },
106 { C::execution_out_of_gas_da, 0 },
107 { C::execution_sel_out_of_gas, 1 },
108 } });
109 EXPECT_THROW(check_relation<gas>(trace), std::runtime_error);
110 trace.set(0,
111 { {
112 { C::execution_out_of_gas_l2, 1 },
113 { C::execution_out_of_gas_da, 1 },
114 { C::execution_sel_out_of_gas, 1 },
115 } });
116 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_l2_settings>(trace)),
117 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_L2. Could not find tuple in destination.");
118 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_da_settings>(trace)),
119 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_DA. Could not find tuple in destination.");
120}
121
122TEST(GasConstrainingTest, OutOfGasBase)
123{
124 uint32_t opcode_l2_gas = 100;
125 uint32_t addressing_gas = 50;
126 uint32_t base_da_gas = 100;
127 uint32_t dynamic_l2_gas = 0;
128 uint32_t dynamic_da_gas = 0;
129 uint32_t dynamic_l2_gas_factor = 2;
130 uint32_t dynamic_da_gas_factor = 1;
131 uint32_t l2_gas_limit = 100;
132 uint32_t da_gas_limit = 80;
133 uint32_t prev_l2_gas_used = 0;
134 uint32_t prev_da_gas_used = 0;
135 uint64_t total_gas_l2 =
136 prev_l2_gas_used + opcode_l2_gas + addressing_gas + (dynamic_l2_gas * dynamic_l2_gas_factor);
137 uint64_t total_gas_da = prev_da_gas_used + base_da_gas + (dynamic_da_gas * dynamic_da_gas_factor);
138
139 TestTraceContainer trace({ {
140 { C::execution_sel_should_check_gas, 1 },
141 // looked up in execution.pil
142 { C::execution_opcode_gas, opcode_l2_gas },
143 { C::execution_addressing_gas, addressing_gas },
144 { C::execution_base_da_gas, base_da_gas },
145 { C::execution_dynamic_l2_gas, dynamic_l2_gas },
146 { C::execution_dynamic_da_gas, dynamic_da_gas },
147 // event
148 { C::execution_l2_gas_limit, l2_gas_limit },
149 { C::execution_da_gas_limit, da_gas_limit },
150 { C::execution_prev_l2_gas_used, prev_l2_gas_used },
151 { C::execution_prev_da_gas_used, prev_da_gas_used },
152 { C::execution_dynamic_l2_gas_factor, dynamic_l2_gas_factor },
153 { C::execution_dynamic_da_gas_factor, dynamic_da_gas_factor },
154 // Derived cumulative gas used.
155 { C::execution_total_gas_l2, total_gas_l2 },
156 { C::execution_total_gas_da, total_gas_da },
157 // out
158 { C::execution_out_of_gas_l2, 1 },
159 { C::execution_out_of_gas_da, 1 },
160 { C::execution_sel_out_of_gas, 1 },
161 } });
162
163 // Add GT lookup values
164 // L2 gas
165 trace.set(0,
166 { {
167 { C::gt_sel, 1 },
168 { C::gt_input_a, total_gas_l2 },
169 { C::gt_input_b, l2_gas_limit },
170 { C::gt_res, 1 },
171 } });
172 // DA gas
173 trace.set(1,
174 { {
175 { C::gt_sel, 1 },
176 { C::gt_input_a, total_gas_da },
177 { C::gt_input_b, da_gas_limit },
178 { C::gt_res, 1 },
179 } });
180
181 check_relation<gas>(trace);
182 check_interaction<ExecutionTraceBuilder,
185
186 // Can't cheat OOG.
187 trace.set(0,
188 { {
189 { C::execution_out_of_gas_l2, 0 },
190 { C::execution_out_of_gas_da, 0 },
191 { C::execution_sel_out_of_gas, 0 },
192 } });
193
194 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_l2_settings>(trace)),
195 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_L2. Could not find tuple in destination.");
196 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_da_settings>(trace)),
197 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_DA. Could not find tuple in destination.");
198}
199
200TEST(GasConstrainingTest, OutOfGasDynamic)
201{
202 uint32_t opcode_l2_gas = 1;
203 uint32_t addressing_gas = 0;
204 uint32_t base_da_gas = 3;
205 uint32_t dynamic_l2_gas = 10;
206 uint32_t dynamic_da_gas = 9;
207 uint32_t dynamic_l2_gas_factor = 10;
208 uint32_t dynamic_da_gas_factor = 10;
209 uint32_t l2_gas_limit = 100;
210 uint32_t da_gas_limit = 80;
211 uint32_t prev_l2_gas_used = 0;
212 uint32_t prev_da_gas_used = 0;
213 uint64_t total_gas_l2 =
214 prev_l2_gas_used + opcode_l2_gas + addressing_gas + (dynamic_l2_gas * dynamic_l2_gas_factor);
215 uint64_t total_gas_da = prev_da_gas_used + base_da_gas + (dynamic_da_gas * dynamic_da_gas_factor);
216
217 TestTraceContainer trace({ {
218 { C::execution_sel_should_check_gas, 1 },
219 // looked up in execution.pil
220 { C::execution_opcode_gas, opcode_l2_gas },
221 { C::execution_addressing_gas, addressing_gas },
222 { C::execution_base_da_gas, base_da_gas },
223 { C::execution_dynamic_l2_gas, dynamic_l2_gas },
224 { C::execution_dynamic_da_gas, dynamic_da_gas },
225 // event
226 { C::execution_l2_gas_limit, l2_gas_limit },
227 { C::execution_da_gas_limit, da_gas_limit },
228 { C::execution_prev_l2_gas_used, prev_l2_gas_used },
229 { C::execution_prev_da_gas_used, prev_da_gas_used },
230 { C::execution_dynamic_l2_gas_factor, dynamic_l2_gas_factor },
231 { C::execution_dynamic_da_gas_factor, dynamic_da_gas_factor },
232 // Derived cumulative gas used.
233 { C::execution_total_gas_l2, total_gas_l2 },
234 { C::execution_total_gas_da, total_gas_da },
235 // out
236 { C::execution_out_of_gas_l2, 1 },
237 { C::execution_out_of_gas_da, 1 },
238 { C::execution_sel_out_of_gas, 1 },
239 } });
240
241 // Add GT lookup values
242 // L2 gas
243 trace.set(0,
244 { {
245 { C::gt_sel, 1 },
246 { C::gt_input_a, total_gas_l2 },
247 { C::gt_input_b, l2_gas_limit },
248 { C::gt_res, 1 },
249 } });
250 // DA gas
251 trace.set(1,
252 { {
253 { C::gt_sel, 1 },
254 { C::gt_input_a, total_gas_da },
255 { C::gt_input_b, da_gas_limit },
256 { C::gt_res, 1 },
257 } });
258 check_relation<gas>(trace);
259 check_interaction<ExecutionTraceBuilder,
262
263 // Can't cheat OOG.
264 trace.set(0,
265 { {
266 { C::execution_out_of_gas_l2, 0 },
267 { C::execution_out_of_gas_da, 0 },
268 { C::execution_sel_out_of_gas, 0 },
269 } });
270 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_l2_settings>(trace)),
271 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_L2. Could not find tuple in destination.");
272 EXPECT_THROW_WITH_MESSAGE((check_interaction<ExecutionTraceBuilder, lookup_gas_is_out_of_gas_da_settings>(trace)),
273 "Failed.*LOOKUP_GAS_IS_OUT_OF_GAS_DA. Could not find tuple in destination.");
274}
275
276TEST(GasConstrainingTest, NoCheckNoOOG)
277{
278 TestTraceContainer trace({ {
279 { C::execution_sel_should_check_gas, 0 },
280 // out
281 { C::execution_out_of_gas_l2, 0 },
282 { C::execution_out_of_gas_da, 0 },
283 { C::execution_sel_out_of_gas, 0 },
284 } });
285 check_relation<gas>(trace);
286
287 // Can't cheat OOG.
288 trace.set(0,
289 { {
290 { C::execution_out_of_gas_l2, 1 },
291 { C::execution_out_of_gas_da, 1 },
292 { C::execution_sel_out_of_gas, 1 },
293 } });
294 EXPECT_THROW(check_relation<gas>(trace), std::runtime_error);
295}
296
297TEST(GasConstrainingTest, DynGasFactorBitwise)
298{
299 PrecomputedTraceBuilder precomputed_builder;
300 TestTraceContainer trace({
301 {
302 { C::execution_sel, 1 },
303 { C::execution_mem_tag_reg_0_, static_cast<uint8_t>(ValueTag::U16) },
304 { C::execution_sel_gas_bitwise, 1 },
305 { C::execution_dynamic_l2_gas_factor, get_tag_bytes(ValueTag::U16) },
306 },
307 });
308
310 precomputed_builder.process_misc(trace, 7); // Need at least clk values from 0-6 for the lookup
311 check_interaction<ExecutionTraceBuilder, lookup_execution_dyn_l2_factor_bitwise_settings>(trace);
312
313 trace.set(C::execution_dynamic_l2_gas_factor, 0, 100); // Set to some random value that can't be looked up
315 (check_interaction<tracegen::ExecutionTraceBuilder, lookup_execution_dyn_l2_factor_bitwise_settings>(trace)),
316 "Failed.*EXECUTION_DYN_L2_FACTOR_BITWISE. Could not find tuple in destination.");
317}
318
319TEST(GasConstrainingTest, DynGasFactorToRadix)
320{
321 PrecomputedTraceBuilder precomputed_builder;
322
323 uint32_t radix = 10;
324 uint32_t num_limbs = 20;
325 uint32_t num_p_limbs = static_cast<uint32_t>(get_p_limbs_per_radix_size(radix));
326 TestTraceContainer trace(
327 { {
328 { C::execution_sel, 1 },
329 { C::execution_register_1_, radix },
330 { C::execution_register_2_, num_limbs },
331 { C::execution_sel_should_check_gas, 1 },
332 // To Radix BE Dynamic Gas
333 { C::execution_sel_gas_to_radix, 1 },
334 { C::execution_dyn_gas_id, AVM_DYN_GAS_ID_TORADIX },
335 { C::execution_two_five_six, 256 },
336 { C::execution_sel_radix_gt_256, 0 },
337 { C::execution_sel_lookup_num_p_limbs, 1 },
338 { C::execution_num_p_limbs, num_p_limbs },
339 { C::execution_sel_use_num_limbs, num_limbs > num_p_limbs ? 1 : 0 },
340 { C::execution_dynamic_l2_gas_factor, num_limbs > num_p_limbs ? num_limbs : num_p_limbs },
341 // GT Trace, used to check if radix > 256
342 { C::gt_sel, 1 },
343 { C::gt_input_a, radix },
344 { C::gt_input_b, 256 },
345 { C::gt_res, 0 },
346 },
347 {
348 // Gt Trace, compare num_limbs > num_p_limbs
349 { C::gt_sel, 1 },
350 { C::gt_input_a, num_limbs },
351 { C::gt_input_b, num_p_limbs },
352 { C::gt_res, num_limbs > num_p_limbs ? 1 : 0 },
353 } });
354
357
358 check_interaction<ExecutionTraceBuilder,
363
364 trace.set(C::execution_dynamic_l2_gas_factor, 0, 100); // Set to some random value is incorrect
366 ".*subrelation DYN_L2_FACTOR_TO_RADIX_BE failed.*");
367}
368
369TEST(GasConstrainingTest, DynGasFactorInvalidRadix)
370{
371 PrecomputedTraceBuilder precomputed_builder;
372
373 uint32_t radix = 1000;
374 uint32_t num_limbs = 20;
375 uint32_t num_p_limbs = 32; // When radix > 256, we set num_p_limbs to 32.
376 TestTraceContainer trace(
377 { {
378 { C::execution_sel, 1 },
379 { C::execution_register_1_, radix },
380 { C::execution_register_2_, num_limbs },
381 { C::execution_sel_should_check_gas, 1 },
382 // To Radix BE Dynamic Gas
383 { C::execution_sel_gas_to_radix, 1 },
384 { C::execution_dyn_gas_id, AVM_DYN_GAS_ID_TORADIX },
385 { C::execution_two_five_six, 256 },
386 { C::execution_sel_radix_gt_256, radix > 256 ? 1 : 0 },
387 { C::execution_sel_lookup_num_p_limbs, radix <= 256 ? 1 : 0 },
388 { C::execution_num_p_limbs, num_p_limbs },
389 { C::execution_sel_use_num_limbs, num_limbs > num_p_limbs ? 1 : 0 },
390 { C::execution_dynamic_l2_gas_factor, num_limbs > num_p_limbs ? num_limbs : num_p_limbs },
391 // GT Trace, used to check if radix > 256
392 { C::gt_sel, 1 },
393 { C::gt_input_a, radix },
394 { C::gt_input_b, 256 },
395 { C::gt_res, radix > 256 ? 1 : 0 },
396 },
397 {
398 // Gt Trace, compare num_limbs > num_p_limbs
399 { C::gt_sel, 1 },
400 { C::gt_input_a, num_limbs },
401 { C::gt_input_b, num_p_limbs },
402 { C::gt_res, num_limbs > num_p_limbs ? 1 : 0 },
403 } });
404
407
408 check_interaction<ExecutionTraceBuilder,
412 check_relation<execution>(trace,
416}
417
418} // namespace
419} // namespace bb::avm2::constraining
#define AVM_DYN_GAS_ID_TORADIX
static constexpr size_t SR_DYN_L2_FACTOR_TO_RADIX_BE
Definition execution.hpp:47
static constexpr size_t SR_DYN_GAS_ID_DECOMPOSITION
Definition execution.hpp:51
static constexpr size_t SR_NUM_P_LIMBS_CEIL
Definition execution.hpp:46
void process_to_radix_safe_limbs(TraceContainer &trace)
void process_misc(TraceContainer &trace, const uint32_t num_rows=MAX_AVM_TRACE_SIZE)
void set(Column col, uint32_t row, const FF &value)
PrecomputedTraceBuilder precomputed_builder
Definition alu.test.cpp:119
TestTraceContainer trace
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(TxExecutionConstrainingTest, WriteTreeValue)
Definition tx.test.cpp:402
TestTraceContainer empty_trace()
Definition fixtures.cpp:153
size_t get_p_limbs_per_radix_size(size_t radix)
Definition to_radix.cpp:54
lookup_settings< lookup_gas_is_out_of_gas_l2_settings_ > lookup_gas_is_out_of_gas_l2_settings
lookup_settings< lookup_gas_is_out_of_gas_da_settings_ > lookup_gas_is_out_of_gas_da_settings
lookup_settings< lookup_execution_get_p_limbs_settings_ > lookup_execution_get_p_limbs_settings
lookup_settings< lookup_execution_check_radix_gt_256_settings_ > lookup_execution_check_radix_gt_256_settings
lookup_settings< lookup_execution_get_max_limbs_settings_ > lookup_execution_get_max_limbs_settings
uint8_t get_tag_bytes(ValueTag tag)
typename Flavor::FF FF
NiceMock< MockExecution > execution