diff --git a/barretenberg/cpp/pil/vm2/context.pil b/barretenberg/cpp/pil/vm2/context.pil index 23017f319ceb..2f60f0b6e8ab 100644 --- a/barretenberg/cpp/pil/vm2/context.pil +++ b/barretenberg/cpp/pil/vm2/context.pil @@ -37,7 +37,9 @@ namespace execution; pol commit contract_address; pol commit bytecode_id; pol commit transaction_fee; - // Constrained boolean by tx trace (for enqueued call) and #[NEXT_IS_STATIC] for nested + // Constrained boolean by tx trace for enqueued call, #[IS_STATIC_NEXT_ROW] during normal execution, + // IS_STATIC_IF_STATIC_CALL+IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT for nested calls, + // and CTX_STACK_CALL for returns or failures. pol commit is_static; pol commit parent_calldata_addr; @@ -193,7 +195,12 @@ namespace execution; // otherwise = 0 ==> is_static' = is_static #[IS_STATIC_NEXT_ROW] NOT_LAST_EXEC * DEFAULT_CTX_ROW * (is_static' - is_static) = 0; - NOT_LAST_EXEC * sel_enter_call * (is_static' - sel_execute_static_call) = 0; + // An external call from a non-static context only creates a nested static context if the opcode is STATICCALL. + #[IS_STATIC_IF_STATIC_CALL] + NOT_LAST_EXEC * sel_enter_call * (1 - is_static) * (is_static' - sel_execute_static_call) = 0; + // An external call from a static context always creates a nested static context. + #[IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT] + NOT_LAST_EXEC * sel_enter_call * is_static * (is_static' - 1) = 0; // nested_exit_call = 1 ==> constraints come from lookup // sel_enter_call = 1 ==> parent_calldata_addr' = rop[4] (resolved operand 5 from execution trace) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/context.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/context.test.cpp index 24a7e8325664..1e231215b7d9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/context.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/context.test.cpp @@ -61,10 +61,12 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn) { C::execution_context_id, 1 }, { C::execution_next_context_id, 2 }, { C::execution_bytecode_id, top_bytecode_id }, + { C::execution_is_static, 0 }, // Non-static context { C::execution_parent_l2_gas_limit, 2000 }, { C::execution_parent_da_gas_limit, 4000 }, { C::execution_parent_l2_gas_used, 500 }, { C::execution_parent_da_gas_used, 1500 }, + { C::execution_enqueued_call_start, 1 }, }, // CALL { @@ -72,10 +74,12 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn) { C::execution_pc, 1 }, { C::execution_next_pc, 2 }, { C::execution_sel_execute_call, 1 }, + { C::execution_sel_execute_static_call, 0 }, // Regular CALL, not STATICCALL { C::execution_sel_enter_call, 1 }, { C::execution_context_id, 1 }, { C::execution_next_context_id, 2 }, { C::execution_bytecode_id, top_bytecode_id }, // Same as previous row (propagated) + { C::execution_is_static, 0 }, // Still non-static { C::execution_rop_4_, /*cd offset=*/10 }, { C::execution_register_2_, /*contract address=*/0xdeadbeef }, { C::execution_register_3_, /*cd size=*/1 }, @@ -96,6 +100,7 @@ TEST(ContextConstrainingTest, ContextSwitchingCallReturn) { C::execution_has_parent_ctx, 1 }, { C::execution_contract_address, 0xdeadbeef }, { C::execution_bytecode_id, nested_bytecode_id }, // New bytecode_id on entering new context + { C::execution_is_static, 0 }, // Remains non-static after regular CALL { C::execution_parent_calldata_addr, 10 }, { C::execution_parent_calldata_size, 1 }, }, @@ -633,6 +638,137 @@ TEST(ContextConstrainingTest, BytecodeIdPropagation) "BYTECODE_ID_NEXT_ROW"); // Should fail constraint } +TEST(ContextConstrainingTest, IsStaticRegularCallFromNonStaticContext) +{ + // Non-static context making a regular CALL - should remain non-static + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 1 }, + { C::execution_next_context_id, 2 }, + { C::execution_is_static, 0 }, // Non-static context + { C::execution_sel_enter_call, 1 }, + { C::execution_sel_execute_call, 1 }, // Regular CALL + { C::execution_sel_execute_static_call, 0 }, + }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 2 }, + { C::execution_next_context_id, 3 }, + { C::execution_is_static, 0 }, // Should remain non-static + }, + }); + check_relation( + trace, context::SR_IS_STATIC_IF_STATIC_CALL, context::SR_IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT); + + // Negative test: change is_static + // regular call from non-static context cannot become static + trace.set(C::execution_is_static, 2, 1); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, context::SR_IS_STATIC_IF_STATIC_CALL), + "IS_STATIC_IF_STATIC_CALL"); + + // reset is_static + trace.set(C::execution_is_static, 2, 0); +} + +TEST(ContextConstrainingTest, IsStaticStaticCallFromNonStaticContext) +{ + // Non-static context making a STATICCALL - should become static + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 1 }, + { C::execution_next_context_id, 2 }, + { C::execution_is_static, 0 }, // Non-static context + { C::execution_sel_enter_call, 1 }, + { C::execution_sel_execute_call, 0 }, + { C::execution_sel_execute_static_call, 1 }, // STATICCALL + }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 2 }, + { C::execution_next_context_id, 3 }, + { C::execution_is_static, 1 }, // Should become static + }, + }); + check_relation( + trace, context::SR_IS_STATIC_IF_STATIC_CALL, context::SR_IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT); + + // Negative test: change is_static + // static call from non-static context MUST become static + trace.set(C::execution_is_static, 2, 0); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, context::SR_IS_STATIC_IF_STATIC_CALL), + "IS_STATIC_IF_STATIC_CALL"); + + // reset is_static + trace.set(C::execution_is_static, 2, 1); +} + +TEST(ContextConstrainingTest, IsStaticCallFromStaticContext) +{ + // Static context making any call - must remain static + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 1 }, + { C::execution_next_context_id, 2 }, + { C::execution_is_static, 1 }, // Static context + { C::execution_sel_enter_call, 1 }, + { C::execution_sel_execute_call, 1 }, // Regular CALL + { C::execution_sel_execute_static_call, 0 }, + }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 2 }, + { C::execution_next_context_id, 3 }, + { C::execution_is_static, 1 }, // Must remain static + }, + }); + check_relation( + trace, context::SR_IS_STATIC_IF_STATIC_CALL, context::SR_IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT); + + // Negative test: change is_static + // static call from static context MUST remain static + trace.set(C::execution_is_static, 2, 0); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, context::SR_IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT), + "IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT"); + + // reset is_static + trace.set(C::execution_is_static, 2, 1); +} + +TEST(ContextConstrainingTest, IsStaticPropagationWithoutCalls) +{ + // is_static propagation without calls + TestTraceContainer trace({ + { { C::precomputed_first_row, 1 } }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 1 }, + { C::execution_next_context_id, 1 }, + { C::execution_is_static, 1 }, // Static context + }, + { + { C::execution_sel, 1 }, + { C::execution_context_id, 1 }, + { C::execution_next_context_id, 1 }, + { C::execution_is_static, 1 }, // Should propagate + }, + }); + check_relation(trace, context::SR_IS_STATIC_NEXT_ROW); + + // Negative test: change is_static + // staticness must propagate without calls + trace.set(C::execution_is_static, 2, 0); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, context::SR_IS_STATIC_NEXT_ROW), "IS_STATIC_NEXT_ROW"); + + // reset is_static + trace.set(C::execution_is_static, 2, 1); +} + TEST(ContextConstrainingTest, ContextIdPropagation) { TestTraceContainer trace({ diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context.hpp index d09f359e4cff..2c8518aaedf8 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context.hpp @@ -14,10 +14,10 @@ template class contextImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { - 2, 3, 3, 3, 4, 3, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, - 5, 5, 6, 5, 3, 5, 6, 5, 3, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5 + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 2, 3, 3, 3, 4, 3, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 3, 5, 6, 6, 5, 5, + 5, 5, 6, 5, 3, 5, 6, 5, 3, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5 }; template inline static bool skip(const AllEntities& in) @@ -67,95 +67,99 @@ template class context : public Relation> { return "TRANSACTION_FEE_NEXT_ROW"; case 21: return "IS_STATIC_NEXT_ROW"; + case 22: + return "IS_STATIC_IF_STATIC_CALL"; case 23: + return "IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT"; + case 24: return "CD_OFFSET_NEXT_ROW"; - case 25: + case 26: return "CD_SIZE_NEXT_ROW"; - case 27: - return "RET_REV_RD_ADDR"; case 28: - return "NEXT_RD_ADDR_IS_ZERO"; + return "RET_REV_RD_ADDR"; case 29: - return "RD_ADDR_IS_ZERO"; + return "NEXT_RD_ADDR_IS_ZERO"; case 30: - return "PROPAGATE_RD_ADDR"; + return "RD_ADDR_IS_ZERO"; case 31: - return "RET_REV_RD_SIZE"; + return "PROPAGATE_RD_ADDR"; case 32: - return "NEXT_RD_SIZE_IS_ZERO"; + return "RET_REV_RD_SIZE"; case 33: - return "RD_SIZE_IS_ZERO"; + return "NEXT_RD_SIZE_IS_ZERO"; case 34: - return "PROPAGATE_RD_SIZE"; + return "RD_SIZE_IS_ZERO"; case 35: - return "EXIT_CALL_LAST_CHILD_ID"; + return "PROPAGATE_RD_SIZE"; case 36: - return "ENTER_CALL_LAST_CHILD_ID"; + return "EXIT_CALL_LAST_CHILD_ID"; case 37: - return "LAST_CHILD_ID_IS_ZERO"; + return "ENTER_CALL_LAST_CHILD_ID"; case 38: - return "PROPAGATE_LAST_CHILD_ID"; + return "LAST_CHILD_ID_IS_ZERO"; case 39: - return "L2_GAS_LIMIT_NEXT_ROW"; + return "PROPAGATE_LAST_CHILD_ID"; case 40: - return "L2_GAS_LIMIT_RESTORE_ON_EXIT"; + return "L2_GAS_LIMIT_NEXT_ROW"; case 41: - return "DA_GAS_LIMIT_NEXT_ROW"; + return "L2_GAS_LIMIT_RESTORE_ON_EXIT"; case 42: - return "DA_GAS_LIMIT_RESTORE_ON_EXIT"; + return "DA_GAS_LIMIT_NEXT_ROW"; case 43: - return "PARENT_L2_GAS_LIMIT_NEXT_ROW"; + return "DA_GAS_LIMIT_RESTORE_ON_EXIT"; case 44: - return "PARENT_L2_GAS_LIMIT_STORE_ON_ENTER"; + return "PARENT_L2_GAS_LIMIT_NEXT_ROW"; case 45: - return "PARENT_DA_GAS_LIMIT_NEXT_ROW"; + return "PARENT_L2_GAS_LIMIT_STORE_ON_ENTER"; case 46: - return "PARENT_DA_GAS_LIMIT_STORE_ON_ENTER"; + return "PARENT_DA_GAS_LIMIT_NEXT_ROW"; case 47: - return "PARENT_L2_GAS_USED_NEXT_ROW"; + return "PARENT_DA_GAS_LIMIT_STORE_ON_ENTER"; case 48: - return "PARENT_L2_GAS_USED_STORE_ON_ENTER"; + return "PARENT_L2_GAS_USED_NEXT_ROW"; case 49: - return "PARENT_DA_GAS_USED_NEXT_ROW"; + return "PARENT_L2_GAS_USED_STORE_ON_ENTER"; case 50: + return "PARENT_DA_GAS_USED_NEXT_ROW"; + case 51: return "PARENT_DA_GAS_USED_STORE_ON_ENTER"; - case 56: - return "L2_GAS_USED_CONTINUITY"; case 57: - return "L2_GAS_USED_ZERO_AFTER_CALL"; + return "L2_GAS_USED_CONTINUITY"; case 58: - return "L2_GAS_USED_INGEST_AFTER_EXIT"; + return "L2_GAS_USED_ZERO_AFTER_CALL"; case 59: - return "DA_GAS_USED_CONTINUITY"; + return "L2_GAS_USED_INGEST_AFTER_EXIT"; case 60: - return "DA_GAS_USED_ZERO_AFTER_CALL"; + return "DA_GAS_USED_CONTINUITY"; case 61: - return "DA_GAS_USED_INGEST_AFTER_EXIT"; + return "DA_GAS_USED_ZERO_AFTER_CALL"; case 62: - return "NOTE_HASH_TREE_ROOT_CONTINUITY"; + return "DA_GAS_USED_INGEST_AFTER_EXIT"; case 63: - return "NOTE_HASH_TREE_SIZE_CONTINUITY"; + return "NOTE_HASH_TREE_ROOT_CONTINUITY"; case 64: - return "NUM_NOTE_HASHES_EMITTED_CONTINUITY"; + return "NOTE_HASH_TREE_SIZE_CONTINUITY"; case 65: - return "NULLIFIER_TREE_ROOT_CONTINUITY"; + return "NUM_NOTE_HASHES_EMITTED_CONTINUITY"; case 66: - return "NULLIFIER_TREE_SIZE_CONTINUITY"; + return "NULLIFIER_TREE_ROOT_CONTINUITY"; case 67: - return "NUM_NULLIFIERS_EMITTED_CONTINUITY"; + return "NULLIFIER_TREE_SIZE_CONTINUITY"; case 68: - return "PUBLIC_DATA_TREE_ROOT_CONTINUITY"; + return "NUM_NULLIFIERS_EMITTED_CONTINUITY"; case 69: - return "PUBLIC_DATA_TREE_SIZE_CONTINUITY"; + return "PUBLIC_DATA_TREE_ROOT_CONTINUITY"; case 70: - return "WRITTEN_PUBLIC_DATA_SLOTS_TREE_ROOT_CONTINUITY"; + return "PUBLIC_DATA_TREE_SIZE_CONTINUITY"; case 71: - return "WRITTEN_PUBLIC_DATA_SLOTS_TREE_SIZE_CONTINUITY"; + return "WRITTEN_PUBLIC_DATA_SLOTS_TREE_ROOT_CONTINUITY"; case 72: - return "L1_L2_TREE_ROOT_CONTINUITY"; + return "WRITTEN_PUBLIC_DATA_SLOTS_TREE_SIZE_CONTINUITY"; case 73: - return "NUM_UNENCRYPTED_LOGS_CONTINUITY"; + return "L1_L2_TREE_ROOT_CONTINUITY"; case 74: + return "NUM_UNENCRYPTED_LOGS_CONTINUITY"; + case 75: return "NUM_L2_TO_L1_MESSAGES_CONTINUITY"; } return std::to_string(index); @@ -175,51 +179,53 @@ template class context : public Relation> { static constexpr size_t SR_BYTECODE_ID_NEXT_ROW = 19; static constexpr size_t SR_TRANSACTION_FEE_NEXT_ROW = 20; static constexpr size_t SR_IS_STATIC_NEXT_ROW = 21; - static constexpr size_t SR_CD_OFFSET_NEXT_ROW = 23; - static constexpr size_t SR_CD_SIZE_NEXT_ROW = 25; - static constexpr size_t SR_RET_REV_RD_ADDR = 27; - static constexpr size_t SR_NEXT_RD_ADDR_IS_ZERO = 28; - static constexpr size_t SR_RD_ADDR_IS_ZERO = 29; - static constexpr size_t SR_PROPAGATE_RD_ADDR = 30; - static constexpr size_t SR_RET_REV_RD_SIZE = 31; - static constexpr size_t SR_NEXT_RD_SIZE_IS_ZERO = 32; - static constexpr size_t SR_RD_SIZE_IS_ZERO = 33; - static constexpr size_t SR_PROPAGATE_RD_SIZE = 34; - static constexpr size_t SR_EXIT_CALL_LAST_CHILD_ID = 35; - static constexpr size_t SR_ENTER_CALL_LAST_CHILD_ID = 36; - static constexpr size_t SR_LAST_CHILD_ID_IS_ZERO = 37; - static constexpr size_t SR_PROPAGATE_LAST_CHILD_ID = 38; - static constexpr size_t SR_L2_GAS_LIMIT_NEXT_ROW = 39; - static constexpr size_t SR_L2_GAS_LIMIT_RESTORE_ON_EXIT = 40; - static constexpr size_t SR_DA_GAS_LIMIT_NEXT_ROW = 41; - static constexpr size_t SR_DA_GAS_LIMIT_RESTORE_ON_EXIT = 42; - static constexpr size_t SR_PARENT_L2_GAS_LIMIT_NEXT_ROW = 43; - static constexpr size_t SR_PARENT_L2_GAS_LIMIT_STORE_ON_ENTER = 44; - static constexpr size_t SR_PARENT_DA_GAS_LIMIT_NEXT_ROW = 45; - static constexpr size_t SR_PARENT_DA_GAS_LIMIT_STORE_ON_ENTER = 46; - static constexpr size_t SR_PARENT_L2_GAS_USED_NEXT_ROW = 47; - static constexpr size_t SR_PARENT_L2_GAS_USED_STORE_ON_ENTER = 48; - static constexpr size_t SR_PARENT_DA_GAS_USED_NEXT_ROW = 49; - static constexpr size_t SR_PARENT_DA_GAS_USED_STORE_ON_ENTER = 50; - static constexpr size_t SR_L2_GAS_USED_CONTINUITY = 56; - static constexpr size_t SR_L2_GAS_USED_ZERO_AFTER_CALL = 57; - static constexpr size_t SR_L2_GAS_USED_INGEST_AFTER_EXIT = 58; - static constexpr size_t SR_DA_GAS_USED_CONTINUITY = 59; - static constexpr size_t SR_DA_GAS_USED_ZERO_AFTER_CALL = 60; - static constexpr size_t SR_DA_GAS_USED_INGEST_AFTER_EXIT = 61; - static constexpr size_t SR_NOTE_HASH_TREE_ROOT_CONTINUITY = 62; - static constexpr size_t SR_NOTE_HASH_TREE_SIZE_CONTINUITY = 63; - static constexpr size_t SR_NUM_NOTE_HASHES_EMITTED_CONTINUITY = 64; - static constexpr size_t SR_NULLIFIER_TREE_ROOT_CONTINUITY = 65; - static constexpr size_t SR_NULLIFIER_TREE_SIZE_CONTINUITY = 66; - static constexpr size_t SR_NUM_NULLIFIERS_EMITTED_CONTINUITY = 67; - static constexpr size_t SR_PUBLIC_DATA_TREE_ROOT_CONTINUITY = 68; - static constexpr size_t SR_PUBLIC_DATA_TREE_SIZE_CONTINUITY = 69; - static constexpr size_t SR_WRITTEN_PUBLIC_DATA_SLOTS_TREE_ROOT_CONTINUITY = 70; - static constexpr size_t SR_WRITTEN_PUBLIC_DATA_SLOTS_TREE_SIZE_CONTINUITY = 71; - static constexpr size_t SR_L1_L2_TREE_ROOT_CONTINUITY = 72; - static constexpr size_t SR_NUM_UNENCRYPTED_LOGS_CONTINUITY = 73; - static constexpr size_t SR_NUM_L2_TO_L1_MESSAGES_CONTINUITY = 74; + static constexpr size_t SR_IS_STATIC_IF_STATIC_CALL = 22; + static constexpr size_t SR_IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT = 23; + static constexpr size_t SR_CD_OFFSET_NEXT_ROW = 24; + static constexpr size_t SR_CD_SIZE_NEXT_ROW = 26; + static constexpr size_t SR_RET_REV_RD_ADDR = 28; + static constexpr size_t SR_NEXT_RD_ADDR_IS_ZERO = 29; + static constexpr size_t SR_RD_ADDR_IS_ZERO = 30; + static constexpr size_t SR_PROPAGATE_RD_ADDR = 31; + static constexpr size_t SR_RET_REV_RD_SIZE = 32; + static constexpr size_t SR_NEXT_RD_SIZE_IS_ZERO = 33; + static constexpr size_t SR_RD_SIZE_IS_ZERO = 34; + static constexpr size_t SR_PROPAGATE_RD_SIZE = 35; + static constexpr size_t SR_EXIT_CALL_LAST_CHILD_ID = 36; + static constexpr size_t SR_ENTER_CALL_LAST_CHILD_ID = 37; + static constexpr size_t SR_LAST_CHILD_ID_IS_ZERO = 38; + static constexpr size_t SR_PROPAGATE_LAST_CHILD_ID = 39; + static constexpr size_t SR_L2_GAS_LIMIT_NEXT_ROW = 40; + static constexpr size_t SR_L2_GAS_LIMIT_RESTORE_ON_EXIT = 41; + static constexpr size_t SR_DA_GAS_LIMIT_NEXT_ROW = 42; + static constexpr size_t SR_DA_GAS_LIMIT_RESTORE_ON_EXIT = 43; + static constexpr size_t SR_PARENT_L2_GAS_LIMIT_NEXT_ROW = 44; + static constexpr size_t SR_PARENT_L2_GAS_LIMIT_STORE_ON_ENTER = 45; + static constexpr size_t SR_PARENT_DA_GAS_LIMIT_NEXT_ROW = 46; + static constexpr size_t SR_PARENT_DA_GAS_LIMIT_STORE_ON_ENTER = 47; + static constexpr size_t SR_PARENT_L2_GAS_USED_NEXT_ROW = 48; + static constexpr size_t SR_PARENT_L2_GAS_USED_STORE_ON_ENTER = 49; + static constexpr size_t SR_PARENT_DA_GAS_USED_NEXT_ROW = 50; + static constexpr size_t SR_PARENT_DA_GAS_USED_STORE_ON_ENTER = 51; + static constexpr size_t SR_L2_GAS_USED_CONTINUITY = 57; + static constexpr size_t SR_L2_GAS_USED_ZERO_AFTER_CALL = 58; + static constexpr size_t SR_L2_GAS_USED_INGEST_AFTER_EXIT = 59; + static constexpr size_t SR_DA_GAS_USED_CONTINUITY = 60; + static constexpr size_t SR_DA_GAS_USED_ZERO_AFTER_CALL = 61; + static constexpr size_t SR_DA_GAS_USED_INGEST_AFTER_EXIT = 62; + static constexpr size_t SR_NOTE_HASH_TREE_ROOT_CONTINUITY = 63; + static constexpr size_t SR_NOTE_HASH_TREE_SIZE_CONTINUITY = 64; + static constexpr size_t SR_NUM_NOTE_HASHES_EMITTED_CONTINUITY = 65; + static constexpr size_t SR_NULLIFIER_TREE_ROOT_CONTINUITY = 66; + static constexpr size_t SR_NULLIFIER_TREE_SIZE_CONTINUITY = 67; + static constexpr size_t SR_NUM_NULLIFIERS_EMITTED_CONTINUITY = 68; + static constexpr size_t SR_PUBLIC_DATA_TREE_ROOT_CONTINUITY = 69; + static constexpr size_t SR_PUBLIC_DATA_TREE_SIZE_CONTINUITY = 70; + static constexpr size_t SR_WRITTEN_PUBLIC_DATA_SLOTS_TREE_ROOT_CONTINUITY = 71; + static constexpr size_t SR_WRITTEN_PUBLIC_DATA_SLOTS_TREE_SIZE_CONTINUITY = 72; + static constexpr size_t SR_L1_L2_TREE_ROOT_CONTINUITY = 73; + static constexpr size_t SR_NUM_UNENCRYPTED_LOGS_CONTINUITY = 74; + static constexpr size_t SR_NUM_L2_TO_L1_MESSAGES_CONTINUITY = 75; }; } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context_impl.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context_impl.hpp index 512139ed977b..d19dfc2345c9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/context_impl.hpp @@ -193,385 +193,393 @@ void contextImpl::accumulate(ContainerOverSubrelations& evals, tmp *= scaling_factor; std::get<21>(evals) += typename Accumulator::View(tmp); } - { + { // IS_STATIC_IF_STATIC_CALL using Accumulator = typename std::tuple_element_t<22, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * + (FF(1) - in.get(C::execution_is_static)) * (in.get(C::execution_is_static_shift) - in.get(C::execution_sel_execute_static_call)); tmp *= scaling_factor; std::get<22>(evals) += typename Accumulator::View(tmp); } - { // CD_OFFSET_NEXT_ROW + { // IS_STATIC_IF_CALL_FROM_STATIC_CONTEXT using Accumulator = typename std::tuple_element_t<23, ContainerOverSubrelations>; + auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * in.get(C::execution_is_static) * + (in.get(C::execution_is_static_shift) - FF(1)); + tmp *= scaling_factor; + std::get<23>(evals) += typename Accumulator::View(tmp); + } + { // CD_OFFSET_NEXT_ROW + using Accumulator = typename std::tuple_element_t<24, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_calldata_addr_shift) - in.get(C::execution_parent_calldata_addr)); tmp *= scaling_factor; - std::get<23>(evals) += typename Accumulator::View(tmp); + std::get<24>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<24, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<25, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_calldata_addr_shift) - in.get(C::execution_rop_4_)); tmp *= scaling_factor; - std::get<24>(evals) += typename Accumulator::View(tmp); + std::get<25>(evals) += typename Accumulator::View(tmp); } { // CD_SIZE_NEXT_ROW - using Accumulator = typename std::tuple_element_t<25, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<26, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_calldata_size_shift) - in.get(C::execution_parent_calldata_size)); tmp *= scaling_factor; - std::get<25>(evals) += typename Accumulator::View(tmp); + std::get<26>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<26, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_calldata_size_shift) - in.get(C::execution_register_3_)); tmp *= scaling_factor; - std::get<26>(evals) += typename Accumulator::View(tmp); + std::get<27>(evals) += typename Accumulator::View(tmp); } { // RET_REV_RD_ADDR - using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_NESTED_RET_REV_ONLY * (in.get(C::execution_last_child_returndata_addr_shift) - in.get(C::execution_rop_1_)); tmp *= scaling_factor; - std::get<27>(evals) += typename Accumulator::View(tmp); + std::get<28>(evals) += typename Accumulator::View(tmp); } { // NEXT_RD_ADDR_IS_ZERO - using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * (in.get(C::execution_sel_enter_call) + in.get(C::execution_sel_error)) * in.get(C::execution_last_child_returndata_addr_shift); tmp *= scaling_factor; - std::get<28>(evals) += typename Accumulator::View(tmp); + std::get<29>(evals) += typename Accumulator::View(tmp); } { // RD_ADDR_IS_ZERO - using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; auto tmp = in.get(C::execution_enqueued_call_start) * in.get(C::execution_last_child_returndata_addr); tmp *= scaling_factor; - std::get<29>(evals) += typename Accumulator::View(tmp); + std::get<30>(evals) += typename Accumulator::View(tmp); } { // PROPAGATE_RD_ADDR - using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_last_child_returndata_addr_shift) - in.get(C::execution_last_child_returndata_addr)); tmp *= scaling_factor; - std::get<30>(evals) += typename Accumulator::View(tmp); + std::get<31>(evals) += typename Accumulator::View(tmp); } { // RET_REV_RD_SIZE - using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_NESTED_RET_REV_ONLY * (in.get(C::execution_last_child_returndata_size_shift) - in.get(C::execution_register_0_)); tmp *= scaling_factor; - std::get<31>(evals) += typename Accumulator::View(tmp); + std::get<32>(evals) += typename Accumulator::View(tmp); } { // NEXT_RD_SIZE_IS_ZERO - using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * (in.get(C::execution_sel_enter_call) + in.get(C::execution_sel_error)) * in.get(C::execution_last_child_returndata_size_shift); tmp *= scaling_factor; - std::get<32>(evals) += typename Accumulator::View(tmp); + std::get<33>(evals) += typename Accumulator::View(tmp); } { // RD_SIZE_IS_ZERO - using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; auto tmp = in.get(C::execution_enqueued_call_start) * in.get(C::execution_last_child_returndata_addr); tmp *= scaling_factor; - std::get<33>(evals) += typename Accumulator::View(tmp); + std::get<34>(evals) += typename Accumulator::View(tmp); } { // PROPAGATE_RD_SIZE - using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_last_child_returndata_size_shift) - in.get(C::execution_last_child_returndata_size)); tmp *= scaling_factor; - std::get<34>(evals) += typename Accumulator::View(tmp); + std::get<35>(evals) += typename Accumulator::View(tmp); } { // EXIT_CALL_LAST_CHILD_ID - using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_nested_exit_call) * (in.get(C::execution_last_child_id_shift) - in.get(C::execution_context_id)); tmp *= scaling_factor; - std::get<35>(evals) += typename Accumulator::View(tmp); + std::get<36>(evals) += typename Accumulator::View(tmp); } { // ENTER_CALL_LAST_CHILD_ID - using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * in.get(C::execution_last_child_id_shift); tmp *= scaling_factor; - std::get<36>(evals) += typename Accumulator::View(tmp); + std::get<37>(evals) += typename Accumulator::View(tmp); } { // LAST_CHILD_ID_IS_ZERO - using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; auto tmp = in.get(C::execution_enqueued_call_start) * in.get(C::execution_last_child_id); tmp *= scaling_factor; - std::get<37>(evals) += typename Accumulator::View(tmp); + std::get<38>(evals) += typename Accumulator::View(tmp); } { // PROPAGATE_LAST_CHILD_ID - using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_last_child_id_shift) - in.get(C::execution_last_child_id)); tmp *= scaling_factor; - std::get<38>(evals) += typename Accumulator::View(tmp); + std::get<39>(evals) += typename Accumulator::View(tmp); } { // L2_GAS_LIMIT_NEXT_ROW - using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_l2_gas_limit_shift) - in.get(C::execution_l2_gas_limit)); tmp *= scaling_factor; - std::get<39>(evals) += typename Accumulator::View(tmp); + std::get<40>(evals) += typename Accumulator::View(tmp); } { // L2_GAS_LIMIT_RESTORE_ON_EXIT - using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_nested_exit_call) * (in.get(C::execution_l2_gas_limit_shift) - in.get(C::execution_parent_l2_gas_limit)); tmp *= scaling_factor; - std::get<40>(evals) += typename Accumulator::View(tmp); + std::get<41>(evals) += typename Accumulator::View(tmp); } { // DA_GAS_LIMIT_NEXT_ROW - using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_da_gas_limit_shift) - in.get(C::execution_da_gas_limit)); tmp *= scaling_factor; - std::get<41>(evals) += typename Accumulator::View(tmp); + std::get<42>(evals) += typename Accumulator::View(tmp); } { // DA_GAS_LIMIT_RESTORE_ON_EXIT - using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_nested_exit_call) * (in.get(C::execution_da_gas_limit_shift) - in.get(C::execution_parent_da_gas_limit)); tmp *= scaling_factor; - std::get<42>(evals) += typename Accumulator::View(tmp); + std::get<43>(evals) += typename Accumulator::View(tmp); } { // PARENT_L2_GAS_LIMIT_NEXT_ROW - using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_l2_gas_limit_shift) - in.get(C::execution_parent_l2_gas_limit)); tmp *= scaling_factor; - std::get<43>(evals) += typename Accumulator::View(tmp); + std::get<44>(evals) += typename Accumulator::View(tmp); } { // PARENT_L2_GAS_LIMIT_STORE_ON_ENTER - using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_l2_gas_limit_shift) - in.get(C::execution_l2_gas_limit)); tmp *= scaling_factor; - std::get<44>(evals) += typename Accumulator::View(tmp); + std::get<45>(evals) += typename Accumulator::View(tmp); } { // PARENT_DA_GAS_LIMIT_NEXT_ROW - using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_da_gas_limit_shift) - in.get(C::execution_parent_da_gas_limit)); tmp *= scaling_factor; - std::get<45>(evals) += typename Accumulator::View(tmp); + std::get<46>(evals) += typename Accumulator::View(tmp); } { // PARENT_DA_GAS_LIMIT_STORE_ON_ENTER - using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_da_gas_limit_shift) - in.get(C::execution_da_gas_limit)); tmp *= scaling_factor; - std::get<46>(evals) += typename Accumulator::View(tmp); + std::get<47>(evals) += typename Accumulator::View(tmp); } { // PARENT_L2_GAS_USED_NEXT_ROW - using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_l2_gas_used_shift) - in.get(C::execution_parent_l2_gas_used)); tmp *= scaling_factor; - std::get<47>(evals) += typename Accumulator::View(tmp); + std::get<48>(evals) += typename Accumulator::View(tmp); } { // PARENT_L2_GAS_USED_STORE_ON_ENTER - using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_l2_gas_used_shift) - in.get(C::execution_l2_gas_used)); tmp *= scaling_factor; - std::get<48>(evals) += typename Accumulator::View(tmp); + std::get<49>(evals) += typename Accumulator::View(tmp); } { // PARENT_DA_GAS_USED_NEXT_ROW - using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_parent_da_gas_used_shift) - in.get(C::execution_parent_da_gas_used)); tmp *= scaling_factor; - std::get<49>(evals) += typename Accumulator::View(tmp); + std::get<50>(evals) += typename Accumulator::View(tmp); } { // PARENT_DA_GAS_USED_STORE_ON_ENTER - using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<51, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * (in.get(C::execution_parent_da_gas_used_shift) - in.get(C::execution_da_gas_used)); tmp *= scaling_factor; - std::get<50>(evals) += typename Accumulator::View(tmp); + std::get<51>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<51, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<52, ContainerOverSubrelations>; auto tmp = in.get(C::execution_rollback_context) * (FF(1) - in.get(C::execution_rollback_context)); tmp *= scaling_factor; - std::get<51>(evals) += typename Accumulator::View(tmp); + std::get<52>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<52, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<53, ContainerOverSubrelations>; auto tmp = (in.get(C::execution_rollback_context) - in.get(C::execution_nested_exit_call) * (FF(1) - in.get(C::execution_sel_execute_return))); tmp *= scaling_factor; - std::get<52>(evals) += typename Accumulator::View(tmp); + std::get<53>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<53, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<54, ContainerOverSubrelations>; auto tmp = (in.get(C::execution_nested_return) - in.get(C::execution_nested_exit_call) * in.get(C::execution_sel_execute_return) * (FF(1) - in.get(C::execution_sel_error))); tmp *= scaling_factor; - std::get<53>(evals) += typename Accumulator::View(tmp); + std::get<54>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<54, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<55, ContainerOverSubrelations>; auto tmp = (((in.get(C::execution_l2_gas_limit) - execution_PREV_GAS_PLUS_USAGE_L2) * execution_SEL_CONSUMED_ALL_GAS + execution_PREV_GAS_PLUS_USAGE_L2) - in.get(C::execution_l2_gas_used)); tmp *= scaling_factor; - std::get<54>(evals) += typename Accumulator::View(tmp); + std::get<55>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<55, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<56, ContainerOverSubrelations>; auto tmp = (((in.get(C::execution_da_gas_limit) - execution_PREV_GAS_PLUS_USAGE_DA) * execution_SEL_CONSUMED_ALL_GAS + execution_PREV_GAS_PLUS_USAGE_DA) - in.get(C::execution_da_gas_used)); tmp *= scaling_factor; - std::get<55>(evals) += typename Accumulator::View(tmp); + std::get<56>(evals) += typename Accumulator::View(tmp); } { // L2_GAS_USED_CONTINUITY - using Accumulator = typename std::tuple_element_t<56, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<57, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_l2_gas_used) - in.get(C::execution_prev_l2_gas_used_shift)); tmp *= scaling_factor; - std::get<56>(evals) += typename Accumulator::View(tmp); + std::get<57>(evals) += typename Accumulator::View(tmp); } { // L2_GAS_USED_ZERO_AFTER_CALL - using Accumulator = typename std::tuple_element_t<57, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<58, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * in.get(C::execution_prev_l2_gas_used_shift); tmp *= scaling_factor; - std::get<57>(evals) += typename Accumulator::View(tmp); + std::get<58>(evals) += typename Accumulator::View(tmp); } { // L2_GAS_USED_INGEST_AFTER_EXIT - using Accumulator = typename std::tuple_element_t<58, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<59, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_nested_exit_call) * ((in.get(C::execution_parent_l2_gas_used) + in.get(C::execution_l2_gas_used)) - in.get(C::execution_prev_l2_gas_used_shift)); tmp *= scaling_factor; - std::get<58>(evals) += typename Accumulator::View(tmp); + std::get<59>(evals) += typename Accumulator::View(tmp); } { // DA_GAS_USED_CONTINUITY - using Accumulator = typename std::tuple_element_t<59, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<60, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_CTX_ROW * (in.get(C::execution_da_gas_used) - in.get(C::execution_prev_da_gas_used_shift)); tmp *= scaling_factor; - std::get<59>(evals) += typename Accumulator::View(tmp); + std::get<60>(evals) += typename Accumulator::View(tmp); } { // DA_GAS_USED_ZERO_AFTER_CALL - using Accumulator = typename std::tuple_element_t<60, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<61, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_sel_enter_call) * in.get(C::execution_prev_da_gas_used_shift); tmp *= scaling_factor; - std::get<60>(evals) += typename Accumulator::View(tmp); + std::get<61>(evals) += typename Accumulator::View(tmp); } { // DA_GAS_USED_INGEST_AFTER_EXIT - using Accumulator = typename std::tuple_element_t<61, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<62, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * in.get(C::execution_nested_exit_call) * ((in.get(C::execution_parent_da_gas_used) + in.get(C::execution_da_gas_used)) - in.get(C::execution_prev_da_gas_used_shift)); tmp *= scaling_factor; - std::get<61>(evals) += typename Accumulator::View(tmp); + std::get<62>(evals) += typename Accumulator::View(tmp); } { // NOTE_HASH_TREE_ROOT_CONTINUITY - using Accumulator = typename std::tuple_element_t<62, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<63, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_note_hash_tree_root) - in.get(C::execution_prev_note_hash_tree_root_shift)); tmp *= scaling_factor; - std::get<62>(evals) += typename Accumulator::View(tmp); + std::get<63>(evals) += typename Accumulator::View(tmp); } { // NOTE_HASH_TREE_SIZE_CONTINUITY - using Accumulator = typename std::tuple_element_t<63, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<64, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_note_hash_tree_size) - in.get(C::execution_prev_note_hash_tree_size_shift)); tmp *= scaling_factor; - std::get<63>(evals) += typename Accumulator::View(tmp); + std::get<64>(evals) += typename Accumulator::View(tmp); } { // NUM_NOTE_HASHES_EMITTED_CONTINUITY - using Accumulator = typename std::tuple_element_t<64, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<65, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_num_note_hashes_emitted) - in.get(C::execution_prev_num_note_hashes_emitted_shift)); tmp *= scaling_factor; - std::get<64>(evals) += typename Accumulator::View(tmp); + std::get<65>(evals) += typename Accumulator::View(tmp); } { // NULLIFIER_TREE_ROOT_CONTINUITY - using Accumulator = typename std::tuple_element_t<65, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<66, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_nullifier_tree_root) - in.get(C::execution_prev_nullifier_tree_root_shift)); tmp *= scaling_factor; - std::get<65>(evals) += typename Accumulator::View(tmp); + std::get<66>(evals) += typename Accumulator::View(tmp); } { // NULLIFIER_TREE_SIZE_CONTINUITY - using Accumulator = typename std::tuple_element_t<66, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<67, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_nullifier_tree_size) - in.get(C::execution_prev_nullifier_tree_size_shift)); tmp *= scaling_factor; - std::get<66>(evals) += typename Accumulator::View(tmp); + std::get<67>(evals) += typename Accumulator::View(tmp); } { // NUM_NULLIFIERS_EMITTED_CONTINUITY - using Accumulator = typename std::tuple_element_t<67, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<68, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_num_nullifiers_emitted) - in.get(C::execution_prev_num_nullifiers_emitted_shift)); tmp *= scaling_factor; - std::get<67>(evals) += typename Accumulator::View(tmp); + std::get<68>(evals) += typename Accumulator::View(tmp); } { // PUBLIC_DATA_TREE_ROOT_CONTINUITY - using Accumulator = typename std::tuple_element_t<68, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<69, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_public_data_tree_root) - in.get(C::execution_prev_public_data_tree_root_shift)); tmp *= scaling_factor; - std::get<68>(evals) += typename Accumulator::View(tmp); + std::get<69>(evals) += typename Accumulator::View(tmp); } { // PUBLIC_DATA_TREE_SIZE_CONTINUITY - using Accumulator = typename std::tuple_element_t<69, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<70, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_public_data_tree_size) - in.get(C::execution_prev_public_data_tree_size_shift)); tmp *= scaling_factor; - std::get<69>(evals) += typename Accumulator::View(tmp); + std::get<70>(evals) += typename Accumulator::View(tmp); } { // WRITTEN_PUBLIC_DATA_SLOTS_TREE_ROOT_CONTINUITY - using Accumulator = typename std::tuple_element_t<70, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<71, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_written_public_data_slots_tree_root) - in.get(C::execution_prev_written_public_data_slots_tree_root_shift)); tmp *= scaling_factor; - std::get<70>(evals) += typename Accumulator::View(tmp); + std::get<71>(evals) += typename Accumulator::View(tmp); } { // WRITTEN_PUBLIC_DATA_SLOTS_TREE_SIZE_CONTINUITY - using Accumulator = typename std::tuple_element_t<71, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<72, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_written_public_data_slots_tree_size) - in.get(C::execution_prev_written_public_data_slots_tree_size_shift)); tmp *= scaling_factor; - std::get<71>(evals) += typename Accumulator::View(tmp); + std::get<72>(evals) += typename Accumulator::View(tmp); } { // L1_L2_TREE_ROOT_CONTINUITY - using Accumulator = typename std::tuple_element_t<72, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<73, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * (in.get(C::execution_l1_l2_tree_root) - in.get(C::execution_l1_l2_tree_root_shift)); tmp *= scaling_factor; - std::get<72>(evals) += typename Accumulator::View(tmp); + std::get<73>(evals) += typename Accumulator::View(tmp); } { // NUM_UNENCRYPTED_LOGS_CONTINUITY - using Accumulator = typename std::tuple_element_t<73, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<74, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_num_unencrypted_logs) - in.get(C::execution_prev_num_unencrypted_logs_shift)); tmp *= scaling_factor; - std::get<73>(evals) += typename Accumulator::View(tmp); + std::get<74>(evals) += typename Accumulator::View(tmp); } { // NUM_L2_TO_L1_MESSAGES_CONTINUITY - using Accumulator = typename std::tuple_element_t<74, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<75, ContainerOverSubrelations>; auto tmp = execution_NOT_LAST_EXEC * execution_DEFAULT_OR_NESTED_RETURN * (in.get(C::execution_num_l2_to_l1_messages) - in.get(C::execution_prev_num_l2_to_l1_messages_shift)); tmp *= scaling_factor; - std::get<74>(evals) += typename Accumulator::View(tmp); + std::get<75>(evals) += typename Accumulator::View(tmp); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp index 0f93b4ca0512..01492ef464b9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.cpp @@ -372,7 +372,7 @@ void Execution::call(ContextInterface& context, /*parent_context=*/context, /*cd_offset_address=*/cd_offset, /*cd_size=*/cd_size.as(), - /*is_static=*/false, + /*is_static=*/context.get_is_static(), /*gas_limit=*/gas_limit, /*side_effect_states=*/context.get_side_effect_states(), /*phase=*/context.get_phase()); diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.test.cpp index 4fbd140abdfa..d4b372f341f7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/execution.test.cpp @@ -273,7 +273,7 @@ TEST_F(ExecutionSimulationTest, Call) EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager)); EXPECT_CALL(bytecode_manager, try_get_bytecode_id); EXPECT_CALL(context, get_next_pc); - EXPECT_CALL(context, get_is_static); + EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(false)); EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address)); EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero)); EXPECT_CALL(context, get_parent_cd_addr); @@ -320,6 +320,127 @@ TEST_F(ExecutionSimulationTest, Call) /*cd_offset=*/5); } +// Test staticness propagation for external calls (CALL vs STATICCALL) +TEST_F(ExecutionSimulationTest, ExternalCallStaticnessPropagation) +{ + // Common test data setup + FF zero = 0; + AztecAddress parent_address = 0xdeadbeef; + AztecAddress nested_address = 0xc0ffee; + MemoryValue nested_address_value = MemoryValue::from(nested_address); + MemoryValue l2_gas_allocated = MemoryValue::from(6); + MemoryValue da_gas_allocated = MemoryValue::from(7); + MemoryValue cd_size = MemoryValue::from(8); + AppendOnlyTreeSnapshot written_public_data_slots_tree_snapshot = AppendOnlyTreeSnapshot{ + .root = 0x12345678, + .nextAvailableLeafIndex = 10, + }; + TreeStates tree_states = + TreeStates{ .noteHashTree = { .tree = { .root = 10, .nextAvailableLeafIndex = 9 }, .counter = 8 }, + .nullifierTree = { .tree = { .root = 7, .nextAvailableLeafIndex = 6 }, .counter = 5 }, + .l1ToL2MessageTree = { .tree = { .root = 4, .nextAvailableLeafIndex = 3 }, .counter = 0 }, + .publicDataTree = { .tree = { .root = 2, .nextAvailableLeafIndex = 1 }, .counter = 1 } }; + SideEffectStates side_effect_states = SideEffectStates{ .numUnencryptedLogs = 1, .numL2ToL1Messages = 2 }; + + auto setup_context_expectations = [&](bool parent_is_static) { + EXPECT_CALL(gas_tracker, compute_gas_limit_for_call(Gas{ 6, 7 })).WillOnce(Return(Gas{ 2, 3 })); + EXPECT_CALL(gas_tracker, consume_gas(Gas{ 0, 0 })); + EXPECT_CALL(context, get_context_id); + EXPECT_CALL(context, get_parent_id); + EXPECT_CALL(context, get_bytecode_manager).WillOnce(ReturnRef(bytecode_manager)); + EXPECT_CALL(bytecode_manager, try_get_bytecode_id); + EXPECT_CALL(context, get_next_pc); + EXPECT_CALL(context, get_is_static).WillRepeatedly(Return(parent_is_static)); + EXPECT_CALL(context, get_msg_sender).WillOnce(ReturnRef(parent_address)); + EXPECT_CALL(context, get_transaction_fee).WillOnce(ReturnRef(zero)); + EXPECT_CALL(context, get_parent_cd_addr); + EXPECT_CALL(context, get_parent_cd_size); + EXPECT_CALL(context, get_parent_gas_used); + EXPECT_CALL(context, get_parent_gas_limit); + EXPECT_CALL(context, get_written_public_data_slots_tree_snapshot) + .WillOnce(Return(written_public_data_slots_tree_snapshot)); + EXPECT_CALL(context, get_side_effect_states).WillRepeatedly(ReturnRef(side_effect_states)); + EXPECT_CALL(context, get_phase).WillOnce(Return(TransactionPhase::APP_LOGIC)); + EXPECT_CALL(merkle_db, get_tree_state).WillOnce(Return(tree_states)); + EXPECT_CALL(context, get_memory); + EXPECT_CALL(context, get_address).WillRepeatedly(ReturnRef(parent_address)); + EXPECT_CALL(memory, get(1)).WillOnce(ReturnRef(l2_gas_allocated)); + EXPECT_CALL(memory, get(2)).WillOnce(ReturnRef(da_gas_allocated)); + EXPECT_CALL(memory, get(3)).WillOnce(ReturnRef(nested_address_value)); + EXPECT_CALL(memory, get(4)).WillOnce(ReturnRef(cd_size)); + }; + + auto create_nested_context = []() { + auto nested = std::make_unique>(); + ON_CALL(*nested, halted()).WillByDefault(Return(true)); + return nested; + }; + + // Test Case 1: Non-static context + CALL -> nested context is non-static + setup_context_expectations(false); + EXPECT_CALL(context_provider, + make_nested_context(nested_address, + parent_address, + _, + _, + _, + _, + /*is_static=*/false, + Gas{ 2, 3 }, + side_effect_states, + TransactionPhase::APP_LOGIC)) + .WillOnce(Return(create_nested_context())); + execution.call(context, 1, 2, 3, 4, 5); + + // Test Case 2: Non-static context + STATICCALL -> nested context is static + setup_context_expectations(false); + EXPECT_CALL(context_provider, + make_nested_context(nested_address, + parent_address, + _, + _, + _, + _, + /*is_static=*/true, + Gas{ 2, 3 }, + side_effect_states, + TransactionPhase::APP_LOGIC)) + .WillOnce(Return(create_nested_context())); + execution.static_call(context, 1, 2, 3, 4, 5); + + // Test Case 3: Static context + CALL -> nested context remains static + setup_context_expectations(true); + EXPECT_CALL(context_provider, + make_nested_context(nested_address, + parent_address, + _, + _, + _, + _, + /*is_static=*/true, + Gas{ 2, 3 }, + side_effect_states, + TransactionPhase::APP_LOGIC)) + .WillOnce(Return(create_nested_context())); + execution.call(context, 1, 2, 3, 4, 5); + + // Test Case 4: Static context + STATICCALL -> nested context remains static + setup_context_expectations(true); + EXPECT_CALL(context_provider, + make_nested_context(nested_address, + parent_address, + _, + _, + _, + _, + /*is_static=*/true, + Gas{ 2, 3 }, + side_effect_states, + TransactionPhase::APP_LOGIC)) + .WillOnce(Return(create_nested_context())); + execution.static_call(context, 1, 2, 3, 4, 5); +} + TEST_F(ExecutionSimulationTest, InternalCall) { uint32_t return_pc = 500; // This is next pc that we should return to after the internal call.