Skip to content

Commit b3ed32f

Browse files
committed
fix(avm)!: last_child id constraints
1 parent 9965aa8 commit b3ed32f

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
@@ -174,7 +174,6 @@ namespace execution;
174174
#[BYTECODE_ID_NEXT_ROW]
175175
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (bytecode_id' - bytecode_id) = 0;
176176

177-
178177
// transaction fee gets set at the start of an enqueued call and remains the same throughout
179178
// TODO(dbanks12): tracegen and test this
180179
#[TRANSACTION_FEE_NEXT_ROW]
@@ -205,23 +204,47 @@ namespace execution;
205204
NOT_LAST_EXEC * sel_enter_call * (parent_calldata_size' - register[3]) = 0;
206205

207206
pol NESTED_RET_REV_ONLY = nested_exit_call * (1 - sel_error);
207+
208208
// NESTED_RET_REV_ONLY = 1 ==> rop[1] (resolved operand 2 from execution trace)
209-
// sel_error = 1 ==> last_child_returndata_size' = 0;
209+
// sel_error = 1 ==> last_child_returndata_addr' = 0;
210210
// sel_enter_call = 1 ==> last_child_returndata_addr' = 0;
211+
// enqueued_call_start = 1 ==> last_child_returndata_addr = 0; <-- This row is 0
211212
// otherwise = 0 ==> last_child_returndata_addr' = last_child_returndata_addr
212-
#[RD_OFFSET_NEXT_ROW]
213-
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_addr' - last_child_returndata_addr) = 0;
213+
#[RET_REV_RD_ADDR]
214214
NOT_LAST_EXEC * NESTED_RET_REV_ONLY * (last_child_returndata_addr' - rop[1]) = 0;
215+
#[NEXT_RD_ADDR_IS_ZERO]
215216
NOT_LAST_EXEC * (sel_enter_call + sel_error) * last_child_returndata_addr' = 0;
217+
#[RD_ADDR_IS_ZERO]
218+
enqueued_call_start * last_child_returndata_addr = 0;
219+
#[PROPAGATE_RD_ADDR]
220+
NOT_LAST_EXEC * DEFAULT_CTX_ROW * (last_child_returndata_addr' - last_child_returndata_addr) = 0;
216221

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

226249
// nested_exit_call = 1 ==> l2_gas_limit' = parent_l2_gas_limit
227250
// sel_enter_call = 1 ==> constraints come from call logic
@@ -395,7 +418,7 @@ namespace execution;
395418
};
396419

397420
pol commit nested_return;
398-
nested_return = nested_exit_call * sel_execute_return;
421+
nested_return = nested_exit_call * sel_execute_return * (1 - sel_error);
399422
#[CTX_STACK_RETURN]
400423
nested_return {
401424
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)