Skip to content

Commit 8d6f1cd

Browse files
committed
fix(avm)!: last_child id constraints
1 parent d06ed9b commit 8d6f1cd

File tree

6 files changed

+399
-181
lines changed

6 files changed

+399
-181
lines changed

barretenberg/cpp/pil/vm2/context.pil

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ namespace execution;
176176
#[BYTECODE_ID_NEXT_ROW]
177177
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (bytecode_id' - bytecode_id) = 0;
178178

179-
180179
// transaction fee gets set at the start of an enqueued call and remains the same throughout
181180
// TODO(dbanks12): tracegen and test this
182181
#[TRANSACTION_FEE_NEXT_ROW]
@@ -207,23 +206,47 @@ namespace execution;
207206
NOT_LAST_EXEC * sel_enter_call * (parent_calldata_size' - register[3]) = 0;
208207

209208
pol NESTED_RET_REV_ONLY = nested_exit_call * (1 - sel_error);
209+
210210
// NESTED_RET_REV_ONLY = 1 ==> rop[1] (resolved operand 2 from execution trace)
211-
// sel_error = 1 ==> last_child_returndata_size' = 0;
211+
// sel_error = 1 ==> last_child_returndata_addr' = 0;
212212
// sel_enter_call = 1 ==> last_child_returndata_addr' = 0;
213+
// enqueued_call_start = 1 ==> last_child_returndata_addr = 0; <-- This row is 0
213214
// otherwise = 0 ==> last_child_returndata_addr' = last_child_returndata_addr
214-
#[RD_OFFSET_NEXT_ROW]
215-
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_addr' - last_child_returndata_addr) = 0;
215+
#[RET_REV_RD_ADDR]
216216
NOT_LAST_EXEC * NESTED_RET_REV_ONLY * (last_child_returndata_addr' - rop[1]) = 0;
217+
#[NEXT_RD_ADDR_IS_ZERO]
217218
NOT_LAST_EXEC * (sel_enter_call + sel_error) * last_child_returndata_addr' = 0;
219+
#[RD_ADDR_IS_ZERO]
220+
enqueued_call_start * last_child_returndata_addr = 0;
221+
#[PROPAGATE_RD_ADDR]
222+
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_addr' - last_child_returndata_addr) = 0;
218223

219224
// NESTED_RET_REV_ONLY = 1 ==> register[0] (intermediate register 1 from execution trace)
220-
// sel_error = 1 ==> last_child_returndata_size' = 0;
221-
// sel_enter_call = 1 ==> last_child_returndata_size' = 0;
222-
// otherwise = 0 ==> last_child_returndata_size' = last_child_returndata_size
223-
#[RD_SIZE_OFFSET_NEXT_ROW]
224-
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_size' - last_child_returndata_size) = 0;
225+
// sel_error = 1 ==> last_child_returndata_size' = 0;
226+
// sel_enter_call = 1 ==> last_child_returndata_size' = 0;
227+
// enqueued_call_start = 1 ==> last_child_returndata_size = 0; <-- Current row is 0
228+
// otherwise = 0 ==> last_child_returndata_size' = last_child_returndata_size
229+
#[RET_REV_RD_SIZE]
225230
NOT_LAST_EXEC * NESTED_RET_REV_ONLY * (last_child_returndata_size' - register[0]) = 0;
231+
#[NEXT_RD_SIZE_IS_ZERO]
226232
NOT_LAST_EXEC * (sel_enter_call + sel_error) * last_child_returndata_size' = 0;
233+
#[RD_SIZE_IS_ZERO]
234+
enqueued_call_start * last_child_returndata_addr = 0;
235+
#[PROPAGATE_RD_SIZE]
236+
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_size' - last_child_returndata_size) = 0;
237+
238+
// sel_exit_call = 1 ==> last_child_id' = context_id; <-- sel_exit_call includes error case
239+
// sel_enter_call = 1 ==> last_child_id' = 0;
240+
// enqueued_call_start = 1 ==> last_child_id = 0; <-- Current row is 0
241+
// otherwise = 0 ==> last_child_id' = last_child_id;
242+
#[EXIT_CALL_LAST_CHILD_ID]
243+
NOT_LAST_EXEC * sel_exit_call * (last_child_id' - context_id) = 0;
244+
#[ENTER_CALL_LAST_CHILD_ID]
245+
NOT_LAST_EXEC * sel_enter_call * last_child_id' = 0;
246+
#[LAST_CHILD_ID_IS_ZERO]
247+
enqueued_call_start * last_child_id = 0;
248+
#[PROPAGATE_LAST_CHILD_ID]
249+
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_id' - last_child_id) = 0;
227250

228251
// nested_exit_call = 1 ==> l2_gas_limit' = parent_l2_gas_limit
229252
// sel_enter_call = 1 ==> constraints come from call logic
@@ -397,7 +420,7 @@ namespace execution;
397420
};
398421

399422
pol commit nested_return;
400-
nested_return = nested_exit_call * sel_execute_return;
423+
nested_return = nested_exit_call * sel_execute_return * (1 - sel_error);
401424
#[CTX_STACK_RETURN]
402425
nested_return {
403426
context_id,

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/context.test.cpp

Lines changed: 134 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "barretenberg/vm2/generated/relations/lookups_context.hpp"
1010
#include "barretenberg/vm2/testing/fixtures.hpp"
1111
#include "barretenberg/vm2/testing/macros.hpp"
12+
#include "barretenberg/vm2/tracegen/execution_trace.hpp"
1213
#include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp"
1314
#include "barretenberg/vm2/tracegen/test_trace_container.hpp"
1415

@@ -19,8 +20,6 @@ using tracegen::TestTraceContainer;
1920
using FF = AvmFlavorSettings::FF;
2021
using C = Column;
2122
using context = bb::avm2::context<FF>;
22-
using stack_call_interaction = bb::avm2::lookup_context_ctx_stack_call_relation<FF>;
23-
using stack_return_interaction = bb::avm2::lookup_context_ctx_stack_return_relation<FF>;
2423

2524
TEST(ContextConstrainingTest, EmptyRow)
2625
{
@@ -53,8 +52,6 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn)
5352
{ C::context_stack_parent_da_gas_limit, 4000 },
5453
{ C::context_stack_parent_l2_gas_used, 500 },
5554
{ C::context_stack_parent_da_gas_used, 1500 },
56-
{ C::context_stack_parent_calldata_addr, 0 },
57-
{ C::context_stack_parent_calldata_size, 0 },
5855
},
5956
// First Row of execution
6057
{
@@ -129,7 +126,8 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn)
129126
{ C::execution_next_context_id, 3 },
130127
{ C::execution_context_id, 1 },
131128
{ C::execution_parent_id, 0 },
132-
{ C::execution_pc, 2 }, // Based on next_pc of CALL step
129+
{ C::execution_last_child_id, 2 }, // Previous context id
130+
{ C::execution_pc, 2 }, // Based on next_pc of CALL step
133131
{ C::execution_msg_sender, 0 },
134132
{ C::execution_contract_address, 0 },
135133
{ C::execution_bytecode_id, top_bytecode_id }, // Restored from context stack
@@ -142,10 +140,135 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn)
142140
{ C::execution_parent_da_gas_limit, 4000 },
143141
{ C::execution_parent_l2_gas_used, 500 },
144142
{ C::execution_parent_da_gas_used, 1500 },
143+
},
144+
{
145+
{ C::execution_sel, 0 },
146+
{ C::execution_last, 1 },
147+
} });
148+
149+
check_relation<context>(trace);
150+
151+
check_interaction<tracegen::ExecutionTraceBuilder,
152+
lookup_context_ctx_stack_call_settings,
153+
lookup_context_ctx_stack_rollback_settings,
154+
lookup_context_ctx_stack_return_settings>(trace);
155+
}
156+
157+
TEST(ContextConstrainingTest, ContextSwitchingExceptionalHalt)
158+
{
159+
constexpr uint32_t top_bytecode_id = 0x12345678;
160+
constexpr uint32_t nested_bytecode_id = 0x456789ab;
161+
162+
TestTraceContainer trace(
163+
{ {
164+
{ C::execution_next_context_id, 0 },
165+
{ C::precomputed_first_row, 1 },
166+
// Context Stack Rows
167+
{ C::context_stack_sel, 1 },
168+
{ C::context_stack_entered_context_id, 2 },
169+
{ C::context_stack_context_id, 1 },
170+
{ C::context_stack_parent_id, 0 },
171+
{ C::context_stack_next_pc, 2 },
172+
{ C::context_stack_msg_sender, 0 },
173+
{ C::context_stack_contract_address, 0 },
174+
{ C::context_stack_bytecode_id, top_bytecode_id },
175+
{ C::context_stack_is_static, 0 },
176+
{ C::context_stack_parent_calldata_addr, 0 },
177+
{ C::context_stack_parent_calldata_size, 0 },
178+
{ C::context_stack_parent_l2_gas_limit, 2000 },
179+
{ C::context_stack_parent_da_gas_limit, 4000 },
180+
{ C::context_stack_parent_l2_gas_used, 500 },
181+
{ C::context_stack_parent_da_gas_used, 1500 },
182+
},
183+
// First Row of execution
184+
{
185+
{ C::execution_sel, 1 },
186+
{ C::execution_pc, 0 },
187+
{ C::execution_next_pc, 1 },
188+
{ C::execution_context_id, 1 },
189+
{ C::execution_next_context_id, 2 },
190+
{ C::execution_bytecode_id, top_bytecode_id },
191+
{ C::execution_parent_l2_gas_limit, 2000 },
192+
{ C::execution_parent_da_gas_limit, 4000 },
193+
{ C::execution_parent_l2_gas_used, 500 },
194+
{ C::execution_parent_da_gas_used, 1500 },
195+
{ C::execution_enqueued_call_start, 1 },
196+
},
197+
// CALL
198+
{
199+
{ C::execution_sel, 1 },
200+
{ C::execution_pc, 1 },
201+
{ C::execution_next_pc, 2 },
202+
{ C::execution_sel_execute_call, 1 },
203+
{ C::execution_sel_enter_call, 1 },
204+
{ C::execution_context_id, 1 },
205+
{ C::execution_next_context_id, 2 },
206+
{ C::execution_bytecode_id, top_bytecode_id }, // Same as previous row (propagated)
207+
{ C::execution_rop_4_, /*cd offset=*/10 },
208+
{ C::execution_register_2_, /*contract address=*/0xdeadbeef },
209+
{ C::execution_register_3_, /*cd size=*/1 },
210+
{ C::execution_parent_l2_gas_limit, 2000 },
211+
{ C::execution_parent_da_gas_limit, 4000 },
212+
{ C::execution_parent_l2_gas_used, 500 },
213+
{ C::execution_parent_da_gas_used, 1500 },
214+
},
215+
// First Row in new context
216+
{
217+
{ C::execution_sel, 1 },
218+
{ C::execution_pc, 0 }, // pc=0 because it is after a CALL
219+
{ C::execution_next_pc, 20 },
220+
{ C::execution_context_id, 2 }, // Previous row next_context_id
221+
{ C::execution_next_context_id, 3 }, // Incremented due to previous call
222+
{ C::execution_parent_id, 1 }, // Previous row context id
223+
{ C::execution_is_parent_id_inv, 1 },
224+
{ C::execution_has_parent_ctx, 1 },
225+
{ C::execution_contract_address, 0xdeadbeef },
226+
{ C::execution_bytecode_id, nested_bytecode_id }, // New bytecode_id on entering new context
227+
{ C::execution_parent_calldata_addr, 10 },
228+
{ C::execution_parent_calldata_size, 1 },
229+
},
230+
// Exceptional Halt Row
231+
{
232+
{ C::execution_sel, 1 },
233+
{ C::execution_pc, 20 },
234+
{ C::execution_next_pc, 30 },
235+
{ C::execution_sel_execute_return, 1 },
236+
{ C::execution_rop_0_, 500 }, // Return data size offset
237+
{ C::execution_rop_1_, 600 }, // Return data offset
238+
{ C::execution_register_0_, 200 }, // Return data size
239+
{ C::execution_sel_exit_call, 1 },
240+
{ C::execution_nested_exit_call, 1 },
241+
{ C::execution_sel_error, 1 }, // Exceptional Halt
242+
{ C::execution_context_id, 2 },
243+
{ C::execution_next_context_id, 3 },
244+
{ C::execution_parent_id, 1 },
245+
{ C::execution_is_parent_id_inv, 1 },
246+
{ C::execution_has_parent_ctx, 1 },
247+
{ C::execution_contract_address, 0xdeadbeef },
248+
{ C::execution_bytecode_id, nested_bytecode_id }, // Propagated within same context
249+
{ C::execution_parent_calldata_addr, 10 },
250+
{ C::execution_parent_calldata_size, 1 },
251+
},
252+
{
253+
{ C::execution_sel, 1 },
254+
{ C::execution_next_context_id, 3 },
255+
{ C::execution_context_id, 1 },
256+
{ C::execution_parent_id, 0 },
257+
{ C::execution_last_child_id, 2 }, // Previous context id
258+
{ C::execution_pc, 2 }, // Based on next_pc of CALL step
259+
{ C::execution_next_pc, 3 },
260+
{ C::execution_msg_sender, 0 },
261+
{ C::execution_contract_address, 0 },
262+
{ C::execution_bytecode_id, top_bytecode_id }, // Restored from context stack
263+
{ C::execution_is_static, 0 },
145264
{ C::execution_parent_calldata_addr, 0 },
146265
{ C::execution_parent_calldata_size, 0 },
147-
{ C::execution_last_child_returndata_size, 200 }, // Return data size
148-
{ C::execution_last_child_returndata_addr, 600 }, // Return data offset
266+
{ C::execution_last_child_returndata_size, 0 }, // Return data size reset
267+
{ C::execution_last_child_returndata_addr, 0 }, // Return data offset reset
268+
{ C::execution_parent_l2_gas_limit, 2000 },
269+
{ C::execution_parent_da_gas_limit, 4000 },
270+
{ C::execution_parent_l2_gas_used, 500 },
271+
{ C::execution_parent_da_gas_used, 1500 },
149272
},
150273
{
151274
{ C::execution_sel, 0 },
@@ -154,9 +277,10 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn)
154277

155278
check_relation<context>(trace);
156279

157-
// TODO: Migrate to check_interaction pattern once these lookups are added in a builder
158-
tracegen::LookupIntoDynamicTableSequential<stack_call_interaction::Settings>().process(trace);
159-
tracegen::LookupIntoDynamicTableSequential<stack_return_interaction::Settings>().process(trace);
280+
check_interaction<tracegen::ExecutionTraceBuilder,
281+
lookup_context_ctx_stack_call_settings,
282+
lookup_context_ctx_stack_rollback_settings,
283+
lookup_context_ctx_stack_return_settings>(trace);
160284
}
161285

162286
TEST(ContextConstrainingTest, GasNextRow)

barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ namespace bb::avm2 {
134134
struct AvmFlavorVariables {
135135
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 133;
136136
static constexpr size_t NUM_WITNESS_ENTITIES = 2936;
137-
static constexpr size_t NUM_SHIFTED_ENTITIES = 316;
137+
static constexpr size_t NUM_SHIFTED_ENTITIES = 317;
138138
static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES;
139-
static constexpr size_t NUM_ALL_ENTITIES = 3385;
139+
static constexpr size_t NUM_ALL_ENTITIES = 3386;
140140

141141
// Need to be templated for recursive verifier
142142
template <typename FF_>

0 commit comments

Comments
 (0)