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;
1920using FF = AvmFlavorSettings::FF;
2021using C = Column;
2122using 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
2524TEST (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
162286TEST (ContextConstrainingTest, GasNextRow)
0 commit comments