diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index 11cd956237d..d1e510699e8 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -23,15 +23,15 @@ pub enum AvmOpcode { ADDRESS, STORAGEADDRESS, SENDER, - FEEPERL2GAS, - FEEPERDAGAS, + FUNCTIONSELECTOR, TRANSACTIONFEE, - CONTRACTCALLDEPTH, CHAINID, VERSION, BLOCKNUMBER, TIMESTAMP, COINBASE, + FEEPERL2GAS, + FEEPERDAGAS, BLOCKL2GASLIMIT, BLOCKDAGASLIMIT, CALLDATACOPY, @@ -106,16 +106,16 @@ impl AvmOpcode { AvmOpcode::ADDRESS => "ADDRESS", AvmOpcode::STORAGEADDRESS => "STORAGEADDRESS", AvmOpcode::SENDER => "SENDER", - AvmOpcode::FEEPERL2GAS => "FEEPERL2GAS", - AvmOpcode::FEEPERDAGAS => "FEEPERDAGAS", + AvmOpcode::FUNCTIONSELECTOR => "FUNCTIONSELECTOR", AvmOpcode::TRANSACTIONFEE => "TRANSACTIONFEE", - AvmOpcode::CONTRACTCALLDEPTH => "CONTRACTCALLDEPTH", // Execution Environment - Globals AvmOpcode::CHAINID => "CHAINID", AvmOpcode::VERSION => "VERSION", AvmOpcode::BLOCKNUMBER => "BLOCKNUMBER", AvmOpcode::TIMESTAMP => "TIMESTAMP", AvmOpcode::COINBASE => "COINBASE", + AvmOpcode::FEEPERL2GAS => "FEEPERL2GAS", + AvmOpcode::FEEPERDAGAS => "FEEPERDAGAS", AvmOpcode::BLOCKL2GASLIMIT => "BLOCKL2GASLIMIT", AvmOpcode::BLOCKDAGASLIMIT => "BLOCKDAGASLIMIT", // Execution Environment - Calldata diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 80610006ec0..f8c0d882bf6 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -314,11 +314,9 @@ fn handle_external_call( ValueOrArray::HeapVector(HeapVector { pointer, size }) => (pointer.0 as u32, size.0 as u32), _ => panic!("Call instruction's args input should be a HeapVector input"), }; - let temporary_function_selector_offset = match &inputs[4] { + let function_selector_offset = match &inputs[4] { ValueOrArray::MemoryAddress(offset) => offset.to_usize() as u32, - _ => panic!( - "Call instruction's temporary function selector input should be a basic MemoryAddress", - ), + _ => panic!("Call instruction's function selector input should be a basic MemoryAddress",), }; let ret_offset_maybe = destinations[0]; @@ -351,7 +349,7 @@ fn handle_external_call( AvmOperand::U32 { value: ret_offset }, AvmOperand::U32 { value: ret_size }, AvmOperand::U32 { value: success_offset }, - AvmOperand::U32 { value: temporary_function_selector_offset }, + AvmOperand::U32 { value: function_selector_offset }, ], ..Default::default() }); @@ -650,6 +648,7 @@ fn handle_getter_instruction( "avmOpcodeTimestamp" => AvmOpcode::TIMESTAMP, "avmOpcodeL2GasLeft" => AvmOpcode::L2GASLEFT, "avmOpcodeDaGasLeft" => AvmOpcode::DAGASLEFT, + "avmOpcodeFunctionSelector" => AvmOpcode::FUNCTIONSELECTOR, // "callStackDepth" => AvmOpcode::CallStackDepth, _ => panic!("Transpiler doesn't know how to process ForeignCall function {:?}", function), }; diff --git a/barretenberg/cpp/pil/avm/constants.pil b/barretenberg/cpp/pil/avm/constants.pil index 6de0cfb9e77..f0f54bd873c 100644 --- a/barretenberg/cpp/pil/avm/constants.pil +++ b/barretenberg/cpp/pil/avm/constants.pil @@ -1,43 +1,45 @@ // NOTE: the constants in this file line up to the indexes of values in the -// `PublicKernelInputs.nr` object +// `PublicCircuitPublicInputs` object namespace constants(256); - // From Public Context Inputs + // From PublicCircuitPublicInputs's CallContext member pol SENDER_SELECTOR = 0; + // "address" actually does not exist in PublicCircuitPublicInputs, + // so this is just an alias to "storage address" for now pol ADDRESS_SELECTOR = 1; - pol STORAGE_ADDRESS_SELECTOR = 2; + pol STORAGE_ADDRESS_SELECTOR = 1; + pol FUNCTION_SELECTOR_SELECTOR = 2; // NOTE: constant expression evaluation does not seem to be supported yet in pil // pol START_GLOBAL_VARIABLES = CALL_CONTEXT_LENGTH + HEADER_LENGTH = 6 + 23 = 29 + // From PublicCircuitPublicInputs's GlobalVariables member // Global Variables pol CHAIN_ID_SELECTOR = 29; pol VERSION_SELECTOR = 30; pol BLOCK_NUMBER_SELECTOR = 31; pol TIMESTAMP_SELECTOR = 32; pol COINBASE_SELECTOR = 33; - - pol END_GLOBAL_VARIABLES = 29 + 8; // We only use the first 5 of 8 global variables for now - - // Gas - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6715): This has since moved into the global variables + // Global Variables - fees pol FEE_PER_DA_GAS_SELECTOR = 35; pol FEE_PER_L2_GAS_SELECTOR = 36; - pol START_SIDE_EFFECT_COUNTER = 37; + pol END_GLOBAL_VARIABLES = 29 + 8; // We only use the first 5 of 8 global variables for now + // Top-level PublicCircuitPublicInputs members + pol START_SIDE_EFFECT_COUNTER = 37; pol TRANSACTION_FEE_SELECTOR = 40; // Other AVM specific constants pol INTERNAL_CALL_SPACE_ID = 255; // Lengths of kernel output vectors + // (vectors in PublicCircuitPublicInputs to be processed by kernel) // Read requests pol MAX_NULLIFIER_READ_REQUESTS_PER_CALL = 32; pol MAX_NOTE_HASH_READ_REQUESTS_PER_CALL = 32; pol MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL = 32; pol MAX_PUBLIC_DATA_READS_PER_CALL = 32; - // Emitting Data pol MAX_NEW_NOTE_HASHES_PER_CALL = 16; pol MAX_NEW_NULLIIFIERS_PER_CALL = 16; diff --git a/barretenberg/cpp/pil/avm/main.pil b/barretenberg/cpp/pil/avm/main.pil index 8ea4377a538..63615604b19 100644 --- a/barretenberg/cpp/pil/avm/main.pil +++ b/barretenberg/cpp/pil/avm/main.pil @@ -24,24 +24,24 @@ namespace main(256); // Kernel lookup selector opcodes pol commit sel_q_kernel_lookup; - // CALL CONTEXT - pol commit sel_op_sender; + // CONTEXT - ENVIRONMENT pol commit sel_op_address; pol commit sel_op_storage_address; - - // FEES - pol commit sel_op_fee_per_l2_gas; - pol commit sel_op_fee_per_da_gas; + pol commit sel_op_sender; + pol commit sel_op_function_selector; pol commit sel_op_transaction_fee; - - // GLOBALS + + // CONTEXT - ENVIRONMENT - GLOBALS pol commit sel_op_chain_id; pol commit sel_op_version; pol commit sel_op_block_number; pol commit sel_op_coinbase; pol commit sel_op_timestamp; + // CONTEXT - ENVIRONMENT - GLOBALS - FEES + pol commit sel_op_fee_per_l2_gas; + pol commit sel_op_fee_per_da_gas; - // MACHINE STATE - GAS + // CONTEXT - MACHINE STATE - GAS pol commit sel_op_l2gasleft; pol commit sel_op_dagasleft; @@ -262,9 +262,11 @@ namespace main(256); // Relations on type constraints // TODO: Very likely, we can remove these constraints as the selectors should be derived during // opcode decomposition. - sel_op_sender * (1 - sel_op_sender) = 0; sel_op_address * (1 - sel_op_address) = 0; sel_op_storage_address * (1 - sel_op_storage_address) = 0; + sel_op_sender * (1 - sel_op_sender) = 0; + sel_op_function_selector * (1 - sel_op_function_selector) = 0; + sel_op_transaction_fee * (1 - sel_op_transaction_fee) = 0; sel_op_chain_id * (1 - sel_op_chain_id) = 0; sel_op_version * (1 - sel_op_version) = 0; sel_op_block_number * (1 - sel_op_block_number) = 0; @@ -272,7 +274,6 @@ namespace main(256); sel_op_timestamp * (1 - sel_op_timestamp) = 0; sel_op_fee_per_l2_gas * (1 - sel_op_fee_per_l2_gas) = 0; sel_op_fee_per_da_gas * (1 - sel_op_fee_per_da_gas) = 0; - sel_op_transaction_fee * (1 - sel_op_transaction_fee) = 0; // MACHINE STATE - GAS sel_op_l2gasleft * (1 - sel_op_l2gasleft) = 0; @@ -410,8 +411,9 @@ namespace main(256); //===== KERNEL LOOKUPS ======================================================= pol KERNEL_INPUT_SELECTORS = ( - sel_op_sender + sel_op_address + sel_op_storage_address + sel_op_chain_id + sel_op_version + sel_op_block_number + sel_op_coinbase + - sel_op_timestamp + sel_op_fee_per_l2_gas + sel_op_fee_per_da_gas + sel_op_transaction_fee + sel_op_address + sel_op_storage_address + sel_op_sender + sel_op_function_selector + sel_op_transaction_fee + + sel_op_chain_id + sel_op_version + sel_op_block_number + sel_op_coinbase + sel_op_timestamp + + sel_op_fee_per_l2_gas + sel_op_fee_per_da_gas ); // Ensure that only one kernel lookup is active when the kernel_in_offset is active #[KERNEL_INPUT_ACTIVE_CHECK] @@ -568,27 +570,23 @@ namespace main(256); // We can lookup into a fixed index of this polynomial by including constraints that force the value // of kernel_in_offset to the value relevant to the given opcode that is active - // CALL CONTEXT - #[SENDER_KERNEL] - sel_op_sender * (kernel.kernel_in_offset - constants.SENDER_SELECTOR) = 0; - + // CONTEXT - ENVIRONMENT #[ADDRESS_KERNEL] sel_op_address * (kernel.kernel_in_offset - constants.ADDRESS_SELECTOR) = 0; #[STORAGE_ADDRESS_KERNEL] sel_op_storage_address * (kernel.kernel_in_offset - constants.STORAGE_ADDRESS_SELECTOR) = 0; - // FEES - #[FEE_DA_GAS_KERNEL] - sel_op_fee_per_da_gas * (kernel.kernel_in_offset - constants.FEE_PER_DA_GAS_SELECTOR) = 0; + #[SENDER_KERNEL] + sel_op_sender * (kernel.kernel_in_offset - constants.SENDER_SELECTOR) = 0; - #[FEE_L2_GAS_KERNEL] - sel_op_fee_per_l2_gas * (kernel.kernel_in_offset - constants.FEE_PER_L2_GAS_SELECTOR) = 0; + #[FUNCTION_SELECTOR_KERNEL] + sel_op_function_selector * (kernel.kernel_in_offset - constants.FUNCTION_SELECTOR_SELECTOR) = 0; #[FEE_TRANSACTION_FEE_KERNEL] sel_op_transaction_fee * (kernel.kernel_in_offset - constants.TRANSACTION_FEE_SELECTOR) = 0; - // GLOBALS + // CONTEXT - ENVIRONMENT - GLOBALS #[CHAIN_ID_KERNEL] sel_op_chain_id * (kernel.kernel_in_offset - constants.CHAIN_ID_SELECTOR) = 0; @@ -598,11 +596,18 @@ namespace main(256); #[BLOCK_NUMBER_KERNEL] sel_op_block_number * (kernel.kernel_in_offset - constants.BLOCK_NUMBER_SELECTOR) = 0; + #[TIMESTAMP_KERNEL] + sel_op_timestamp * (kernel.kernel_in_offset - constants.TIMESTAMP_SELECTOR) = 0; + #[COINBASE_KERNEL] sel_op_coinbase * (kernel.kernel_in_offset - constants.COINBASE_SELECTOR) = 0; - #[TIMESTAMP_KERNEL] - sel_op_timestamp * (kernel.kernel_in_offset - constants.TIMESTAMP_SELECTOR) = 0; + // CONTEXT - ENVIRONMENT - GLOBALS - FEES + #[FEE_DA_GAS_KERNEL] + sel_op_fee_per_da_gas * (kernel.kernel_in_offset - constants.FEE_PER_DA_GAS_SELECTOR) = 0; + + #[FEE_L2_GAS_KERNEL] + sel_op_fee_per_l2_gas * (kernel.kernel_in_offset - constants.FEE_PER_L2_GAS_SELECTOR) = 0; // OUTPUTS LOOKUPS // Constrain the value of kernel_out_offset to be the correct offset for the operation being performed diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp index 9fa9e19c6c4..c50b8825f71 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -211,6 +211,7 @@ [[maybe_unused]] auto main_sel_op_fdiv = View(new_term.main_sel_op_fdiv); \ [[maybe_unused]] auto main_sel_op_fee_per_da_gas = View(new_term.main_sel_op_fee_per_da_gas); \ [[maybe_unused]] auto main_sel_op_fee_per_l2_gas = View(new_term.main_sel_op_fee_per_l2_gas); \ + [[maybe_unused]] auto main_sel_op_function_selector = View(new_term.main_sel_op_function_selector); \ [[maybe_unused]] auto main_sel_op_get_contract_instance = View(new_term.main_sel_op_get_contract_instance); \ [[maybe_unused]] auto main_sel_op_halt = View(new_term.main_sel_op_halt); \ [[maybe_unused]] auto main_sel_op_internal_call = View(new_term.main_sel_op_internal_call); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/main.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/main.hpp index 360aa5af82b..5491bd8a586 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/main.hpp @@ -84,6 +84,7 @@ template struct MainRow { FF main_sel_op_fdiv{}; FF main_sel_op_fee_per_da_gas{}; FF main_sel_op_fee_per_l2_gas{}; + FF main_sel_op_function_selector{}; FF main_sel_op_get_contract_instance{}; FF main_sel_op_halt{}; FF main_sel_op_internal_call{}; @@ -144,80 +145,77 @@ inline std::string get_relation_label_main(int index) case 5: return "DA_GAS_INACTIVE"; - case 74: + case 75: return "OUTPUT_U8"; - case 75: + case 76: return "SUBOP_FDIV"; - case 76: + case 77: return "SUBOP_FDIV_ZERO_ERR1"; - case 77: + case 78: return "SUBOP_FDIV_ZERO_ERR2"; - case 78: + case 79: return "SUBOP_FDIV_R_IN_TAG_FF"; - case 79: + case 80: return "SUBOP_FDIV_W_IN_TAG_FF"; - case 80: + case 81: return "SUBOP_ERROR_RELEVANT_OP"; - case 81: + case 82: return "KERNEL_INPUT_ACTIVE_CHECK"; - case 82: + case 83: return "KERNEL_OUTPUT_ACTIVE_CHECK"; - case 83: + case 84: return "PC_JUMP"; - case 84: + case 85: return "PC_JUMPI"; - case 85: + case 86: return "RETURN_POINTER_INCREMENT"; - case 91: + case 92: return "RETURN_POINTER_DECREMENT"; - case 97: + case 98: return "PC_INCREMENT"; - case 98: + case 99: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 99: + case 100: return "SPACE_ID_INTERNAL"; - case 100: + case 101: return "SPACE_ID_STANDARD_OPCODES"; - case 101: + case 102: return "CMOV_CONDITION_RES_1"; - case 102: + case 103: return "CMOV_CONDITION_RES_2"; - case 105: + case 106: return "MOV_SAME_VALUE_A"; - case 106: + case 107: return "MOV_SAME_VALUE_B"; - case 107: + case 108: return "MOV_MAIN_SAME_TAG"; - case 111: - return "L2GASLEFT"; - case 112: - return "DAGASLEFT"; + return "L2GASLEFT"; case 113: - return "SENDER_KERNEL"; + return "DAGASLEFT"; case 114: return "ADDRESS_KERNEL"; @@ -226,10 +224,10 @@ inline std::string get_relation_label_main(int index) return "STORAGE_ADDRESS_KERNEL"; case 116: - return "FEE_DA_GAS_KERNEL"; + return "SENDER_KERNEL"; case 117: - return "FEE_L2_GAS_KERNEL"; + return "FUNCTION_SELECTOR_KERNEL"; case 118: return "FEE_TRANSACTION_FEE_KERNEL"; @@ -244,42 +242,48 @@ inline std::string get_relation_label_main(int index) return "BLOCK_NUMBER_KERNEL"; case 122: - return "COINBASE_KERNEL"; + return "TIMESTAMP_KERNEL"; case 123: - return "TIMESTAMP_KERNEL"; + return "COINBASE_KERNEL"; case 124: - return "NOTE_HASH_KERNEL_OUTPUT"; + return "FEE_DA_GAS_KERNEL"; + + case 125: + return "FEE_L2_GAS_KERNEL"; case 126: - return "EMIT_NOTE_HASH_KERNEL_OUTPUT"; + return "NOTE_HASH_KERNEL_OUTPUT"; case 128: + return "EMIT_NOTE_HASH_KERNEL_OUTPUT"; + + case 130: return "NULLIFIER_EXISTS_KERNEL_OUTPUT"; - case 131: + case 133: return "EMIT_NULLIFIER_KERNEL_OUTPUT"; - case 133: + case 135: return "L1_TO_L2_MSG_EXISTS_KERNEL_OUTPUT"; - case 135: + case 137: return "EMIT_UNENCRYPTED_LOG_KERNEL_OUTPUT"; - case 137: + case 139: return "EMIT_L2_TO_L1_MSGS_KERNEL_OUTPUT"; - case 139: + case 141: return "SLOAD_KERNEL_OUTPUT"; - case 141: + case 143: return "SSTORE_KERNEL_OUTPUT"; - case 144: + case 146: return "BIN_SEL_1"; - case 145: + case 147: return "BIN_SEL_2"; } return std::to_string(index); @@ -289,11 +293,11 @@ template class mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 4, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 3, 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 5, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 4, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, }; template @@ -379,7 +383,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (main_sel_op_sender * (-main_sel_op_sender + FF(1))); + auto tmp = (main_sel_op_address * (-main_sel_op_address + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -387,7 +391,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = (main_sel_op_address * (-main_sel_op_address + FF(1))); + auto tmp = (main_sel_op_storage_address * (-main_sel_op_storage_address + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -395,7 +399,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(10); - auto tmp = (main_sel_op_storage_address * (-main_sel_op_storage_address + FF(1))); + auto tmp = (main_sel_op_sender * (-main_sel_op_sender + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -403,7 +407,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(11); - auto tmp = (main_sel_op_chain_id * (-main_sel_op_chain_id + FF(1))); + auto tmp = (main_sel_op_function_selector * (-main_sel_op_function_selector + FF(1))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -411,7 +415,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = (main_sel_op_version * (-main_sel_op_version + FF(1))); + auto tmp = (main_sel_op_transaction_fee * (-main_sel_op_transaction_fee + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -419,7 +423,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(13); - auto tmp = (main_sel_op_block_number * (-main_sel_op_block_number + FF(1))); + auto tmp = (main_sel_op_chain_id * (-main_sel_op_chain_id + FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -427,7 +431,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = (main_sel_op_coinbase * (-main_sel_op_coinbase + FF(1))); + auto tmp = (main_sel_op_version * (-main_sel_op_version + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -435,7 +439,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = (main_sel_op_timestamp * (-main_sel_op_timestamp + FF(1))); + auto tmp = (main_sel_op_block_number * (-main_sel_op_block_number + FF(1))); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -443,7 +447,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (main_sel_op_fee_per_l2_gas * (-main_sel_op_fee_per_l2_gas + FF(1))); + auto tmp = (main_sel_op_coinbase * (-main_sel_op_coinbase + FF(1))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -451,7 +455,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = (main_sel_op_fee_per_da_gas * (-main_sel_op_fee_per_da_gas + FF(1))); + auto tmp = (main_sel_op_timestamp * (-main_sel_op_timestamp + FF(1))); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -459,7 +463,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (main_sel_op_transaction_fee * (-main_sel_op_transaction_fee + FF(1))); + auto tmp = (main_sel_op_fee_per_l2_gas * (-main_sel_op_fee_per_l2_gas + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -467,7 +471,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (main_sel_op_l2gasleft * (-main_sel_op_l2gasleft + FF(1))); + auto tmp = (main_sel_op_fee_per_da_gas * (-main_sel_op_fee_per_da_gas + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -475,7 +479,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (main_sel_op_dagasleft * (-main_sel_op_dagasleft + FF(1))); + auto tmp = (main_sel_op_l2gasleft * (-main_sel_op_l2gasleft + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -483,7 +487,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (main_sel_op_note_hash_exists * (-main_sel_op_note_hash_exists + FF(1))); + auto tmp = (main_sel_op_dagasleft * (-main_sel_op_dagasleft + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -491,7 +495,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (main_sel_op_emit_note_hash * (-main_sel_op_emit_note_hash + FF(1))); + auto tmp = (main_sel_op_note_hash_exists * (-main_sel_op_note_hash_exists + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -499,7 +503,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (main_sel_op_nullifier_exists * (-main_sel_op_nullifier_exists + FF(1))); + auto tmp = (main_sel_op_emit_note_hash * (-main_sel_op_emit_note_hash + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -507,7 +511,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (main_sel_op_emit_nullifier * (-main_sel_op_emit_nullifier + FF(1))); + auto tmp = (main_sel_op_nullifier_exists * (-main_sel_op_nullifier_exists + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -515,7 +519,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (main_sel_op_l1_to_l2_msg_exists * (-main_sel_op_l1_to_l2_msg_exists + FF(1))); + auto tmp = (main_sel_op_emit_nullifier * (-main_sel_op_emit_nullifier + FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -523,7 +527,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (main_sel_op_emit_unencrypted_log * (-main_sel_op_emit_unencrypted_log + FF(1))); + auto tmp = (main_sel_op_l1_to_l2_msg_exists * (-main_sel_op_l1_to_l2_msg_exists + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -531,7 +535,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (main_sel_op_emit_l2_to_l1_msg * (-main_sel_op_emit_l2_to_l1_msg + FF(1))); + auto tmp = (main_sel_op_emit_unencrypted_log * (-main_sel_op_emit_unencrypted_log + FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -539,7 +543,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (main_sel_op_get_contract_instance * (-main_sel_op_get_contract_instance + FF(1))); + auto tmp = (main_sel_op_emit_l2_to_l1_msg * (-main_sel_op_emit_l2_to_l1_msg + FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -547,7 +551,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (main_sel_op_sload * (-main_sel_op_sload + FF(1))); + auto tmp = (main_sel_op_get_contract_instance * (-main_sel_op_get_contract_instance + FF(1))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -555,7 +559,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (main_sel_op_sstore * (-main_sel_op_sstore + FF(1))); + auto tmp = (main_sel_op_sload * (-main_sel_op_sload + FF(1))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -563,7 +567,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (main_sel_op_radix_le * (-main_sel_op_radix_le + FF(1))); + auto tmp = (main_sel_op_sstore * (-main_sel_op_sstore + FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -571,7 +575,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (main_sel_op_sha256 * (-main_sel_op_sha256 + FF(1))); + auto tmp = (main_sel_op_radix_le * (-main_sel_op_radix_le + FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -579,7 +583,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (main_sel_op_poseidon2 * (-main_sel_op_poseidon2 + FF(1))); + auto tmp = (main_sel_op_sha256 * (-main_sel_op_sha256 + FF(1))); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -587,7 +591,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (main_sel_op_keccak * (-main_sel_op_keccak + FF(1))); + auto tmp = (main_sel_op_poseidon2 * (-main_sel_op_poseidon2 + FF(1))); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -595,7 +599,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (main_sel_op_pedersen * (-main_sel_op_pedersen + FF(1))); + auto tmp = (main_sel_op_keccak * (-main_sel_op_keccak + FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -603,7 +607,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (main_sel_op_add * (-main_sel_op_add + FF(1))); + auto tmp = (main_sel_op_pedersen * (-main_sel_op_pedersen + FF(1))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -611,7 +615,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (main_sel_op_sub * (-main_sel_op_sub + FF(1))); + auto tmp = (main_sel_op_add * (-main_sel_op_add + FF(1))); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -619,7 +623,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (main_sel_op_mul * (-main_sel_op_mul + FF(1))); + auto tmp = (main_sel_op_sub * (-main_sel_op_sub + FF(1))); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -627,7 +631,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = (main_sel_op_div * (-main_sel_op_div + FF(1))); + auto tmp = (main_sel_op_mul * (-main_sel_op_mul + FF(1))); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -635,7 +639,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (main_sel_op_fdiv * (-main_sel_op_fdiv + FF(1))); + auto tmp = (main_sel_op_div * (-main_sel_op_div + FF(1))); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -643,7 +647,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(41); - auto tmp = (main_sel_op_not * (-main_sel_op_not + FF(1))); + auto tmp = (main_sel_op_fdiv * (-main_sel_op_fdiv + FF(1))); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -651,7 +655,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = (main_sel_op_eq * (-main_sel_op_eq + FF(1))); + auto tmp = (main_sel_op_not * (-main_sel_op_not + FF(1))); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -659,7 +663,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = (main_sel_op_and * (-main_sel_op_and + FF(1))); + auto tmp = (main_sel_op_eq * (-main_sel_op_eq + FF(1))); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -667,7 +671,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(44); - auto tmp = (main_sel_op_or * (-main_sel_op_or + FF(1))); + auto tmp = (main_sel_op_and * (-main_sel_op_and + FF(1))); tmp *= scaling_factor; std::get<44>(evals) += tmp; } @@ -675,7 +679,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(45); - auto tmp = (main_sel_op_xor * (-main_sel_op_xor + FF(1))); + auto tmp = (main_sel_op_or * (-main_sel_op_or + FF(1))); tmp *= scaling_factor; std::get<45>(evals) += tmp; } @@ -683,7 +687,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(46); - auto tmp = (main_sel_op_cast * (-main_sel_op_cast + FF(1))); + auto tmp = (main_sel_op_xor * (-main_sel_op_xor + FF(1))); tmp *= scaling_factor; std::get<46>(evals) += tmp; } @@ -691,7 +695,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(47); - auto tmp = (main_sel_op_lt * (-main_sel_op_lt + FF(1))); + auto tmp = (main_sel_op_cast * (-main_sel_op_cast + FF(1))); tmp *= scaling_factor; std::get<47>(evals) += tmp; } @@ -699,7 +703,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(48); - auto tmp = (main_sel_op_lte * (-main_sel_op_lte + FF(1))); + auto tmp = (main_sel_op_lt * (-main_sel_op_lt + FF(1))); tmp *= scaling_factor; std::get<48>(evals) += tmp; } @@ -707,7 +711,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(49); - auto tmp = (main_sel_op_shl * (-main_sel_op_shl + FF(1))); + auto tmp = (main_sel_op_lte * (-main_sel_op_lte + FF(1))); tmp *= scaling_factor; std::get<49>(evals) += tmp; } @@ -715,7 +719,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(50); - auto tmp = (main_sel_op_shr * (-main_sel_op_shr + FF(1))); + auto tmp = (main_sel_op_shl * (-main_sel_op_shl + FF(1))); tmp *= scaling_factor; std::get<50>(evals) += tmp; } @@ -723,7 +727,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(51); - auto tmp = (main_sel_op_internal_call * (-main_sel_op_internal_call + FF(1))); + auto tmp = (main_sel_op_shr * (-main_sel_op_shr + FF(1))); tmp *= scaling_factor; std::get<51>(evals) += tmp; } @@ -731,7 +735,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(52); - auto tmp = (main_sel_op_internal_return * (-main_sel_op_internal_return + FF(1))); + auto tmp = (main_sel_op_internal_call * (-main_sel_op_internal_call + FF(1))); tmp *= scaling_factor; std::get<52>(evals) += tmp; } @@ -739,7 +743,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(53); - auto tmp = (main_sel_op_jump * (-main_sel_op_jump + FF(1))); + auto tmp = (main_sel_op_internal_return * (-main_sel_op_internal_return + FF(1))); tmp *= scaling_factor; std::get<53>(evals) += tmp; } @@ -747,7 +751,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(54); - auto tmp = (main_sel_op_jumpi * (-main_sel_op_jumpi + FF(1))); + auto tmp = (main_sel_op_jump * (-main_sel_op_jump + FF(1))); tmp *= scaling_factor; std::get<54>(evals) += tmp; } @@ -755,7 +759,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(55); - auto tmp = (main_sel_op_halt * (-main_sel_op_halt + FF(1))); + auto tmp = (main_sel_op_jumpi * (-main_sel_op_jumpi + FF(1))); tmp *= scaling_factor; std::get<55>(evals) += tmp; } @@ -763,7 +767,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(56); - auto tmp = (main_sel_op_external_call * (-main_sel_op_external_call + FF(1))); + auto tmp = (main_sel_op_halt * (-main_sel_op_halt + FF(1))); tmp *= scaling_factor; std::get<56>(evals) += tmp; } @@ -771,7 +775,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(57); - auto tmp = (main_sel_op_mov * (-main_sel_op_mov + FF(1))); + auto tmp = (main_sel_op_external_call * (-main_sel_op_external_call + FF(1))); tmp *= scaling_factor; std::get<57>(evals) += tmp; } @@ -779,7 +783,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(58); - auto tmp = (main_sel_op_cmov * (-main_sel_op_cmov + FF(1))); + auto tmp = (main_sel_op_mov * (-main_sel_op_mov + FF(1))); tmp *= scaling_factor; std::get<58>(evals) += tmp; } @@ -787,7 +791,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(59); - auto tmp = (main_op_err * (-main_op_err + FF(1))); + auto tmp = (main_sel_op_cmov * (-main_sel_op_cmov + FF(1))); tmp *= scaling_factor; std::get<59>(evals) += tmp; } @@ -795,7 +799,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(60); - auto tmp = (main_tag_err * (-main_tag_err + FF(1))); + auto tmp = (main_op_err * (-main_op_err + FF(1))); tmp *= scaling_factor; std::get<60>(evals) += tmp; } @@ -803,7 +807,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(61); - auto tmp = (main_id_zero * (-main_id_zero + FF(1))); + auto tmp = (main_tag_err * (-main_tag_err + FF(1))); tmp *= scaling_factor; std::get<61>(evals) += tmp; } @@ -811,7 +815,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(62); - auto tmp = (main_sel_mem_op_a * (-main_sel_mem_op_a + FF(1))); + auto tmp = (main_id_zero * (-main_id_zero + FF(1))); tmp *= scaling_factor; std::get<62>(evals) += tmp; } @@ -819,7 +823,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(63); - auto tmp = (main_sel_mem_op_b * (-main_sel_mem_op_b + FF(1))); + auto tmp = (main_sel_mem_op_a * (-main_sel_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<63>(evals) += tmp; } @@ -827,7 +831,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(64); - auto tmp = (main_sel_mem_op_c * (-main_sel_mem_op_c + FF(1))); + auto tmp = (main_sel_mem_op_b * (-main_sel_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<64>(evals) += tmp; } @@ -835,7 +839,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(65); - auto tmp = (main_sel_mem_op_d * (-main_sel_mem_op_d + FF(1))); + auto tmp = (main_sel_mem_op_c * (-main_sel_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<65>(evals) += tmp; } @@ -843,7 +847,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(66); - auto tmp = (main_rwa * (-main_rwa + FF(1))); + auto tmp = (main_sel_mem_op_d * (-main_sel_mem_op_d + FF(1))); tmp *= scaling_factor; std::get<66>(evals) += tmp; } @@ -851,7 +855,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(67); - auto tmp = (main_rwb * (-main_rwb + FF(1))); + auto tmp = (main_rwa * (-main_rwa + FF(1))); tmp *= scaling_factor; std::get<67>(evals) += tmp; } @@ -859,7 +863,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(68); - auto tmp = (main_rwc * (-main_rwc + FF(1))); + auto tmp = (main_rwb * (-main_rwb + FF(1))); tmp *= scaling_factor; std::get<68>(evals) += tmp; } @@ -867,7 +871,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(69); - auto tmp = (main_rwd * (-main_rwd + FF(1))); + auto tmp = (main_rwc * (-main_rwc + FF(1))); tmp *= scaling_factor; std::get<69>(evals) += tmp; } @@ -875,7 +879,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(70); - auto tmp = (main_sel_resolve_ind_addr_a * (-main_sel_resolve_ind_addr_a + FF(1))); + auto tmp = (main_rwd * (-main_rwd + FF(1))); tmp *= scaling_factor; std::get<70>(evals) += tmp; } @@ -883,7 +887,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(71); - auto tmp = (main_sel_resolve_ind_addr_b * (-main_sel_resolve_ind_addr_b + FF(1))); + auto tmp = (main_sel_resolve_ind_addr_a * (-main_sel_resolve_ind_addr_a + FF(1))); tmp *= scaling_factor; std::get<71>(evals) += tmp; } @@ -891,7 +895,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(72); - auto tmp = (main_sel_resolve_ind_addr_c * (-main_sel_resolve_ind_addr_c + FF(1))); + auto tmp = (main_sel_resolve_ind_addr_b * (-main_sel_resolve_ind_addr_b + FF(1))); tmp *= scaling_factor; std::get<72>(evals) += tmp; } @@ -899,7 +903,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(73); - auto tmp = (main_sel_resolve_ind_addr_d * (-main_sel_resolve_ind_addr_d + FF(1))); + auto tmp = (main_sel_resolve_ind_addr_c * (-main_sel_resolve_ind_addr_c + FF(1))); tmp *= scaling_factor; std::get<73>(evals) += tmp; } @@ -907,7 +911,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(74); - auto tmp = (((main_sel_op_eq + main_sel_op_lte) + main_sel_op_lt) * (main_w_in_tag - FF(1))); + auto tmp = (main_sel_resolve_ind_addr_d * (-main_sel_resolve_ind_addr_d + FF(1))); tmp *= scaling_factor; std::get<74>(evals) += tmp; } @@ -915,7 +919,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(75); - auto tmp = ((main_sel_op_fdiv * (-main_op_err + FF(1))) * ((main_ic * main_ib) - main_ia)); + auto tmp = (((main_sel_op_eq + main_sel_op_lte) + main_sel_op_lt) * (main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<75>(evals) += tmp; } @@ -923,7 +927,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(76); - auto tmp = ((main_sel_op_fdiv + main_sel_op_div) * (((main_ib * main_inv) - FF(1)) + main_op_err)); + auto tmp = ((main_sel_op_fdiv * (-main_op_err + FF(1))) * ((main_ic * main_ib) - main_ia)); tmp *= scaling_factor; std::get<76>(evals) += tmp; } @@ -931,7 +935,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(77); - auto tmp = (((main_sel_op_fdiv + main_sel_op_div) * main_op_err) * (-main_inv + FF(1))); + auto tmp = ((main_sel_op_fdiv + main_sel_op_div) * (((main_ib * main_inv) - FF(1)) + main_op_err)); tmp *= scaling_factor; std::get<77>(evals) += tmp; } @@ -939,7 +943,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(78); - auto tmp = (main_sel_op_fdiv * (main_r_in_tag - FF(6))); + auto tmp = (((main_sel_op_fdiv + main_sel_op_div) * main_op_err) * (-main_inv + FF(1))); tmp *= scaling_factor; std::get<78>(evals) += tmp; } @@ -947,7 +951,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(79); - auto tmp = (main_sel_op_fdiv * (main_w_in_tag - FF(6))); + auto tmp = (main_sel_op_fdiv * (main_r_in_tag - FF(6))); tmp *= scaling_factor; std::get<79>(evals) += tmp; } @@ -955,7 +959,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(80); - auto tmp = (main_op_err * ((main_sel_op_fdiv + main_sel_op_div) - FF(1))); + auto tmp = (main_sel_op_fdiv * (main_w_in_tag - FF(6))); tmp *= scaling_factor; std::get<80>(evals) += tmp; } @@ -963,16 +967,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(81); - auto tmp = (((((((((((main_sel_op_sender + main_sel_op_address) + main_sel_op_storage_address) + - main_sel_op_chain_id) + - main_sel_op_version) + - main_sel_op_block_number) + - main_sel_op_coinbase) + - main_sel_op_timestamp) + - main_sel_op_fee_per_l2_gas) + - main_sel_op_fee_per_da_gas) + - main_sel_op_transaction_fee) * - (-main_sel_q_kernel_lookup + FF(1))); + auto tmp = (main_op_err * ((main_sel_op_fdiv + main_sel_op_div) - FF(1))); tmp *= scaling_factor; std::get<81>(evals) += tmp; } @@ -980,13 +975,17 @@ template class mainImpl { { Avm_DECLARE_VIEWS(82); - auto tmp = - (((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + - main_sel_op_emit_nullifier) + - main_sel_op_l1_to_l2_msg_exists) + - main_sel_op_emit_unencrypted_log) + - main_sel_op_emit_l2_to_l1_msg) * - (-main_sel_q_kernel_output_lookup + FF(1))); + auto tmp = ((((((((((((main_sel_op_address + main_sel_op_storage_address) + main_sel_op_sender) + + main_sel_op_function_selector) + + main_sel_op_transaction_fee) + + main_sel_op_chain_id) + + main_sel_op_version) + + main_sel_op_block_number) + + main_sel_op_coinbase) + + main_sel_op_timestamp) + + main_sel_op_fee_per_l2_gas) + + main_sel_op_fee_per_da_gas) * + (-main_sel_q_kernel_lookup + FF(1))); tmp *= scaling_factor; std::get<82>(evals) += tmp; } @@ -994,7 +993,13 @@ template class mainImpl { { Avm_DECLARE_VIEWS(83); - auto tmp = (main_sel_op_jump * (main_pc_shift - main_ia)); + auto tmp = + (((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + + main_sel_op_emit_nullifier) + + main_sel_op_l1_to_l2_msg_exists) + + main_sel_op_emit_unencrypted_log) + + main_sel_op_emit_l2_to_l1_msg) * + (-main_sel_q_kernel_output_lookup + FF(1))); tmp *= scaling_factor; std::get<83>(evals) += tmp; } @@ -1002,8 +1007,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(84); - auto tmp = (main_sel_op_jumpi * (((-main_id_zero + FF(1)) * (main_pc_shift - main_ia)) + - (main_id_zero * ((main_pc_shift - main_pc) - FF(1))))); + auto tmp = (main_sel_op_jump * (main_pc_shift - main_ia)); tmp *= scaling_factor; std::get<84>(evals) += tmp; } @@ -1011,8 +1015,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(85); - auto tmp = - (main_sel_op_internal_call * (main_internal_return_ptr_shift - (main_internal_return_ptr + FF(1)))); + auto tmp = (main_sel_op_jumpi * (((-main_id_zero + FF(1)) * (main_pc_shift - main_ia)) + + (main_id_zero * ((main_pc_shift - main_pc) - FF(1))))); tmp *= scaling_factor; std::get<85>(evals) += tmp; } @@ -1020,7 +1024,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(86); - auto tmp = (main_sel_op_internal_call * (main_internal_return_ptr - main_mem_addr_b)); + auto tmp = + (main_sel_op_internal_call * (main_internal_return_ptr_shift - (main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<86>(evals) += tmp; } @@ -1028,7 +1033,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(87); - auto tmp = (main_sel_op_internal_call * (main_pc_shift - main_ia)); + auto tmp = (main_sel_op_internal_call * (main_internal_return_ptr - main_mem_addr_b)); tmp *= scaling_factor; std::get<87>(evals) += tmp; } @@ -1036,7 +1041,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(88); - auto tmp = (main_sel_op_internal_call * ((main_pc + FF(1)) - main_ib)); + auto tmp = (main_sel_op_internal_call * (main_pc_shift - main_ia)); tmp *= scaling_factor; std::get<88>(evals) += tmp; } @@ -1044,7 +1049,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(89); - auto tmp = (main_sel_op_internal_call * (main_rwb - FF(1))); + auto tmp = (main_sel_op_internal_call * ((main_pc + FF(1)) - main_ib)); tmp *= scaling_factor; std::get<89>(evals) += tmp; } @@ -1052,7 +1057,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(90); - auto tmp = (main_sel_op_internal_call * (main_sel_mem_op_b - FF(1))); + auto tmp = (main_sel_op_internal_call * (main_rwb - FF(1))); tmp *= scaling_factor; std::get<90>(evals) += tmp; } @@ -1060,8 +1065,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(91); - auto tmp = - (main_sel_op_internal_return * (main_internal_return_ptr_shift - (main_internal_return_ptr - FF(1)))); + auto tmp = (main_sel_op_internal_call * (main_sel_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<91>(evals) += tmp; } @@ -1069,7 +1073,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(92); - auto tmp = (main_sel_op_internal_return * ((main_internal_return_ptr - FF(1)) - main_mem_addr_a)); + auto tmp = + (main_sel_op_internal_return * (main_internal_return_ptr_shift - (main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<92>(evals) += tmp; } @@ -1077,7 +1082,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(93); - auto tmp = (main_sel_op_internal_return * (main_pc_shift - main_ia)); + auto tmp = (main_sel_op_internal_return * ((main_internal_return_ptr - FF(1)) - main_mem_addr_a)); tmp *= scaling_factor; std::get<93>(evals) += tmp; } @@ -1085,7 +1090,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(94); - auto tmp = (main_sel_op_internal_return * main_rwa); + auto tmp = (main_sel_op_internal_return * (main_pc_shift - main_ia)); tmp *= scaling_factor; std::get<94>(evals) += tmp; } @@ -1093,7 +1098,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(95); - auto tmp = (main_sel_op_internal_return * (main_sel_mem_op_a - FF(1))); + auto tmp = (main_sel_op_internal_return * main_rwa); tmp *= scaling_factor; std::get<95>(evals) += tmp; } @@ -1101,6 +1106,14 @@ template class mainImpl { { Avm_DECLARE_VIEWS(96); + auto tmp = (main_sel_op_internal_return * (main_sel_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<96>(evals) += tmp; + } + // Contribution 97 + { + Avm_DECLARE_VIEWS(97); + auto tmp = (((((main_sel_gas_accounting_active - (((((((main_sel_op_fdiv + @@ -1116,15 +1129,16 @@ template class mainImpl { (main_sel_op_cmov + main_sel_op_mov)) + ((((main_sel_op_radix_le + main_sel_op_sha256) + main_sel_op_poseidon2) + main_sel_op_keccak) + main_sel_op_pedersen)) + - ((((((((((main_sel_op_sender + main_sel_op_address) + main_sel_op_storage_address) + - main_sel_op_chain_id) + - main_sel_op_version) + - main_sel_op_block_number) + - main_sel_op_coinbase) + - main_sel_op_timestamp) + - main_sel_op_fee_per_l2_gas) + - main_sel_op_fee_per_da_gas) + - main_sel_op_transaction_fee)) + + (((((((((((main_sel_op_address + main_sel_op_storage_address) + main_sel_op_sender) + + main_sel_op_function_selector) + + main_sel_op_transaction_fee) + + main_sel_op_chain_id) + + main_sel_op_version) + + main_sel_op_block_number) + + main_sel_op_coinbase) + + main_sel_op_timestamp) + + main_sel_op_fee_per_l2_gas) + + main_sel_op_fee_per_da_gas)) + ((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + main_sel_op_emit_nullifier) + @@ -1138,11 +1152,11 @@ template class mainImpl { main_sel_op_sstore) - main_sel_mem_op_activate_gas); tmp *= scaling_factor; - std::get<96>(evals) += tmp; + std::get<97>(evals) += tmp; } - // Contribution 97 + // Contribution 98 { - Avm_DECLARE_VIEWS(97); + Avm_DECLARE_VIEWS(98); auto tmp = ((((-main_sel_first + FF(1)) * (-main_sel_op_halt + FF(1))) * @@ -1159,15 +1173,16 @@ template class mainImpl { (main_sel_op_cmov + main_sel_op_mov)) + ((((main_sel_op_radix_le + main_sel_op_sha256) + main_sel_op_poseidon2) + main_sel_op_keccak) + main_sel_op_pedersen)) + - ((((((((((main_sel_op_sender + main_sel_op_address) + main_sel_op_storage_address) + - main_sel_op_chain_id) + - main_sel_op_version) + - main_sel_op_block_number) + - main_sel_op_coinbase) + - main_sel_op_timestamp) + - main_sel_op_fee_per_l2_gas) + - main_sel_op_fee_per_da_gas) + - main_sel_op_transaction_fee)) + + (((((((((((main_sel_op_address + main_sel_op_storage_address) + main_sel_op_sender) + + main_sel_op_function_selector) + + main_sel_op_transaction_fee) + + main_sel_op_chain_id) + + main_sel_op_version) + + main_sel_op_block_number) + + main_sel_op_coinbase) + + main_sel_op_timestamp) + + main_sel_op_fee_per_l2_gas) + + main_sel_op_fee_per_da_gas)) + ((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + main_sel_op_emit_nullifier) + main_sel_op_l1_to_l2_msg_exists) + @@ -1176,30 +1191,30 @@ template class mainImpl { (main_sel_op_dagasleft + main_sel_op_l2gasleft))) * (main_pc_shift - (main_pc + FF(1)))); tmp *= scaling_factor; - std::get<97>(evals) += tmp; + std::get<98>(evals) += tmp; } - // Contribution 98 + // Contribution 99 { - Avm_DECLARE_VIEWS(98); + Avm_DECLARE_VIEWS(99); auto tmp = ((-(((main_sel_first + main_sel_op_internal_call) + main_sel_op_internal_return) + main_sel_op_halt) + FF(1)) * (main_internal_return_ptr_shift - main_internal_return_ptr)); tmp *= scaling_factor; - std::get<98>(evals) += tmp; + std::get<99>(evals) += tmp; } - // Contribution 99 + // Contribution 100 { - Avm_DECLARE_VIEWS(99); + Avm_DECLARE_VIEWS(100); auto tmp = ((main_sel_op_internal_call + main_sel_op_internal_return) * (main_space_id - FF(255))); tmp *= scaling_factor; - std::get<99>(evals) += tmp; + std::get<100>(evals) += tmp; } - // Contribution 100 + // Contribution 101 { - Avm_DECLARE_VIEWS(100); + Avm_DECLARE_VIEWS(101); auto tmp = ((((((((main_sel_op_fdiv + @@ -1215,15 +1230,16 @@ template class mainImpl { (main_sel_op_cmov + main_sel_op_mov)) + ((((main_sel_op_radix_le + main_sel_op_sha256) + main_sel_op_poseidon2) + main_sel_op_keccak) + main_sel_op_pedersen)) + - ((((((((((main_sel_op_sender + main_sel_op_address) + main_sel_op_storage_address) + - main_sel_op_chain_id) + - main_sel_op_version) + - main_sel_op_block_number) + - main_sel_op_coinbase) + - main_sel_op_timestamp) + - main_sel_op_fee_per_l2_gas) + - main_sel_op_fee_per_da_gas) + - main_sel_op_transaction_fee)) + + (((((((((((main_sel_op_address + main_sel_op_storage_address) + main_sel_op_sender) + + main_sel_op_function_selector) + + main_sel_op_transaction_fee) + + main_sel_op_chain_id) + + main_sel_op_version) + + main_sel_op_block_number) + + main_sel_op_coinbase) + + main_sel_op_timestamp) + + main_sel_op_fee_per_l2_gas) + + main_sel_op_fee_per_da_gas)) + ((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + main_sel_op_emit_nullifier) + main_sel_op_l1_to_l2_msg_exists) + @@ -1232,21 +1248,13 @@ template class mainImpl { (main_sel_op_dagasleft + main_sel_op_l2gasleft)) * (main_call_ptr - main_space_id)); tmp *= scaling_factor; - std::get<100>(evals) += tmp; - } - // Contribution 101 - { - Avm_DECLARE_VIEWS(101); - - auto tmp = ((main_sel_op_cmov + main_sel_op_jumpi) * (((main_id * main_inv) - FF(1)) + main_id_zero)); - tmp *= scaling_factor; std::get<101>(evals) += tmp; } // Contribution 102 { Avm_DECLARE_VIEWS(102); - auto tmp = (((main_sel_op_cmov + main_sel_op_jumpi) * main_id_zero) * (-main_inv + FF(1))); + auto tmp = ((main_sel_op_cmov + main_sel_op_jumpi) * (((main_id * main_inv) - FF(1)) + main_id_zero)); tmp *= scaling_factor; std::get<102>(evals) += tmp; } @@ -1254,7 +1262,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(103); - auto tmp = (main_sel_mov_ia_to_ic - (main_sel_op_mov + (main_sel_op_cmov * (-main_id_zero + FF(1))))); + auto tmp = (((main_sel_op_cmov + main_sel_op_jumpi) * main_id_zero) * (-main_inv + FF(1))); tmp *= scaling_factor; std::get<103>(evals) += tmp; } @@ -1262,7 +1270,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(104); - auto tmp = (main_sel_mov_ib_to_ic - (main_sel_op_cmov * main_id_zero)); + auto tmp = (main_sel_mov_ia_to_ic - (main_sel_op_mov + (main_sel_op_cmov * (-main_id_zero + FF(1))))); tmp *= scaling_factor; std::get<104>(evals) += tmp; } @@ -1270,7 +1278,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(105); - auto tmp = (main_sel_mov_ia_to_ic * (main_ia - main_ic)); + auto tmp = (main_sel_mov_ib_to_ic - (main_sel_op_cmov * main_id_zero)); tmp *= scaling_factor; std::get<105>(evals) += tmp; } @@ -1278,7 +1286,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(106); - auto tmp = (main_sel_mov_ib_to_ic * (main_ib - main_ic)); + auto tmp = (main_sel_mov_ia_to_ic * (main_ia - main_ic)); tmp *= scaling_factor; std::get<106>(evals) += tmp; } @@ -1286,7 +1294,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(107); - auto tmp = ((main_sel_op_mov + main_sel_op_cmov) * (main_r_in_tag - main_w_in_tag)); + auto tmp = (main_sel_mov_ib_to_ic * (main_ib - main_ic)); tmp *= scaling_factor; std::get<107>(evals) += tmp; } @@ -1294,6 +1302,14 @@ template class mainImpl { { Avm_DECLARE_VIEWS(108); + auto tmp = ((main_sel_op_mov + main_sel_op_cmov) * (main_r_in_tag - main_w_in_tag)); + tmp *= scaling_factor; + std::get<108>(evals) += tmp; + } + // Contribution 109 + { + Avm_DECLARE_VIEWS(109); + auto tmp = (main_sel_alu - ((((((((((((main_sel_op_add + main_sel_op_sub) + main_sel_op_mul) + main_sel_op_div) + main_sel_op_not) + @@ -1306,11 +1322,11 @@ template class mainImpl { (-main_tag_err + FF(1))) * (-main_op_err + FF(1)))); tmp *= scaling_factor; - std::get<108>(evals) += tmp; + std::get<109>(evals) += tmp; } - // Contribution 109 + // Contribution 110 { - Avm_DECLARE_VIEWS(109); + Avm_DECLARE_VIEWS(110); auto tmp = ((((((((((main_sel_op_add + main_sel_op_sub) + main_sel_op_mul) + main_sel_op_div) + main_sel_op_not) + @@ -1321,21 +1337,13 @@ template class mainImpl { main_sel_op_shl) * (main_alu_in_tag - main_r_in_tag)); tmp *= scaling_factor; - std::get<109>(evals) += tmp; - } - // Contribution 110 - { - Avm_DECLARE_VIEWS(110); - - auto tmp = (main_sel_op_cast * (main_alu_in_tag - main_w_in_tag)); - tmp *= scaling_factor; std::get<110>(evals) += tmp; } // Contribution 111 { Avm_DECLARE_VIEWS(111); - auto tmp = (main_sel_op_l2gasleft * (main_ia - main_l2_gas_remaining_shift)); + auto tmp = (main_sel_op_cast * (main_alu_in_tag - main_w_in_tag)); tmp *= scaling_factor; std::get<111>(evals) += tmp; } @@ -1343,7 +1351,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(112); - auto tmp = (main_sel_op_dagasleft * (main_ia - main_da_gas_remaining_shift)); + auto tmp = (main_sel_op_l2gasleft * (main_ia - main_l2_gas_remaining_shift)); tmp *= scaling_factor; std::get<112>(evals) += tmp; } @@ -1351,7 +1359,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(113); - auto tmp = (main_sel_op_sender * kernel_kernel_in_offset); + auto tmp = (main_sel_op_dagasleft * (main_ia - main_da_gas_remaining_shift)); tmp *= scaling_factor; std::get<113>(evals) += tmp; } @@ -1367,7 +1375,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(115); - auto tmp = (main_sel_op_storage_address * (kernel_kernel_in_offset - FF(2))); + auto tmp = (main_sel_op_storage_address * (kernel_kernel_in_offset - FF(1))); tmp *= scaling_factor; std::get<115>(evals) += tmp; } @@ -1375,7 +1383,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(116); - auto tmp = (main_sel_op_fee_per_da_gas * (kernel_kernel_in_offset - FF(35))); + auto tmp = (main_sel_op_sender * kernel_kernel_in_offset); tmp *= scaling_factor; std::get<116>(evals) += tmp; } @@ -1383,7 +1391,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(117); - auto tmp = (main_sel_op_fee_per_l2_gas * (kernel_kernel_in_offset - FF(36))); + auto tmp = (main_sel_op_function_selector * (kernel_kernel_in_offset - FF(2))); tmp *= scaling_factor; std::get<117>(evals) += tmp; } @@ -1423,7 +1431,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(122); - auto tmp = (main_sel_op_coinbase * (kernel_kernel_in_offset - FF(33))); + auto tmp = (main_sel_op_timestamp * (kernel_kernel_in_offset - FF(32))); tmp *= scaling_factor; std::get<122>(evals) += tmp; } @@ -1431,7 +1439,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(123); - auto tmp = (main_sel_op_timestamp * (kernel_kernel_in_offset - FF(32))); + auto tmp = (main_sel_op_coinbase * (kernel_kernel_in_offset - FF(33))); tmp *= scaling_factor; std::get<123>(evals) += tmp; } @@ -1439,8 +1447,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(124); - auto tmp = (main_sel_op_note_hash_exists * - (kernel_kernel_out_offset - (kernel_note_hash_exist_write_offset + FF(0)))); + auto tmp = (main_sel_op_fee_per_da_gas * (kernel_kernel_in_offset - FF(35))); tmp *= scaling_factor; std::get<124>(evals) += tmp; } @@ -1448,7 +1455,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(125); - auto tmp = (main_sel_first * kernel_note_hash_exist_write_offset); + auto tmp = (main_sel_op_fee_per_l2_gas * (kernel_kernel_in_offset - FF(36))); tmp *= scaling_factor; std::get<125>(evals) += tmp; } @@ -1456,8 +1463,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(126); - auto tmp = (main_sel_op_emit_note_hash * - (kernel_kernel_out_offset - (kernel_emit_note_hash_write_offset + FF(176)))); + auto tmp = (main_sel_op_note_hash_exists * + (kernel_kernel_out_offset - (kernel_note_hash_exist_write_offset + FF(0)))); tmp *= scaling_factor; std::get<126>(evals) += tmp; } @@ -1465,7 +1472,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(127); - auto tmp = (main_sel_first * kernel_emit_note_hash_write_offset); + auto tmp = (main_sel_first * kernel_note_hash_exist_write_offset); tmp *= scaling_factor; std::get<127>(evals) += tmp; } @@ -1473,10 +1480,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(128); - auto tmp = (main_sel_op_nullifier_exists * - (kernel_kernel_out_offset - - ((main_ib * (kernel_nullifier_exists_write_offset + FF(32))) + - ((-main_ib + FF(1)) * (kernel_nullifier_non_exists_write_offset + FF(64)))))); + auto tmp = (main_sel_op_emit_note_hash * + (kernel_kernel_out_offset - (kernel_emit_note_hash_write_offset + FF(176)))); tmp *= scaling_factor; std::get<128>(evals) += tmp; } @@ -1484,7 +1489,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(129); - auto tmp = (main_sel_first * kernel_nullifier_exists_write_offset); + auto tmp = (main_sel_first * kernel_emit_note_hash_write_offset); tmp *= scaling_factor; std::get<129>(evals) += tmp; } @@ -1492,7 +1497,10 @@ template class mainImpl { { Avm_DECLARE_VIEWS(130); - auto tmp = (main_sel_first * kernel_nullifier_non_exists_write_offset); + auto tmp = (main_sel_op_nullifier_exists * + (kernel_kernel_out_offset - + ((main_ib * (kernel_nullifier_exists_write_offset + FF(32))) + + ((-main_ib + FF(1)) * (kernel_nullifier_non_exists_write_offset + FF(64)))))); tmp *= scaling_factor; std::get<130>(evals) += tmp; } @@ -1500,8 +1508,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(131); - auto tmp = (main_sel_op_emit_nullifier * - (kernel_kernel_out_offset - (kernel_emit_nullifier_write_offset + FF(192)))); + auto tmp = (main_sel_first * kernel_nullifier_exists_write_offset); tmp *= scaling_factor; std::get<131>(evals) += tmp; } @@ -1509,7 +1516,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(132); - auto tmp = (main_sel_first * kernel_emit_nullifier_write_offset); + auto tmp = (main_sel_first * kernel_nullifier_non_exists_write_offset); tmp *= scaling_factor; std::get<132>(evals) += tmp; } @@ -1517,8 +1524,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(133); - auto tmp = (main_sel_op_l1_to_l2_msg_exists * - (kernel_kernel_out_offset - (kernel_l1_to_l2_msg_exists_write_offset + FF(96)))); + auto tmp = (main_sel_op_emit_nullifier * + (kernel_kernel_out_offset - (kernel_emit_nullifier_write_offset + FF(192)))); tmp *= scaling_factor; std::get<133>(evals) += tmp; } @@ -1526,7 +1533,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(134); - auto tmp = (main_sel_first * kernel_l1_to_l2_msg_exists_write_offset); + auto tmp = (main_sel_first * kernel_emit_nullifier_write_offset); tmp *= scaling_factor; std::get<134>(evals) += tmp; } @@ -1534,8 +1541,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(135); - auto tmp = (main_sel_op_emit_unencrypted_log * - (kernel_kernel_out_offset - (kernel_emit_unencrypted_log_write_offset + FF(210)))); + auto tmp = (main_sel_op_l1_to_l2_msg_exists * + (kernel_kernel_out_offset - (kernel_l1_to_l2_msg_exists_write_offset + FF(96)))); tmp *= scaling_factor; std::get<135>(evals) += tmp; } @@ -1543,7 +1550,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(136); - auto tmp = (main_sel_first * kernel_emit_unencrypted_log_write_offset); + auto tmp = (main_sel_first * kernel_l1_to_l2_msg_exists_write_offset); tmp *= scaling_factor; std::get<136>(evals) += tmp; } @@ -1551,8 +1558,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(137); - auto tmp = (main_sel_op_emit_l2_to_l1_msg * - (kernel_kernel_out_offset - (kernel_emit_l2_to_l1_msg_write_offset + FF(208)))); + auto tmp = (main_sel_op_emit_unencrypted_log * + (kernel_kernel_out_offset - (kernel_emit_unencrypted_log_write_offset + FF(210)))); tmp *= scaling_factor; std::get<137>(evals) += tmp; } @@ -1560,7 +1567,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(138); - auto tmp = (main_sel_first * kernel_emit_l2_to_l1_msg_write_offset); + auto tmp = (main_sel_first * kernel_emit_unencrypted_log_write_offset); tmp *= scaling_factor; std::get<138>(evals) += tmp; } @@ -1568,7 +1575,8 @@ template class mainImpl { { Avm_DECLARE_VIEWS(139); - auto tmp = (main_sel_op_sload * (kernel_kernel_out_offset - (kernel_sload_write_offset + FF(144)))); + auto tmp = (main_sel_op_emit_l2_to_l1_msg * + (kernel_kernel_out_offset - (kernel_emit_l2_to_l1_msg_write_offset + FF(208)))); tmp *= scaling_factor; std::get<139>(evals) += tmp; } @@ -1576,7 +1584,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(140); - auto tmp = (main_sel_first * kernel_sload_write_offset); + auto tmp = (main_sel_first * kernel_emit_l2_to_l1_msg_write_offset); tmp *= scaling_factor; std::get<140>(evals) += tmp; } @@ -1584,7 +1592,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(141); - auto tmp = (main_sel_op_sstore * (kernel_kernel_out_offset - (kernel_sstore_write_offset + FF(112)))); + auto tmp = (main_sel_op_sload * (kernel_kernel_out_offset - (kernel_sload_write_offset + FF(144)))); tmp *= scaling_factor; std::get<141>(evals) += tmp; } @@ -1592,7 +1600,7 @@ template class mainImpl { { Avm_DECLARE_VIEWS(142); - auto tmp = (main_sel_first * kernel_sstore_write_offset); + auto tmp = (main_sel_first * kernel_sload_write_offset); tmp *= scaling_factor; std::get<142>(evals) += tmp; } @@ -1600,6 +1608,22 @@ template class mainImpl { { Avm_DECLARE_VIEWS(143); + auto tmp = (main_sel_op_sstore * (kernel_kernel_out_offset - (kernel_sstore_write_offset + FF(112)))); + tmp *= scaling_factor; + std::get<143>(evals) += tmp; + } + // Contribution 144 + { + Avm_DECLARE_VIEWS(144); + + auto tmp = (main_sel_first * kernel_sstore_write_offset); + tmp *= scaling_factor; + std::get<144>(evals) += tmp; + } + // Contribution 145 + { + Avm_DECLARE_VIEWS(145); + auto tmp = (((((((main_sel_op_note_hash_exists + main_sel_op_emit_note_hash) + main_sel_op_nullifier_exists) + main_sel_op_emit_nullifier) + @@ -1608,23 +1632,23 @@ template class mainImpl { main_sel_op_emit_l2_to_l1_msg) * (kernel_side_effect_counter_shift - (kernel_side_effect_counter + FF(1)))); tmp *= scaling_factor; - std::get<143>(evals) += tmp; + std::get<145>(evals) += tmp; } - // Contribution 144 + // Contribution 146 { - Avm_DECLARE_VIEWS(144); + Avm_DECLARE_VIEWS(146); auto tmp = (main_bin_op_id - (main_sel_op_or + (main_sel_op_xor * FF(2)))); tmp *= scaling_factor; - std::get<144>(evals) += tmp; + std::get<146>(evals) += tmp; } - // Contribution 145 + // Contribution 147 { - Avm_DECLARE_VIEWS(145); + Avm_DECLARE_VIEWS(147); auto tmp = (main_sel_bin - ((main_sel_op_and + main_sel_op_or) + main_sel_op_xor)); tmp *= scaling_factor; - std::get<145>(evals) += tmp; + std::get<147>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index f3908d89e2b..1663491d3ab 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -57,89 +57,84 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::SHR, three_operand_format }, // Compute - Type Conversions { OpCode::CAST, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, + // Execution Environment - Globals { OpCode::ADDRESS, getter_format }, { OpCode::STORAGEADDRESS, getter_format }, { OpCode::SENDER, getter_format }, - { OpCode::FEEPERL2GAS, getter_format }, - { OpCode::FEEPERDAGAS, getter_format }, + { OpCode::FUNCTIONSELECTOR, getter_format }, { OpCode::TRANSACTIONFEE, getter_format }, - - { OpCode::GETCONTRACTINSTANCE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, - // TODO: ordering inline with spec - { OpCode::EMITNOTEHASH, - { - OperandType::INDIRECT, - OperandType::UINT32, - } }, // TODO: new format for these - { OpCode::EMITNULLIFIER, - { - OperandType::INDIRECT, - OperandType::UINT32, - } }, // TODO: new format for these - { OpCode::EMITUNENCRYPTEDLOG, - { - OperandType::INDIRECT, - OperandType::UINT32, - OperandType::UINT32, - } }, - { OpCode::SENDL2TOL1MSG, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, - { OpCode::SLOAD, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, - { OpCode::SSTORE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, - /*TODO: leafIndexOffset is not constrained*/ - { OpCode::NOTEHASHEXISTS, - { OperandType::INDIRECT, - OperandType::UINT32, - /*TODO: leafIndexOffset is not constrained*/ OperandType::UINT32, - OperandType::UINT32 } }, - - { OpCode::NULLIFIEREXISTS, - { OperandType::INDIRECT, - OperandType::UINT32, - /*TODO: Address is not constrained*/ OperandType::UINT32, - OperandType::UINT32 } }, - { OpCode::L1TOL2MSGEXISTS, - { OperandType::INDIRECT, - OperandType::UINT32, - /*TODO: leafIndexOffset is not constrained*/ OperandType::UINT32, - OperandType::UINT32 } }, - // CONTRACTCALLDEPTH, -- not in simulator // Execution Environment - Globals { OpCode::CHAINID, getter_format }, { OpCode::VERSION, getter_format }, { OpCode::BLOCKNUMBER, getter_format }, - { OpCode::TIMESTAMP, getter_format }, // COINBASE, -- not in simulator + { OpCode::TIMESTAMP, getter_format }, + // Execution Environment - Globals - Gas + { OpCode::FEEPERL2GAS, getter_format }, + { OpCode::FEEPERDAGAS, getter_format }, // BLOCKL2GASLIMIT, -- not in simulator // BLOCKDAGASLIMIT, -- not in simulator + // // Execution Environment - Calldata { OpCode::CALLDATACOPY, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + // Machine State - Gas { OpCode::L2GASLEFT, getter_format }, { OpCode::DAGASLEFT, getter_format }, + // Machine State - Internal Control Flow { OpCode::JUMP, { OperandType::UINT32 } }, { OpCode::JUMPI, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::INTERNALCALL, { OperandType::UINT32 } }, { OpCode::INTERNALRETURN, {} }, + // Machine State - Memory // OpCode::SET is handled differently { OpCode::MOV, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::CMOV, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, - // World State - // SLOAD, - // SSTORE, - // NOTEHASHEXISTS, - // EMITNOTEHASH, - // NULLIFIEREXISTS, - // EMITNULLIFIER, - // L1TOL2MSGEXISTS, - // HEADERMEMBER, - // GETCONTRACTINSTANCE, - // Accrued Substate - // EMITUNENCRYPTEDLOG, - // SENDL2TOL1MSG, + + // Side Effects - Public Storage + { OpCode::SLOAD, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + { OpCode::SSTORE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + // Side Effects - Notes, Nullfiers, Logs, Messages + { OpCode::NOTEHASHEXISTS, + { OperandType::INDIRECT, + OperandType::UINT32, + /*TODO: leafIndexOffset is not constrained*/ OperandType::UINT32, + OperandType::UINT32 } }, + + { OpCode::EMITNOTEHASH, + { + OperandType::INDIRECT, + OperandType::UINT32, + } }, // TODO: new format for these + { OpCode::NULLIFIEREXISTS, + { OperandType::INDIRECT, + OperandType::UINT32, + /*TODO: Address is not constrained*/ OperandType::UINT32, + OperandType::UINT32 } }, + { OpCode::EMITNULLIFIER, + { + OperandType::INDIRECT, + OperandType::UINT32, + } }, // TODO: new format for these + /*TODO: leafIndexOffset is not constrained*/ + { OpCode::L1TOL2MSGEXISTS, + { OperandType::INDIRECT, + OperandType::UINT32, + /*TODO: leafIndexOffset is not constrained*/ OperandType::UINT32, + OperandType::UINT32 } }, + { OpCode::GETCONTRACTINSTANCE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, + { OpCode::EMITUNENCRYPTEDLOG, + { + OperandType::INDIRECT, + OperandType::UINT32, + OperandType::UINT32, + } }, + { OpCode::SENDL2TOL1MSG, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, + // Control Flow - Contract Calls { OpCode::CALL, external_call_format }, // STATICCALL, @@ -147,15 +142,13 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::RETURN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, // REVERT, { OpCode::REVERT, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, + // Misc { OpCode::DEBUGLOG, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + // Gadgets - // KECCAK, - // POSEIDON2, - // SHA256, - // PEDERSEN, - // Gadget - Hashing + // Gadgets - Hashing { OpCode::KECCAK, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::POSEIDON2, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::SHA256, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, @@ -176,6 +169,7 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = // Gadget - Conversion { OpCode::TORADIXLE, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + // Gadgets - Unused for now { OpCode::SHA256COMPRESSION, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index 79bc084ac06..fb59bdf1d6a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -133,19 +133,21 @@ VmPublicInputs Execution::convert_public_inputs(std::vector const& public_in std::array& kernel_inputs = std::get(public_inputs); - // Copy the call context items - kernel_inputs[SENDER_SELECTOR] = public_inputs_vec[SENDER_SELECTOR]; // Sender - kernel_inputs[ADDRESS_SELECTOR] = public_inputs_vec[ADDRESS_SELECTOR]; // Address + // Copy items from PublicCircuitPublicInputs vector to public input columns + // PublicCircuitPublicInputs - CallContext + kernel_inputs[SENDER_SELECTOR] = public_inputs_vec[SENDER_SELECTOR]; // Sender + // NOTE: address has same position as storage address (they are the same for now...) + // kernel_inputs[ADDRESS_SELECTOR] = public_inputs_vec[ADDRESS_SELECTOR]; // Address kernel_inputs[STORAGE_ADDRESS_SELECTOR] = public_inputs_vec[STORAGE_ADDRESS_SELECTOR]; // Storage Address + kernel_inputs[FUNCTION_SELECTOR_SELECTOR] = public_inputs_vec[FUNCTION_SELECTOR_SELECTOR]; - // Global variables + // PublicCircuitPublicInputs - GlobalVariables kernel_inputs[CHAIN_ID_SELECTOR] = public_inputs_vec[CHAIN_ID_OFFSET]; // Chain ID kernel_inputs[VERSION_SELECTOR] = public_inputs_vec[VERSION_OFFSET]; // Version kernel_inputs[BLOCK_NUMBER_SELECTOR] = public_inputs_vec[BLOCK_NUMBER_OFFSET]; // Block Number kernel_inputs[TIMESTAMP_SELECTOR] = public_inputs_vec[TIMESTAMP_OFFSET]; // Timestamp kernel_inputs[COINBASE_SELECTOR] = public_inputs_vec[COINBASE_OFFSET]; // Coinbase - - // Fees + // PublicCircuitPublicInputs - GlobalVariables - GasFees kernel_inputs[FEE_PER_DA_GAS_SELECTOR] = public_inputs_vec[FEE_PER_DA_GAS_OFFSET]; kernel_inputs[FEE_PER_L2_GAS_SELECTOR] = public_inputs_vec[FEE_PER_L2_GAS_OFFSET]; @@ -457,9 +459,6 @@ std::vector Execution::gen_trace(std::vector const& instructio trace_builder.op_dagasleft(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); break; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6284): support indirect for below - case OpCode::SENDER: - trace_builder.op_sender(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); - break; case OpCode::ADDRESS: trace_builder.op_address(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); break; @@ -467,13 +466,12 @@ std::vector Execution::gen_trace(std::vector const& instructio trace_builder.op_storage_address(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); break; - case OpCode::FEEPERL2GAS: - trace_builder.op_fee_per_l2_gas(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1))); + case OpCode::SENDER: + trace_builder.op_sender(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); break; - case OpCode::FEEPERDAGAS: - trace_builder.op_fee_per_da_gas(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1))); + case OpCode::FUNCTIONSELECTOR: + trace_builder.op_function_selector(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); break; case OpCode::TRANSACTIONFEE: trace_builder.op_transaction_fee(std::get(inst.operands.at(0)), @@ -495,6 +493,14 @@ std::vector Execution::gen_trace(std::vector const& instructio case OpCode::TIMESTAMP: trace_builder.op_timestamp(std::get(inst.operands.at(0)), std::get(inst.operands.at(1))); break; + case OpCode::FEEPERL2GAS: + trace_builder.op_fee_per_l2_gas(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); + break; + case OpCode::FEEPERDAGAS: + trace_builder.op_fee_per_da_gas(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); + break; case OpCode::NOTEHASHEXISTS: trace_builder.op_note_hash_exists(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.cpp index 95aa16a1709..52fcc8c6d12 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.cpp @@ -49,11 +49,6 @@ void AvmKernelTraceBuilder::perform_kernel_output_lookup(uint32_t write_offset, // We want to be able to get the return value from the public inputs column // Get the return value, this will be places in ia // We read from the public inputs that were provided to the kernel -FF AvmKernelTraceBuilder::op_sender() -{ - return perform_kernel_input_lookup(SENDER_SELECTOR); -} - FF AvmKernelTraceBuilder::op_address() { return perform_kernel_input_lookup(ADDRESS_SELECTOR); @@ -63,14 +58,14 @@ FF AvmKernelTraceBuilder::op_storage_address() return perform_kernel_input_lookup(STORAGE_ADDRESS_SELECTOR); } -FF AvmKernelTraceBuilder::op_fee_per_da_gas() +FF AvmKernelTraceBuilder::op_sender() { - return perform_kernel_input_lookup(FEE_PER_DA_GAS_SELECTOR); + return perform_kernel_input_lookup(SENDER_SELECTOR); } -FF AvmKernelTraceBuilder::op_fee_per_l2_gas() +FF AvmKernelTraceBuilder::op_function_selector() { - return perform_kernel_input_lookup(FEE_PER_L2_GAS_SELECTOR); + return perform_kernel_input_lookup(FUNCTION_SELECTOR_SELECTOR); } FF AvmKernelTraceBuilder::op_transaction_fee() @@ -103,6 +98,16 @@ FF AvmKernelTraceBuilder::op_timestamp() return perform_kernel_input_lookup(TIMESTAMP_SELECTOR); } +FF AvmKernelTraceBuilder::op_fee_per_da_gas() +{ + return perform_kernel_input_lookup(FEE_PER_DA_GAS_SELECTOR); +} + +FF AvmKernelTraceBuilder::op_fee_per_l2_gas() +{ + return perform_kernel_input_lookup(FEE_PER_L2_GAS_SELECTOR); +} + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6481): need to process hint from avm in order to know if // output should be set to true or not void AvmKernelTraceBuilder::op_note_hash_exists(uint32_t clk, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.hpp index a8c43f66046..b829ee1677f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_kernel_trace.hpp @@ -10,8 +10,11 @@ #include inline const uint32_t SENDER_SELECTOR = 0; +// address doesn't actually exist in PublicCircuitPublicInputs, but storageAddress does +// so we just make a address & storageAddress an alias of each other for now inline const uint32_t ADDRESS_SELECTOR = 1; -inline const uint32_t STORAGE_ADDRESS_SELECTOR = 2; +inline const uint32_t STORAGE_ADDRESS_SELECTOR = ADDRESS_SELECTOR; +inline const uint32_t FUNCTION_SELECTOR_SELECTOR = 2; inline const uint32_t START_GLOBAL_VARIABLES = CALL_CONTEXT_LENGTH + HEADER_LENGTH; @@ -20,21 +23,14 @@ inline const uint32_t VERSION_SELECTOR = START_GLOBAL_VARIABLES + 1; inline const uint32_t BLOCK_NUMBER_SELECTOR = START_GLOBAL_VARIABLES + 2; inline const uint32_t TIMESTAMP_SELECTOR = START_GLOBAL_VARIABLES + 3; inline const uint32_t COINBASE_SELECTOR = START_GLOBAL_VARIABLES + 4; +inline const uint32_t FEE_PER_DA_GAS_SELECTOR = START_GLOBAL_VARIABLES + 6; +inline const uint32_t FEE_PER_L2_GAS_SELECTOR = START_GLOBAL_VARIABLES + 7; inline const uint32_t END_GLOBAL_VARIABLES = START_GLOBAL_VARIABLES + GLOBAL_VARIABLES_LENGTH; inline const uint32_t START_SIDE_EFFECT_COUNTER = END_GLOBAL_VARIABLES; -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6715): update these to come from the global inputs -inline const uint32_t FEE_PER_DA_GAS_SELECTOR = START_GLOBAL_VARIABLES + 6; -inline const uint32_t FEE_PER_L2_GAS_SELECTOR = START_GLOBAL_VARIABLES + 7; inline const uint32_t TRANSACTION_FEE_SELECTOR = KERNEL_INPUTS_LENGTH - 1; -const std::array KERNEL_INPUTS_SELECTORS = { - SENDER_SELECTOR, ADDRESS_SELECTOR, STORAGE_ADDRESS_SELECTOR, FEE_PER_DA_GAS_SELECTOR, - FEE_PER_L2_GAS_SELECTOR, TRANSACTION_FEE_SELECTOR, CHAIN_ID_SELECTOR, VERSION_SELECTOR, - BLOCK_NUMBER_SELECTOR, COINBASE_SELECTOR, TIMESTAMP_SELECTOR -}; - namespace bb::avm_trace { class AvmKernelTraceBuilder { @@ -75,13 +71,10 @@ class AvmKernelTraceBuilder { std::vector finalize(); // Context - FF op_sender(); FF op_address(); FF op_storage_address(); - - // Fees - FF op_fee_per_da_gas(); - FF op_fee_per_l2_gas(); + FF op_sender(); + FF op_function_selector(); FF op_transaction_fee(); // Globals @@ -90,19 +83,21 @@ class AvmKernelTraceBuilder { FF op_block_number(); FF op_coinbase(); FF op_timestamp(); + // Globals - Gas + FF op_fee_per_da_gas(); + FF op_fee_per_l2_gas(); // Outputs // Each returns the selector that was used + void op_sload(uint32_t clk, uint32_t side_effect_counter, const FF& slot, const FF& value); + void op_sstore(uint32_t clk, uint32_t side_effect_counter, const FF& slot, const FF& value); void op_note_hash_exists(uint32_t clk, uint32_t side_effect_counter, const FF& note_hash, uint32_t result); void op_emit_note_hash(uint32_t clk, uint32_t side_effect_counter, const FF& note_hash); void op_nullifier_exists(uint32_t clk, uint32_t side_effect_counter, const FF& nullifier, uint32_t result); void op_emit_nullifier(uint32_t clk, uint32_t side_effect_counter, const FF& nullifier); void op_l1_to_l2_msg_exists(uint32_t clk, uint32_t side_effect_counter, const FF& message, uint32_t result); void op_emit_unencrypted_log(uint32_t clk, uint32_t side_effect_counter, const FF& log_hash); - void op_emit_l2_to_l1_msg(uint32_t clk, uint32_t side_effect_counter, const FF& message, const FF& recipient); - - void op_sload(uint32_t clk, uint32_t side_effect_counter, const FF& slot, const FF& value); - void op_sstore(uint32_t clk, uint32_t side_effect_counter, const FF& slot, const FF& value); + void op_emit_l2_to_l1_msg(uint32_t clk, uint32_t side_effect_counter, const FF& l2_to_l1_msg, const FF& recipient); // TODO: Move into constants.hpp? static const uint32_t START_NOTE_HASH_EXISTS_WRITE_OFFSET = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp index 2439fd4e0a2..f137128d9f0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.cpp @@ -60,14 +60,10 @@ std::string to_string(OpCode opcode) return "STORAGEADDRESS"; case OpCode::SENDER: return "SENDER"; - case OpCode::FEEPERL2GAS: - return "FEEPERL2GAS"; - case OpCode::FEEPERDAGAS: - return "FEEPERDAGAS"; + case OpCode::FUNCTIONSELECTOR: + return "FUNCTIONSELECTOR"; case OpCode::TRANSACTIONFEE: return "TRANSACTIONFEE"; - case OpCode::CONTRACTCALLDEPTH: - return "CONTRACTCALLDEPTH"; case OpCode::CHAINID: return "CHAINID"; case OpCode::VERSION: @@ -78,6 +74,10 @@ std::string to_string(OpCode opcode) return "TIMESTAMP"; case OpCode::COINBASE: return "COINBASE"; + case OpCode::FEEPERL2GAS: + return "FEEPERL2GAS"; + case OpCode::FEEPERDAGAS: + return "FEEPERDAGAS"; case OpCode::BLOCKL2GASLIMIT: return "BLOCKL2GASLIMIT"; case OpCode::BLOCKDAGASLIMIT: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp index e3ced1a03e7..f2beb29d32f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_opcode.hpp @@ -45,16 +45,16 @@ enum class OpCode : uint8_t { ADDRESS, STORAGEADDRESS, SENDER, - FEEPERL2GAS, - FEEPERDAGAS, + FUNCTIONSELECTOR, TRANSACTIONFEE, - CONTRACTCALLDEPTH, // Execution Environment - Globals CHAINID, VERSION, BLOCKNUMBER, TIMESTAMP, COINBASE, + FEEPERL2GAS, + FEEPERDAGAS, BLOCKL2GASLIMIT, BLOCKDAGASLIMIT, // Execution Environment - Calldata diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp index 477775e22b4..55b22de128d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1188,6 +1188,18 @@ Row AvmTraceBuilder::create_kernel_lookup_opcode( }; } +void AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset) +{ + FF ia_value = kernel_trace_builder.op_address(); + Row row = create_kernel_lookup_opcode(indirect, dst_offset, ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF); + row.main_sel_op_address = FF(1); + + // Constrain gas cost + gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::ADDRESS); + + main_trace.push_back(row); +} + void AvmTraceBuilder::op_storage_address(uint8_t indirect, uint32_t dst_offset) { FF ia_value = kernel_trace_builder.op_storage_address(); @@ -1212,38 +1224,15 @@ void AvmTraceBuilder::op_sender(uint8_t indirect, uint32_t dst_offset) main_trace.push_back(row); } -void AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset) -{ - FF ia_value = kernel_trace_builder.op_address(); - Row row = create_kernel_lookup_opcode(indirect, dst_offset, ADDRESS_SELECTOR, ia_value, AvmMemoryTag::FF); - row.main_sel_op_address = FF(1); - - // Constrain gas cost - gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::ADDRESS); - - main_trace.push_back(row); -} - -void AvmTraceBuilder::op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset) -{ - FF ia_value = kernel_trace_builder.op_fee_per_da_gas(); - Row row = create_kernel_lookup_opcode(indirect, dst_offset, FEE_PER_DA_GAS_SELECTOR, ia_value, AvmMemoryTag::FF); - row.main_sel_op_fee_per_da_gas = FF(1); - - // Constrain gas cost - gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::FEEPERDAGAS); - - main_trace.push_back(row); -} - -void AvmTraceBuilder::op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset) +void AvmTraceBuilder::op_function_selector(uint8_t indirect, uint32_t dst_offset) { - FF ia_value = kernel_trace_builder.op_fee_per_l2_gas(); - Row row = create_kernel_lookup_opcode(indirect, dst_offset, FEE_PER_L2_GAS_SELECTOR, ia_value, AvmMemoryTag::FF); - row.main_sel_op_fee_per_l2_gas = FF(1); + FF ia_value = kernel_trace_builder.op_function_selector(); + Row row = + create_kernel_lookup_opcode(indirect, dst_offset, FUNCTION_SELECTOR_SELECTOR, ia_value, AvmMemoryTag::U32); + row.main_sel_op_function_selector = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::FEEPERL2GAS); + gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::FUNCTIONSELECTOR); main_trace.push_back(row); } @@ -1320,6 +1309,30 @@ void AvmTraceBuilder::op_timestamp(uint8_t indirect, uint32_t dst_offset) main_trace.push_back(row); } +void AvmTraceBuilder::op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset) +{ + FF ia_value = kernel_trace_builder.op_fee_per_da_gas(); + Row row = create_kernel_lookup_opcode(indirect, dst_offset, FEE_PER_DA_GAS_SELECTOR, ia_value, AvmMemoryTag::FF); + row.main_sel_op_fee_per_da_gas = FF(1); + + // Constrain gas cost + gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::FEEPERDAGAS); + + main_trace.push_back(row); +} + +void AvmTraceBuilder::op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset) +{ + FF ia_value = kernel_trace_builder.op_fee_per_l2_gas(); + Row row = create_kernel_lookup_opcode(indirect, dst_offset, FEE_PER_L2_GAS_SELECTOR, ia_value, AvmMemoryTag::FF); + row.main_sel_op_fee_per_l2_gas = FF(1); + + // Constrain gas cost + gas_trace_builder.constrain_gas_lookup(static_cast(row.main_clk), OpCode::FEEPERL2GAS); + + main_trace.push_back(row); +} + // Helper function to add kernel lookup operations into the main trace Row AvmTraceBuilder::create_kernel_output_opcode(uint8_t indirect, uint32_t clk, uint32_t data_offset) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index 3baf3ce50d2..307943c8940 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -49,124 +49,99 @@ class AvmTraceBuilder { // Addition with direct or indirect memory access. void op_add(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Subtraction with direct or indirect memory access. void op_sub(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Multiplication with direct or indirect memory access. void op_mul(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - + // Integer Division with direct or indirect memory access. + void op_div(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); // Finite field division with direct or indirect memory access. void op_fdiv(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset); - // Bitwise not with direct or indirect memory access. - void op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Equality with direct or indirect memory access. void op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Less Than with direct or indirect memory access. + void op_lt(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Less Than or Equal to with direct or indirect memory access. + void op_lte(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); // Bitwise and with direct or indirect memory access. void op_and(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Bitwise or with direct or indirect memory access. void op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Bitwise xor with direct or indirect memory access. void op_xor(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - - // Less Than with direct or indirect memory access. - void op_lt(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - - // Less Than or Equal to with direct or indirect memory access. - void op_lte(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - - // Shift Right with direct or indirect memory access. - void op_shr(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - + // Bitwise not with direct or indirect memory access. + void op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag in_tag); // Shift Left with direct or indirect memory access. void op_shl(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Shift Right with direct or indirect memory access. + void op_shr(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - // Set a constant from bytecode with direct or indirect memory access. - void op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); - - // Move (copy) the value and tag of a memory cell to another one. - void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset); - - // Move (copy) the value and tag of a memory cell to another one whereby the source - // is determined conditionally based on a conditional value determined by cond_offset. - void op_cmov(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t cond_offset, uint32_t dst_offset); + // Cast an element pointed by the address a_offset into type specified by dst_tag and + // store the result in address given by dst_offset. + void op_cast(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag dst_tag); - // Call Context - void op_storage_address(uint8_t indirect, uint32_t dst_offset); + // Context - Environment void op_sender(uint8_t indirect, uint32_t dst_offset); void op_address(uint8_t indirect, uint32_t dst_offset); - - // Fees - void op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset); - void op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset); + void op_storage_address(uint8_t indirect, uint32_t dst_offset); void op_transaction_fee(uint8_t indirect, uint32_t dst_offset); + void op_function_selector(uint8_t indirect, uint32_t dst_offset); - // Globals + // Context - Environment - Globals void op_chain_id(uint8_t indirect, uint32_t dst_offset); void op_version(uint8_t indirect, uint32_t dst_offset); void op_block_number(uint8_t indirect, uint32_t dst_offset); void op_coinbase(uint8_t indirect, uint32_t dst_offset); void op_timestamp(uint8_t indirect, uint32_t dst_offset); + // Context - Environment - Globals - Gas + void op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset); + void op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offset); - // Outputs - // With single output values - void op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset); - void op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset); - void op_emit_unencrypted_log(uint8_t indirect, uint32_t log_offset, uint32_t log_size_offset); - void op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset); - void op_get_contract_instance(uint8_t indirect, uint32_t address_offset, uint32_t dst_offset); - - // With additional metadata output - void op_l1_to_l2_msg_exists(uint8_t indirect, uint32_t log_offset, uint32_t dest_offset); - void op_note_hash_exists(uint8_t indirect, uint32_t note_hash_offset, uint32_t dest_offset); - void op_nullifier_exists(uint8_t indirect, uint32_t nullifier_offset, uint32_t dest_offset); - - void op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset); - void op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset); - - // Cast an element pointed by the address a_offset into type specified by dst_tag and - // store the result in address given by dst_offset. - void op_cast(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag dst_tag); - - // Integer Division with direct or indirect memory access. - void op_div(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Context - Environment - Calldata + // CALLDATACOPY opcode with direct/indirect memory access, i.e., + // direct: M[dst_offset:dst_offset+copy_size] = calldata[cd_offset:cd_offset+copy_size] + // indirect: M[M[dst_offset]:M[dst_offset]+copy_size] = calldata[cd_offset:cd_offset+copy_size] + void op_calldata_copy(uint8_t indirect, uint32_t cd_offset, uint32_t copy_size, uint32_t dst_offset); - // Machine State - Gas + // Context - Machine State - Gas void op_l2gasleft(uint8_t indirect, uint32_t dst_offset); void op_dagasleft(uint8_t indirect, uint32_t dst_offset); // Jump to a given program counter. void op_jump(uint32_t jmp_dest); - // Jump conditionally to a given program counter. void op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t cond_offset); - // Jump to a given program counter; storing the return location on a call stack. // TODO(md): this program counter MUST be an operand to the OPCODE. void op_internal_call(uint32_t jmp_dest); - - // Return from a jump. + // Return from an internal call. void op_internal_return(); - // Halt -> stop program execution. - void halt(); + // Set a constant from bytecode with direct or indirect memory access. + void op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); + // Move (copy) the value and tag of a memory cell to another one. + void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset); + // Move (copy) the value and tag of a memory cell to another one whereby the source + // is determined conditionally based on a conditional value determined by cond_offset. + void op_cmov(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t cond_offset, uint32_t dst_offset); - // CALLDATACOPY opcode with direct/indirect memory access, i.e., - // direct: M[dst_offset:dst_offset+copy_size] = calldata[cd_offset:cd_offset+copy_size] - // indirect: M[M[dst_offset]:M[dst_offset]+copy_size] = calldata[cd_offset:cd_offset+copy_size] - void op_calldata_copy(uint8_t indirect, uint32_t cd_offset, uint32_t copy_size, uint32_t dst_offset); + // Side Effects - Public Storage + void op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset); + void op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset); - // REVERT Opcode (that just call return under the hood for now) - std::vector op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size); - // RETURN opcode with direct and indirect memory access, i.e., - // direct: return(M[ret_offset:ret_offset+ret_size]) - // indirect: return(M[M[ret_offset]:M[ret_offset]+ret_size]) - std::vector op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size); + // With single output values + void op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset); + void op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset); + void op_emit_unencrypted_log(uint8_t indirect, uint32_t log_offset, uint32_t log_size_offset); + void op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset); + void op_get_contract_instance(uint8_t indirect, uint32_t address_offset, uint32_t dst_offset); + + // With additional metadata output + void op_l1_to_l2_msg_exists(uint8_t indirect, uint32_t log_offset, uint32_t dest_offset); + void op_note_hash_exists(uint8_t indirect, uint32_t note_hash_offset, uint32_t dest_offset); + void op_nullifier_exists(uint8_t indirect, uint32_t nullifier_offset, uint32_t dest_offset); // Calls void op_call(uint8_t indirect, @@ -179,6 +154,16 @@ class AvmTraceBuilder { uint32_t success_offset, uint32_t function_selector_offset); + // RETURN opcode with direct and indirect memory access, i.e., + // direct: return(M[ret_offset:ret_offset+ret_size]) + // indirect: return(M[M[ret_offset]:M[ret_offset]+ret_size]) + std::vector op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size); + // REVERT Opcode (that just call return under the hood for now) + std::vector op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size); + + // (not an opcode) Halt -> stop program execution. + void halt(); + // Gadgets // --- Conversions // To Radix LE conversion operation. diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/constants.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/constants.hpp index 4d60a7b0ad9..86c18af9fd9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/constants.hpp @@ -7,7 +7,7 @@ // NOTE(MD): for now we will only include the public inputs that are included in call_context // With more being added in subsequent prs -// KERNEL_INPUTS_LENGTH = CALL_CONTEXT_LENGTH + +// KERNEL_INPUTS_LENGTH = CALL_CONTEXT_LENGTH inline const std::size_t KERNEL_INPUTS_LENGTH = PUBLIC_CONTEXT_INPUTS_LENGTH; inline const std::size_t KERNEL_OUTPUTS_LENGTH = @@ -21,22 +21,24 @@ inline const std::size_t KERNEL_OUTPUTS_LENGTH = // https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts inline const uint32_t PCPI_GLOBALS_START = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 7 - GLOBAL_VARIABLES_LENGTH; +// Global Variables inline const uint32_t CHAIN_ID_OFFSET = PCPI_GLOBALS_START; inline const uint32_t VERSION_OFFSET = PCPI_GLOBALS_START + 1; inline const uint32_t BLOCK_NUMBER_OFFSET = PCPI_GLOBALS_START + 2; inline const uint32_t TIMESTAMP_OFFSET = PCPI_GLOBALS_START + 3; inline const uint32_t COINBASE_OFFSET = PCPI_GLOBALS_START + 4; - +// Global Variables - fees inline const uint32_t FEE_PER_DA_GAS_OFFSET = PCPI_GLOBALS_START + 6; inline const uint32_t FEE_PER_L2_GAS_OFFSET = PCPI_GLOBALS_START + 7; -inline const uint32_t TRANSACTION_FEE_OFFSET = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 1; +// Top-level PublicCircuitPublicInputs members inline const uint32_t DA_START_GAS_LEFT_PCPI_OFFSET = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 3 - GAS_LENGTH; inline const uint32_t L2_START_GAS_LEFT_PCPI_OFFSET = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 2 - GAS_LENGTH; +inline const uint32_t TRANSACTION_FEE_OFFSET = PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH - 1; // Kernel output pil offset (Where update objects are inlined) -// Kernel outputs public inputs offsets +// Side Effects (offsets to vectors in PublicCircuitPublicInputs) inline const uint32_t PCPI_NOTE_HASH_EXISTS_OFFSET = CALL_CONTEXT_LENGTH + 2; inline const uint32_t PCPI_NULLIFIER_EXISTS_OFFSET = PCPI_NOTE_HASH_EXISTS_OFFSET + (MAX_NOTE_HASH_READ_REQUESTS_PER_CALL * READ_REQUEST_LENGTH); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.cpp index 5ccb624b528..a1194d51e98 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.cpp @@ -221,6 +221,7 @@ template std::vector AvmFullRow::names() "main_sel_op_fdiv", "main_sel_op_fee_per_da_gas", "main_sel_op_fee_per_l2_gas", + "main_sel_op_function_selector", "main_sel_op_get_contract_instance", "main_sel_op_halt", "main_sel_op_internal_call", @@ -520,6 +521,7 @@ template std::ostream& operator<<(std::ostream& os, AvmFullRow << "," << field_to_string(row.main_sel_op_external_call) << "," << field_to_string(row.main_sel_op_fdiv) << "," << field_to_string(row.main_sel_op_fee_per_da_gas) << "," << field_to_string(row.main_sel_op_fee_per_l2_gas) << "," + << field_to_string(row.main_sel_op_function_selector) << "," << field_to_string(row.main_sel_op_get_contract_instance) << "," << field_to_string(row.main_sel_op_halt) << "," << field_to_string(row.main_sel_op_internal_call) << "," << field_to_string(row.main_sel_op_internal_return) << "," << field_to_string(row.main_sel_op_jump) << "," diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index b0acd7a8bac..6508ba7d465 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -290,6 +290,7 @@ template struct AvmFullRow { FF main_sel_op_fdiv{}; FF main_sel_op_fee_per_da_gas{}; FF main_sel_op_fee_per_l2_gas{}; + FF main_sel_op_function_selector{}; FF main_sel_op_get_contract_instance{}; FF main_sel_op_halt{}; FF main_sel_op_internal_call{}; @@ -554,8 +555,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 451; - static constexpr size_t num_polys = 386; + static constexpr size_t num_fixed_columns = 452; + static constexpr size_t num_polys = 387; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -775,6 +776,7 @@ class AvmCircuitBuilder { polys.main_sel_op_fdiv[i] = rows[i].main_sel_op_fdiv; polys.main_sel_op_fee_per_da_gas[i] = rows[i].main_sel_op_fee_per_da_gas; polys.main_sel_op_fee_per_l2_gas[i] = rows[i].main_sel_op_fee_per_l2_gas; + polys.main_sel_op_function_selector[i] = rows[i].main_sel_op_function_selector; polys.main_sel_op_get_contract_instance[i] = rows[i].main_sel_op_get_contract_instance; polys.main_sel_op_halt[i] = rows[i].main_sel_op_halt; polys.main_sel_op_internal_call[i] = rows[i].main_sel_op_internal_call; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 0d33acf8c1d..c29a3b0212a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -100,11 +100,11 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 384; + static constexpr size_t NUM_WITNESS_ENTITIES = 385; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 451; + static constexpr size_t NUM_ALL_ENTITIES = 452; using GrandProductRelations = std::tuple, perm_main_bin_relation, @@ -461,6 +461,7 @@ class AvmFlavor { main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, + main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_halt, main_sel_op_internal_call, @@ -848,6 +849,7 @@ class AvmFlavor { main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, + main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_halt, main_sel_op_internal_call, @@ -1240,6 +1242,7 @@ class AvmFlavor { main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, + main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_halt, main_sel_op_internal_call, @@ -1694,6 +1697,7 @@ class AvmFlavor { main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, + main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_halt, main_sel_op_internal_call, @@ -2148,6 +2152,7 @@ class AvmFlavor { main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, + main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_halt, main_sel_op_internal_call, @@ -2958,6 +2963,7 @@ class AvmFlavor { Base::main_sel_op_fdiv = "MAIN_SEL_OP_FDIV"; Base::main_sel_op_fee_per_da_gas = "MAIN_SEL_OP_FEE_PER_DA_GAS"; Base::main_sel_op_fee_per_l2_gas = "MAIN_SEL_OP_FEE_PER_L2_GAS"; + Base::main_sel_op_function_selector = "MAIN_SEL_OP_FUNCTION_SELECTOR"; Base::main_sel_op_get_contract_instance = "MAIN_SEL_OP_GET_CONTRACT_INSTANCE"; Base::main_sel_op_halt = "MAIN_SEL_OP_HALT"; Base::main_sel_op_internal_call = "MAIN_SEL_OP_INTERNAL_CALL"; @@ -3361,6 +3367,7 @@ class AvmFlavor { Commitment main_sel_op_fdiv; Commitment main_sel_op_fee_per_da_gas; Commitment main_sel_op_fee_per_l2_gas; + Commitment main_sel_op_function_selector; Commitment main_sel_op_get_contract_instance; Commitment main_sel_op_halt; Commitment main_sel_op_internal_call; @@ -3775,6 +3782,7 @@ class AvmFlavor { main_sel_op_fdiv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); main_sel_op_fee_per_da_gas = deserialize_from_buffer(Transcript::proof_data, num_frs_read); main_sel_op_fee_per_l2_gas = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + main_sel_op_function_selector = deserialize_from_buffer(Transcript::proof_data, num_frs_read); main_sel_op_get_contract_instance = deserialize_from_buffer(Transcript::proof_data, num_frs_read); main_sel_op_halt = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -4183,6 +4191,7 @@ class AvmFlavor { serialize_to_buffer(main_sel_op_fdiv, Transcript::proof_data); serialize_to_buffer(main_sel_op_fee_per_da_gas, Transcript::proof_data); serialize_to_buffer(main_sel_op_fee_per_l2_gas, Transcript::proof_data); + serialize_to_buffer(main_sel_op_function_selector, Transcript::proof_data); serialize_to_buffer(main_sel_op_get_contract_instance, Transcript::proof_data); serialize_to_buffer(main_sel_op_halt, Transcript::proof_data); serialize_to_buffer(main_sel_op_internal_call, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index 17c2e68976e..93ff4ac5989 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -270,6 +270,7 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.main_sel_op_fdiv = commitment_key->commit(key->main_sel_op_fdiv); witness_commitments.main_sel_op_fee_per_da_gas = commitment_key->commit(key->main_sel_op_fee_per_da_gas); witness_commitments.main_sel_op_fee_per_l2_gas = commitment_key->commit(key->main_sel_op_fee_per_l2_gas); + witness_commitments.main_sel_op_function_selector = commitment_key->commit(key->main_sel_op_function_selector); witness_commitments.main_sel_op_get_contract_instance = commitment_key->commit(key->main_sel_op_get_contract_instance); witness_commitments.main_sel_op_halt = commitment_key->commit(key->main_sel_op_halt); @@ -640,6 +641,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.main_sel_op_fee_per_da_gas); transcript->send_to_verifier(commitment_labels.main_sel_op_fee_per_l2_gas, witness_commitments.main_sel_op_fee_per_l2_gas); + transcript->send_to_verifier(commitment_labels.main_sel_op_function_selector, + witness_commitments.main_sel_op_function_selector); transcript->send_to_verifier(commitment_labels.main_sel_op_get_contract_instance, witness_commitments.main_sel_op_get_contract_instance); transcript->send_to_verifier(commitment_labels.main_sel_op_halt, witness_commitments.main_sel_op_halt); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index b341ba30e09..d15ad4f2fca 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -376,6 +376,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vectortemplate receive_from_prover(commitment_labels.main_sel_op_fee_per_da_gas); commitments.main_sel_op_fee_per_l2_gas = transcript->template receive_from_prover(commitment_labels.main_sel_op_fee_per_l2_gas); + commitments.main_sel_op_function_selector = + transcript->template receive_from_prover(commitment_labels.main_sel_op_function_selector); commitments.main_sel_op_get_contract_instance = transcript->template receive_from_prover(commitment_labels.main_sel_op_get_contract_instance); commitments.main_sel_op_halt = diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp index 6e9d749e6d4..21b9d2793cb 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp @@ -1322,133 +1322,148 @@ TEST_F(AvmExecutionTests, msmOpCode) // Positive test for Kernel Input opcodes TEST_F(AvmExecutionTests, kernelInputOpcodes) { - std::string bytecode_hex = to_hex(OpCode::SENDER) + // opcode SENDER - "00" // Indirect flag - "00000001" // dst_offset 1 - + to_hex(OpCode::ADDRESS) + // opcode ADDRESS - "00" // Indirect flag - "00000002" // dst_offset 2 - + to_hex(OpCode::STORAGEADDRESS) + // opcode STORAGEADDRESS - "00" // Indirect flag - "00000003" // dst_offset 3 - + to_hex(OpCode::FEEPERL2GAS) + // opcode FEEPERL2GAS - "00" // Indirect flag - "00000004" // dst_offset 4 - + to_hex(OpCode::FEEPERDAGAS) + // opcode FEEPERDAGAS - "00" // Indirect flag - "00000005" // dst_offset 5 - + to_hex(OpCode::TRANSACTIONFEE) + // opcode TRANSACTIONFEE - "00" // Indirect flag - "00000006" // dst_offset 6 - + to_hex(OpCode::CHAINID) + // opcode CHAINID - "00" // Indirect flag - "00000007" // dst_offset 7 - + to_hex(OpCode::VERSION) + // opcode VERSION - "00" // Indirect flag - "00000008" // dst_offset 8 - + to_hex(OpCode::BLOCKNUMBER) + // opcode BLOCKNUMBER - "00" // Indirect flag - "00000009" // dst_offset 9 - + to_hex(OpCode::TIMESTAMP) + // opcode TIMESTAMP - "00" // Indirect flag - "0000000a" // dst_offset 10 - // Not in simulator + std::string bytecode_hex = to_hex(OpCode::ADDRESS) + // opcode ADDRESS + "00" // Indirect flag + "00000001" // dst_offset + + to_hex(OpCode::STORAGEADDRESS) + // opcode STORAGEADDRESS + "00" // Indirect flag + "00000002" // dst_offset + + to_hex(OpCode::SENDER) + // opcode SENDER + "00" // Indirect flag + "00000003" // dst_offset + + to_hex(OpCode::FUNCTIONSELECTOR) + // opcode TRANSACTIONFEE + "00" // Indirect flag + "00000004" // dst_offset + + to_hex(OpCode::TRANSACTIONFEE) + // opcode TRANSACTIONFEE + "00" // Indirect flag + "00000005" // dst_offset + + to_hex(OpCode::CHAINID) + // opcode CHAINID + "00" // Indirect flag + "00000006" // dst_offset + + to_hex(OpCode::VERSION) + // opcode VERSION + "00" // Indirect flag + "00000007" // dst_offset + + to_hex(OpCode::BLOCKNUMBER) + // opcode BLOCKNUMBER + "00" // Indirect flag + "00000008" // dst_offset + + to_hex(OpCode::TIMESTAMP) + // opcode TIMESTAMP + "00" // Indirect flag + "00000009" // dst_offset + // Not in simulator // + to_hex(OpCode::COINBASE) + // opcode COINBASE // "00" // Indirect flag - // "0000000a" // dst_offset 10 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000001" // ret offset 1 - "0000000a"; // ret size 10 + // "00000009" // dst_offset + + to_hex(OpCode::FEEPERL2GAS) + // opcode FEEPERL2GAS + "00" // Indirect flag + "0000000a" // dst_offset + + to_hex(OpCode::FEEPERDAGAS) + // opcode FEEPERDAGAS + "00" // Indirect flag + "0000000b" // dst_offset + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000001" // ret offset 1 + "0000000b"; // ret size 11 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); - ASSERT_THAT(instructions, SizeIs(11)); + ASSERT_THAT(instructions, SizeIs(12)); - // SENDER + // ADDRESS EXPECT_THAT(instructions.at(0), - AllOf(Field(&Instruction::op_code, OpCode::SENDER), + AllOf(Field(&Instruction::op_code, OpCode::ADDRESS), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(1))))); - // ADDRESS + // STORAGEADDRESS EXPECT_THAT(instructions.at(1), - AllOf(Field(&Instruction::op_code, OpCode::ADDRESS), + AllOf(Field(&Instruction::op_code, OpCode::STORAGEADDRESS), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(2))))); - // STORAGEADDRESS + // SENDER EXPECT_THAT(instructions.at(2), - AllOf(Field(&Instruction::op_code, OpCode::STORAGEADDRESS), + AllOf(Field(&Instruction::op_code, OpCode::SENDER), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(3))))); - // FEEPERL2GAS + + // FUNCTIONSELECTOR EXPECT_THAT(instructions.at(3), - AllOf(Field(&Instruction::op_code, OpCode::FEEPERL2GAS), + AllOf(Field(&Instruction::op_code, OpCode::FUNCTIONSELECTOR), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(4))))); - // FEEPERDAGAS - EXPECT_THAT(instructions.at(4), - AllOf(Field(&Instruction::op_code, OpCode::FEEPERDAGAS), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(5))))); - // TRANSACTIONFEE - EXPECT_THAT(instructions.at(5), + EXPECT_THAT(instructions.at(4), AllOf(Field(&Instruction::op_code, OpCode::TRANSACTIONFEE), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(6))))); + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(5))))); // CHAINID - EXPECT_THAT(instructions.at(6), + EXPECT_THAT(instructions.at(5), AllOf(Field(&Instruction::op_code, OpCode::CHAINID), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(7))))); + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(6))))); // VERSION - EXPECT_THAT(instructions.at(7), + EXPECT_THAT(instructions.at(6), AllOf(Field(&Instruction::op_code, OpCode::VERSION), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(8))))); + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(7))))); // BLOCKNUMBER - EXPECT_THAT(instructions.at(8), + EXPECT_THAT(instructions.at(7), AllOf(Field(&Instruction::op_code, OpCode::BLOCKNUMBER), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(9))))); + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(8))))); // TIMESTAMP - EXPECT_THAT(instructions.at(9), + EXPECT_THAT(instructions.at(8), AllOf(Field(&Instruction::op_code, OpCode::TIMESTAMP), - Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(10))))); + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(9))))); // COINBASE // Not in simulator - // EXPECT_THAT(instructions.at(9), + // EXPECT_THAT(instructions.at(8), // AllOf(Field(&Instruction::op_code, OpCode::COINBASE), // Field(&Instruction::operands, ElementsAre(VariantWith(0), // VariantWith(10))))); + // FEEPERL2GAS + EXPECT_THAT(instructions.at(9), + AllOf(Field(&Instruction::op_code, OpCode::FEEPERL2GAS), + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(10))))); + + // FEEPERDAGAS + EXPECT_THAT(instructions.at(10), + AllOf(Field(&Instruction::op_code, OpCode::FEEPERDAGAS), + Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(11))))); + // Public inputs for the circuit std::vector calldata = {}; FF sender = 1; FF address = 2; - FF storage_address = 3; - FF feeperl2gas = 4; - FF feeperdagas = 5; - FF transactionfee = 6; - FF chainid = 7; - FF version = 8; - FF blocknumber = 9; - FF timestamp = 10; - // Not in simulator - // FF coinbase = 10; + // NOTE: address doesn't actually exist in public circuit public inputs, + // so storage address is just an alias of address for now + FF storage_address = address; + FF function_selector = 4; + FF transaction_fee = 5; + FF chainid = 6; + FF version = 7; + FF blocknumber = 8; + FF timestamp = 9; + // FF coinbase = 10; // Not in simulator + FF feeperl2gas = 10; + FF feeperdagas = 11; // The return data for this test should be a the opcodes in sequence, as the opcodes dst address lines up with // this array The returndata call above will then return this array - std::vector returndata = { sender, address, storage_address, feeperl2gas, feeperdagas, - transactionfee, chainid, version, blocknumber, /*coinbase,*/ timestamp }; + std::vector returndata = { sender, address, storage_address, function_selector, transaction_fee, + chainid, version, blocknumber, /*coinbase,*/ timestamp, feeperl2gas, + feeperdagas }; // Set up public inputs to contain the above values // TODO: maybe have a javascript like object construction so that this is readable // Reduce the amount of times we have similar code to this - public_inputs_vec[SENDER_SELECTOR] = sender; + // public_inputs_vec[ADDRESS_SELECTOR] = address; public_inputs_vec[STORAGE_ADDRESS_SELECTOR] = storage_address; + public_inputs_vec[SENDER_SELECTOR] = sender; + public_inputs_vec[FUNCTION_SELECTOR_SELECTOR] = function_selector; + public_inputs_vec[TRANSACTION_FEE_OFFSET] = transaction_fee; // Global variables public_inputs_vec[CHAIN_ID_OFFSET] = chainid; @@ -1457,21 +1472,13 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) public_inputs_vec[TIMESTAMP_OFFSET] = timestamp; // Not in the simulator yet // public_inputs_vec[COINBASE_OFFSET] = coinbase; - - // Fees + // Global variables - Gas public_inputs_vec[FEE_PER_DA_GAS_OFFSET] = feeperdagas; public_inputs_vec[FEE_PER_L2_GAS_OFFSET] = feeperl2gas; - // Transaction fee - public_inputs_vec[TRANSACTION_FEE_OFFSET] = transactionfee; - auto trace = Execution::gen_trace(instructions, returndata, calldata, public_inputs_vec); // Validate that the opcode read the correct value into ia - // Check sender - auto sender_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_sender == 1; }); - EXPECT_EQ(sender_row->main_ia, sender); - // Check address auto address_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_address == 1; }); @@ -1482,6 +1489,20 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_storage_address == 1; }); EXPECT_EQ(storage_addr_row->main_ia, storage_address); + // Check sender + auto sender_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_sender == 1; }); + EXPECT_EQ(sender_row->main_ia, sender); + + // Check function selector + auto function_selector_row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_function_selector == 1; }); + EXPECT_EQ(function_selector_row->main_ia, function_selector); + + // Check transactionfee + auto transaction_fee_row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_transaction_fee == 1; }); + EXPECT_EQ(transaction_fee_row->main_ia, transaction_fee); + // Check chain id auto chainid_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_chain_id == 1; }); @@ -1502,6 +1523,12 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_timestamp == 1; }); EXPECT_EQ(timestamp_row->main_ia, timestamp); + // // Check coinbase + // Not in simulator + // auto coinbase_row = + // std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_coinbase == 1; }); + // EXPECT_EQ(coinbase_row->main_ia, coinbase); + // Check feeperdagas auto feeperdagas_row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_fee_per_da_gas == 1; }); @@ -1512,17 +1539,6 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_fee_per_l2_gas == 1; }); EXPECT_EQ(feeperl2gas_row->main_ia, feeperl2gas); - // Check transactionfee - auto transactionfee_row = - std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_transaction_fee == 1; }); - EXPECT_EQ(transactionfee_row->main_ia, transactionfee); - - // // Check coinbase - // Not in simulator - // auto coinbase_row = - // std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_coinbase == 1; }); - // EXPECT_EQ(coinbase_row->main_ia, coinbase); - validate_trace(std::move(trace), Execution::convert_public_inputs(public_inputs_vec)); } diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_kernel.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_kernel.test.cpp index dcfb3ab71a1..0ea5ca18b30 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_kernel.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_kernel.test.cpp @@ -280,6 +280,42 @@ TEST_F(AvmKernelPositiveTests, kernelStorageAddress) test_kernel_lookup(true, indirect_apply_opcodes, checks); } +TEST_F(AvmKernelPositiveTests, kernelFunctionSelector) +{ + // Direct + uint32_t dst_offset = 42; + uint32_t indirect_dst_offset = 69; + // We test that the function selector opcode is included at index 0 in the public inputs + auto direct_apply_opcodes = [=](AvmTraceBuilder& trace_builder) { + trace_builder.op_function_selector(/*indirect*/ false, dst_offset); + }; + auto indirect_apply_opcodes = [=](AvmTraceBuilder& trace_builder) { + trace_builder.op_set( + /*indirect*/ false, + /*value*/ dst_offset, + /*dst_offset*/ indirect_dst_offset, + AvmMemoryTag::U32); + trace_builder.op_function_selector(/*indirect*/ true, indirect_dst_offset); + }; + + auto checks = [=](bool indirect, const std::vector& trace) { + auto row = std::ranges::find_if( + trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_function_selector == FF(1); }); + EXPECT_TRUE(row != trace.end()); + + expect_row(row, + /*kernel_in_offset=*/FUNCTION_SELECTOR_SELECTOR, + /*ia=*/FUNCTION_SELECTOR_SELECTOR + + 1, // Note the value generated above for public inputs is the same as the index read + 1 + /*ind_a*/ indirect ? indirect_dst_offset : 0, + /*mem_addr_a=*/dst_offset, + /*w_in_tag=*/AvmMemoryTag::U32); + }; + + test_kernel_lookup(false, direct_apply_opcodes, checks); + test_kernel_lookup(true, indirect_apply_opcodes, checks); +} + TEST_F(AvmKernelPositiveTests, kernelFeePerDa) { uint32_t dst_offset = 42; @@ -662,6 +698,32 @@ TEST_F(AvmKernelNegativeTests, incorrectIaStorageAddress) negative_test_incorrect_ia_kernel_lookup(apply_opcodes, checks, incorrect_ia, "PERM_MAIN_MEM_A"); } +TEST_F(AvmKernelNegativeTests, incorrectIaFunctionSelector) +{ + uint32_t dst_offset = 42; + FF incorrect_ia = FF(69); + + // We test that the sender opcode is inlcuded at index x in the public inputs + auto apply_opcodes = [=](AvmTraceBuilder& trace_builder) { + trace_builder.op_function_selector(/*indirect*/ false, dst_offset); + }; + auto checks = [=](bool indirect, const std::vector& trace) { + auto row = std::ranges::find_if( + trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_function_selector == FF(1); }); + EXPECT_TRUE(row != trace.end()); + + expect_row( + row, + /*kernel_in_offset=*/FUNCTION_SELECTOR_SELECTOR, + /*ia=*/incorrect_ia, // Note the value generated above for public inputs is the same as the index read + 1 + /*ind_a*/ indirect, + /*mem_addr_a=*/dst_offset, + /*w_in_tag=*/AvmMemoryTag::U32); + }; + + negative_test_incorrect_ia_kernel_lookup(apply_opcodes, checks, incorrect_ia, "PERM_MAIN_MEM_A"); +} + TEST_F(AvmKernelNegativeTests, incorrectIaDaGas) { uint32_t dst_offset = 42; diff --git a/docs/docs/protocol-specs/public-vm/_nested-context.md b/docs/docs/protocol-specs/public-vm/_nested-context.md index 2b24cff09f2..c6fbd1824ab 100644 --- a/docs/docs/protocol-specs/public-vm/_nested-context.md +++ b/docs/docs/protocol-specs/public-vm/_nested-context.md @@ -14,11 +14,10 @@ nestedContext = deriveContext(context, instr.args, isStaticCall, isDelegateCall) Nested context derivation is defined as follows: ```jsx nestedExecutionEnvironment = ExecutionEnvironment { - sender: isDelegateCall ? context.sender : context.address, address: M[addrOffset], storageAddress: isDelegateCall ? context.storageAddress : M[addrOffset], - feePerL2Gas: context.environment.feePerL2Gas, - feePerDaGas: context.environment.feePerDaGas, + sender: isDelegateCall ? context.sender : context.address, + functionSelector: context.environment.functionSelector, transactionFee: context.environment.transactionFee, contractCallDepth: context.contractCallDepth + 1, contractCallPointer: context.worldStateAccessTrace.contractCalls.length + 1, @@ -49,4 +48,4 @@ nestedContext = AvmContext { } ``` -> `M[offset]` notation is shorthand for `context.machineState.memory[offset]` \ No newline at end of file +> `M[offset]` notation is shorthand for `context.machineState.memory[offset]` diff --git a/docs/docs/protocol-specs/public-vm/context.mdx b/docs/docs/protocol-specs/public-vm/context.mdx index d770462befe..6bb784ef606 100644 --- a/docs/docs/protocol-specs/public-vm/context.mdx +++ b/docs/docs/protocol-specs/public-vm/context.mdx @@ -28,9 +28,7 @@ A context's **execution environment** remains constant throughout a contract cal | address | `AztecAddress` | | | storageAddress | `AztecAddress` | | | sender | `AztecAddress` | | -| portal | `EthAddress` | | -| feePerL2Gas | `field` | | -| feePerDaGas | `field` | | +| functionSelector | `u32` | | | transactionFee | `field` | Computed transaction fee based on gas fees, inclusion fee, and gas usage. Zero in all phases but teardown. | | contractCallDepth | `field` | Depth of the current call (how many nested calls deep is it). | | contractCallPointer | `field` | Uniquely identifies each contract call processed by an AVM session. An initial call is assigned pointer value of 1 (expanded on in the AVM circuit section's ["Call Pointer"](./avm-circuit#call-pointer) subsection). | @@ -76,9 +74,7 @@ INITIAL_EXECUTION_ENVIRONMENT = ExecutionEnvironment { address: PublicCallRequest.contractAddress, storageAddress: PublicCallRequest.CallContext.storageContractAddress, sender: PublicCallRequest.CallContext.msgSender, - portal: PublicCallRequest.CallContext.portalContractAddress, - feePerL2Gas: TxRequest.feePerL2Gas, - feePerDaGas: TxRequest.feePerDaGas, + functionelector: PublicCallRequest.functionSelector, contractCallDepth: 0, contractCallPointer: 1, globals: @@ -88,8 +84,8 @@ INITIAL_EXECUTION_ENVIRONMENT = ExecutionEnvironment { } INITIAL_MACHINE_STATE = MachineState { - l2GasLeft: TxRequest.l2GasLimit, - daGasLeft: TxRequest.daGasLimit, + l2GasLeft: , + daGasLeft: , pc: 0, internalCallStack: [], // initialized as empty memory: [0, ..., 0], // all 2^32 entries are initialized to zero diff --git a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx index ab744c11ed6..cf740097fc4 100644 --- a/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx +++ b/docs/docs/protocol-specs/public-vm/gen/_instruction-set.mdx @@ -159,22 +159,14 @@ Click on an instruction name to jump to its section. 0x12 - \[\`FEEPERL2GAS\`\](#isa-section-feeperl2gas) - Get the fee to be paid per "L2 gas" - constant for entire transaction + \[\`FUNCTIONSELECTOR\`\](#isa-section-functionselector) + Get the function selector of the contract function being executed { - `M[dstOffset] = context.environment.feePerL2Gas` + `M[dstOffset] = context.environment.functionSelector` } 0x13 - \[\`FEEPERDAGAS\`\](#isa-section-feeperdagas) - Get the fee to be paid per "DA gas" - constant for entire transaction - { - `M[dstOffset] = context.environment.feePerDaGas` - } - - - 0x14 \[\`TRANSACTIONFEE\`\](#isa-section-transactionfee) Get the computed transaction fee during teardown phase, zero otherwise { @@ -182,15 +174,7 @@ Click on an instruction name to jump to its section. } - 0x15 - \[\`CONTRACTCALLDEPTH\`\](#isa-section-contractcalldepth) - Get how many contract calls deep the current call context is - { - `M[dstOffset] = context.environment.contractCallDepth` - } - - - 0x16 + 0x14 \[\`CHAINID\`\](#isa-section-chainid) Get this rollup's L1 chain ID { @@ -198,7 +182,7 @@ Click on an instruction name to jump to its section. } - 0x17 + 0x15 \[\`VERSION\`\](#isa-section-version) Get this rollup's L2 version ID { @@ -206,7 +190,7 @@ Click on an instruction name to jump to its section. } - 0x18 + 0x16 \[\`BLOCKNUMBER\`\](#isa-section-blocknumber) Get this L2 block's number { @@ -214,7 +198,7 @@ Click on an instruction name to jump to its section. } - 0x19 + 0x17 \[\`TIMESTAMP\`\](#isa-section-timestamp) Get this L2 block's timestamp { @@ -222,17 +206,33 @@ Click on an instruction name to jump to its section. } - 0x1a + 0x18 \[\`COINBASE\`\](#isa-section-coinbase) - Get the block's beneficiary address + (UNIMPLEMENTED) Get the block's beneficiary address { `M[dstOffset] = context.environment.globals.coinbase` } + + 0x19 + \[\`FEEPERL2GAS\`\](#isa-section-feeperl2gas) + Get the fee to be paid per "L2 gas" - constant for entire transaction + { + `M[dstOffset] = context.environment.globals.feePerL2Gas` + } + + + 0x1a + \[\`FEEPERDAGAS\`\](#isa-section-feeperdagas) + Get the fee to be paid per "DA gas" - constant for entire transaction + { + `M[dstOffset] = context.environment.globals.feePerDaGas` + } + 0x1b \[\`BLOCKL2GASLIMIT\`\](#isa-section-blockl2gaslimit) - Total amount of "L2 gas" that a block can consume + (UNIMPLEMENTED) Total amount of "L2 gas" that a block can consume { `M[dstOffset] = context.environment.globals.l2GasLimit` } @@ -240,7 +240,7 @@ Click on an instruction name to jump to its section. 0x1c \[\`BLOCKDAGASLIMIT\`\](#isa-section-blockdagaslimit) - Total amount of "DA gas" that a block can consume + (UNIMPLEMENTED) Total amount of "DA gas" that a block can consume { `M[dstOffset] = context.environment.globals.daGasLimit` } @@ -399,7 +399,7 @@ M[existsOffset] = exists`} 0x2e \[\`HEADERMEMBER\`\](#isa-section-headermember) - Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so + (UNIMPLEMENTED) Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so {`exists = context.worldState.header.has({ leafIndex: M[blockIndexOffset], leaf: M[msgKeyOffset] @@ -486,7 +486,7 @@ updateContextAfterNestedCall(context, instr.args, nestedContext)`} 0x34 \[\`DELEGATECALL\`\](#isa-section-delegatecall) - Call into another contract, but keep the caller's `sender` and `storageAddress` + (UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress` {`// instr.args are { gasOffset, addrOffset, argsOffset, retOffset, retSize } chargeGas(context, @@ -895,10 +895,10 @@ Get the address of the sender (caller of the current context) [![](/img/protocol-specs/public-vm/bit-formats/SENDER.png)](/img/protocol-specs/public-vm/bit-formats/SENDER.png) -### `FEEPERL2GAS` -Get the fee to be paid per "L2 gas" - constant for entire transaction +### `FUNCTIONSELECTOR` +Get the function selector of the contract function being executed -[See in table.](#isa-table-feeperl2gas) +[See in table.](#isa-table-functionselector) - **Opcode**: 0x12 - **Category**: Execution Environment @@ -906,35 +906,17 @@ Get the fee to be paid per "L2 gas" - constant for entire transaction - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. - **Args**: - **dstOffset**: memory offset specifying where to store operation's result -- **Expression**: `M[dstOffset] = context.environment.feePerL2Gas` -- **Tag updates**: `T[dstOffset] = field` -- **Bit-size**: 56 - -[![](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png) - -### `FEEPERDAGAS` -Get the fee to be paid per "DA gas" - constant for entire transaction - -[See in table.](#isa-table-feeperdagas) - -- **Opcode**: 0x13 -- **Category**: Execution Environment -- **Flags**: - - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. -- **Args**: - - **dstOffset**: memory offset specifying where to store operation's result -- **Expression**: `M[dstOffset] = context.environment.feePerDaGas` -- **Tag updates**: `T[dstOffset] = field` +- **Expression**: `M[dstOffset] = context.environment.functionSelector` +- **Tag updates**: `T[dstOffset] = u32` - **Bit-size**: 56 -[![](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png) ### `TRANSACTIONFEE` Get the computed transaction fee during teardown phase, zero otherwise [See in table.](#isa-table-transactionfee) -- **Opcode**: 0x14 +- **Opcode**: 0x13 - **Category**: Execution Environment - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -945,30 +927,12 @@ Get the computed transaction fee during teardown phase, zero otherwise - **Bit-size**: 56 -### `CONTRACTCALLDEPTH` -Get how many contract calls deep the current call context is - -[See in table.](#isa-table-contractcalldepth) - -- **Opcode**: 0x15 -- **Category**: Execution Environment -- **Flags**: - - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. -- **Args**: - - **dstOffset**: memory offset specifying where to store operation's result -- **Expression**: `M[dstOffset] = context.environment.contractCallDepth` -- **Details**: Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`. -- **Tag updates**: `T[dstOffset] = field` -- **Bit-size**: 56 - -[![](/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png)](/img/protocol-specs/public-vm/bit-formats/CONTRACTCALLDEPTH.png) - ### `CHAINID` Get this rollup's L1 chain ID [See in table.](#isa-table-chainid) -- **Opcode**: 0x16 +- **Opcode**: 0x14 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -985,7 +949,7 @@ Get this rollup's L2 version ID [See in table.](#isa-table-version) -- **Opcode**: 0x17 +- **Opcode**: 0x15 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1002,7 +966,7 @@ Get this L2 block's number [See in table.](#isa-table-blocknumber) -- **Opcode**: 0x18 +- **Opcode**: 0x16 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1019,7 +983,7 @@ Get this L2 block's timestamp [See in table.](#isa-table-timestamp) -- **Opcode**: 0x19 +- **Opcode**: 0x17 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1032,11 +996,11 @@ Get this L2 block's timestamp [![](/img/protocol-specs/public-vm/bit-formats/TIMESTAMP.png)](/img/protocol-specs/public-vm/bit-formats/TIMESTAMP.png) ### `COINBASE` -Get the block's beneficiary address +(UNIMPLEMENTED) Get the block's beneficiary address [See in table.](#isa-table-coinbase) -- **Opcode**: 0x1a +- **Opcode**: 0x18 - **Category**: Execution Environment - Globals - **Flags**: - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. @@ -1048,8 +1012,42 @@ Get the block's beneficiary address [![](/img/protocol-specs/public-vm/bit-formats/COINBASE.png)](/img/protocol-specs/public-vm/bit-formats/COINBASE.png) +### `FEEPERL2GAS` +Get the fee to be paid per "L2 gas" - constant for entire transaction + +[See in table.](#isa-table-feeperl2gas) + +- **Opcode**: 0x19 +- **Category**: Execution Environment - Globals - Gas +- **Flags**: + - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = context.environment.globals.feePerL2Gas` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 56 + +[![](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERL2GAS.png) + +### `FEEPERDAGAS` +Get the fee to be paid per "DA gas" - constant for entire transaction + +[See in table.](#isa-table-feeperdagas) + +- **Opcode**: 0x1a +- **Category**: Execution Environment - Globals - Gas +- **Flags**: + - **indirect**: Toggles whether each memory-offset argument is an indirect offset. Rightmost bit corresponds to 0th offset arg, etc. Indirect offsets result in memory accesses like `M[M[offset]]` instead of the more standard `M[offset]`. +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = context.environment.globals.feePerDaGas` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 56 + +[![](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png)](/img/protocol-specs/public-vm/bit-formats/FEEPERDAGAS.png) + ### `BLOCKL2GASLIMIT` -Total amount of "L2 gas" that a block can consume +(UNIMPLEMENTED) Total amount of "L2 gas" that a block can consume [See in table.](#isa-table-blockl2gaslimit) @@ -1066,7 +1064,7 @@ Total amount of "L2 gas" that a block can consume [![](/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png)](/img/protocol-specs/public-vm/bit-formats/BLOCKL2GASLIMIT.png) ### `BLOCKDAGASLIMIT` -Total amount of "DA gas" that a block can consume +(UNIMPLEMENTED) Total amount of "DA gas" that a block can consume [See in table.](#isa-table-blockdagaslimit) @@ -1522,7 +1520,7 @@ M[existsOffset] = exists`} ### `HEADERMEMBER` -Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so +(UNIMPLEMENTED) Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so [See in table.](#isa-table-headermember) @@ -1737,7 +1735,7 @@ T[retOffset:retOffset+retSize] = field`} [![](/img/protocol-specs/public-vm/bit-formats/STATICCALL.png)](/img/protocol-specs/public-vm/bit-formats/STATICCALL.png) ### `DELEGATECALL` -Call into another contract, but keep the caller's `sender` and `storageAddress` +(UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress` [See in table.](#isa-table-delegatecall) diff --git a/docs/docs/protocol-specs/public-vm/intro.md b/docs/docs/protocol-specs/public-vm/intro.md index e27ea9e1ced..a89e45fc1b2 100644 --- a/docs/docs/protocol-specs/public-vm/intro.md +++ b/docs/docs/protocol-specs/public-vm/intro.md @@ -38,4 +38,9 @@ A contract's public bytecode is a series of execution instructions for the AVM. The entirety of a contract's public code is represented as a single block of bytecode with a maximum of `MAX_PUBLIC_INSTRUCTIONS_PER_CONTRACT` ($2^{15} = 32768$) instructions. The mechanism used to distinguish between different "functions" in an AVM bytecode program is left as a higher-level abstraction (_e.g._ similar to Solidity's concept of a function selector). +::: warning +Ultimately, function selectors _may_ be removed as an enshrined protocol mechanism as described above. For now, each public function on a contract has a distinct bytecode that can be selected for execution via a function selector. +::: + + > See the [Bytecode Validation Circuit](./bytecode-validation-circuit) to see how a contract's bytecode can be validated and committed to. diff --git a/docs/src/preprocess/InstructionSet/InstructionSet.js b/docs/src/preprocess/InstructionSet/InstructionSet.js index daead5a8c39..5fd93fc92e3 100644 --- a/docs/src/preprocess/InstructionSet/InstructionSet.js +++ b/docs/src/preprocess/InstructionSet/InstructionSet.js @@ -550,27 +550,8 @@ const INSTRUCTION_SET_RAW = [ "Tag updates": "`T[dstOffset] = field`", }, { - id: "feeperl2gas", - Name: "`FEEPERL2GAS`", - Category: "Execution Environment", - Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], - Args: [ - { - name: "dstOffset", - description: - "memory offset specifying where to store operation's result", - }, - ], - Expression: "`M[dstOffset] = context.environment.feePerL2Gas`", - Summary: - 'Get the fee to be paid per "L2 gas" - constant for entire transaction', - Details: "", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = field`", - }, - { - id: "feeperdagas", - Name: "`FEEPERDAGAS`", + id: "functionselector", + Name: "`FUNCTIONSELECTOR`", Category: "Execution Environment", Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], Args: [ @@ -580,12 +561,11 @@ const INSTRUCTION_SET_RAW = [ "memory offset specifying where to store operation's result", }, ], - Expression: "`M[dstOffset] = context.environment.feePerDaGas`", - Summary: - 'Get the fee to be paid per "DA gas" - constant for entire transaction', + Expression: "`M[dstOffset] = context.environment.functionSelector`", + Summary: "Get the function selector of the contract function being executed", Details: "", "Tag checks": "", - "Tag updates": "`T[dstOffset] = field`", + "Tag updates": "`T[dstOffset] = u32`", }, { id: "transactionfee", @@ -606,25 +586,6 @@ const INSTRUCTION_SET_RAW = [ "Tag checks": "", "Tag updates": "`T[dstOffset] = field`", }, - { - id: "contractcalldepth", - Name: "`CONTRACTCALLDEPTH`", - Category: "Execution Environment", - Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], - Args: [ - { - name: "dstOffset", - description: - "memory offset specifying where to store operation's result", - }, - ], - Expression: "`M[dstOffset] = context.environment.contractCallDepth`", - Summary: "Get how many contract calls deep the current call context is", - Details: - "Note: security issues with EVM's tx.origin can be resolved by asserting `calldepth == 0`.", - "Tag checks": "", - "Tag updates": "`T[dstOffset] = field`", - }, { id: "chainid", Name: "`CHAINID`", @@ -710,7 +671,45 @@ const INSTRUCTION_SET_RAW = [ }, ], Expression: "`M[dstOffset] = context.environment.globals.coinbase`", - Summary: "Get the block's beneficiary address", + Summary: "(UNIMPLEMENTED) Get the block's beneficiary address", + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + id: "feeperl2gas", + Name: "`FEEPERL2GAS`", + Category: "Execution Environment - Globals - Gas", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.feePerL2Gas`", + Summary: + 'Get the fee to be paid per "L2 gas" - constant for entire transaction', + Details: "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + id: "feeperdagas", + Name: "`FEEPERDAGAS`", + Category: "Execution Environment - Globals - Gas", + Flags: [{ name: "indirect", description: INDIRECT_FLAG_DESCRIPTION }], + Args: [ + { + name: "dstOffset", + description: + "memory offset specifying where to store operation's result", + }, + ], + Expression: "`M[dstOffset] = context.environment.globals.feePerDaGas`", + Summary: + 'Get the fee to be paid per "DA gas" - constant for entire transaction', Details: "", "Tag checks": "", "Tag updates": "`T[dstOffset] = field`", @@ -728,7 +727,7 @@ const INSTRUCTION_SET_RAW = [ }, ], Expression: "`M[dstOffset] = context.environment.globals.l2GasLimit`", - Summary: 'Total amount of "L2 gas" that a block can consume', + Summary: '(UNIMPLEMENTED) Total amount of "L2 gas" that a block can consume', Details: "", "Tag checks": "", "Tag updates": "`T[dstOffset] = field`", @@ -746,7 +745,7 @@ const INSTRUCTION_SET_RAW = [ }, ], Expression: "`M[dstOffset] = context.environment.globals.daGasLimit`", - Summary: 'Total amount of "DA gas" that a block can consume', + Summary: '(UNIMPLEMENTED) Total amount of "DA gas" that a block can consume', Details: "", "Tag checks": "", "Tag updates": "`T[dstOffset] = field`", @@ -1287,7 +1286,7 @@ if exists: M[dstOffset] = header[M[memberIndexOffset]] // member `, Summary: - "Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so", + "(UNIMPLEMENTED) Check if a header exists in the [archive tree](../state/archive) and retrieve the specified member if so", "World State access tracing": ` context.worldStateAccessTrace.archiveChecks.append( TracedArchiveLeafCheck { @@ -1462,7 +1461,7 @@ execute(nestedContext) updateContextAfterNestedCall(context, instr.args, nestedContext) `, Summary: - "Call into another contract, but keep the caller's `sender` and `storageAddress`", + "(UNIMPLEMENTED) Call into another contract, but keep the caller's `sender` and `storageAddress`", Details: `Same as \`CALL\`, but \`sender\` and \`storageAddress\` remains the same in the nested call as they were in the caller. ` + diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr index 9075e5a207d..aa7bb176c0f 100644 --- a/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr +++ b/noir-projects/aztec-nr/aztec/src/context/inputs/public_context_inputs.nr @@ -2,7 +2,6 @@ use dep::protocol_types::traits::Empty; // These inputs will likely go away once the AVM processes 1 public kernel per enqueued call. struct PublicContextInputs { - selector: Field, args_hash: Field, is_static_call: bool } @@ -10,7 +9,6 @@ struct PublicContextInputs { impl Empty for PublicContextInputs { fn empty() -> Self { PublicContextInputs { - selector: 0, args_hash: 0, is_static_call: false } diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 7c056a43506..53e213abb8f 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -14,18 +14,6 @@ impl PublicContext { PublicContext { inputs } } - pub fn storage_address(self) -> AztecAddress { - storage_address() - } - - pub fn fee_per_l2_gas(self) -> Field { - fee_per_l2_gas() - } - - pub fn fee_per_da_gas(self) -> Field { - fee_per_da_gas() - } - pub fn emit_unencrypted_log(&mut self, log: T) where T: Serialize { emit_unencrypted_log(Serialize::serialize(log).as_slice()); } @@ -38,18 +26,6 @@ impl PublicContext { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) == 1 } - fn block_number(self) -> Field { - block_number() - } - - fn timestamp(self) -> u64 { - timestamp() - } - - fn transaction_fee(self) -> Field { - transaction_fee() - } - fn nullifier_exists(self, unsiloed_nullifier: Field, address: AztecAddress) -> bool { nullifier_exists(unsiloed_nullifier, address.to_field()) == 1 } @@ -90,7 +66,7 @@ impl PublicContext { fn call_public_function( self: &mut Self, contract_address: AztecAddress, - temporary_function_selector: FunctionSelector, + function_selector: FunctionSelector, args: [Field], gas_opts: GasOpts ) -> FunctionReturns { @@ -98,7 +74,7 @@ impl PublicContext { gas_for_call(gas_opts), contract_address, args, - temporary_function_selector.to_field() + function_selector.to_field() ); let data_to_return: [Field; RETURNS_COUNT] = results.0; let success: u8 = results.1; @@ -110,7 +86,7 @@ impl PublicContext { fn static_call_public_function( self: &mut Self, contract_address: AztecAddress, - temporary_function_selector: FunctionSelector, + function_selector: FunctionSelector, args: [Field], gas_opts: GasOpts ) -> FunctionReturns { @@ -118,7 +94,7 @@ impl PublicContext { gas_for_call(gas_opts), contract_address, args, - temporary_function_selector.to_field() + function_selector.to_field() ); assert(success == 1, "Nested static call failed!"); @@ -142,24 +118,45 @@ impl PublicContext { // Cannot nullify pending commitments in AVM, so `nullified_commitment` is not used emit_nullifier(nullifier); } + + fn this_address(self) -> AztecAddress { + address() + } + pub fn storage_address(self) -> AztecAddress { + storage_address() + } fn msg_sender(self) -> AztecAddress { sender() } - fn this_address(self) -> AztecAddress { - address() + fn selector(self) -> FunctionSelector { + FunctionSelector::from_u32(function_selector()) } + fn get_args_hash(self) -> Field { + self.inputs.args_hash + } + fn transaction_fee(self) -> Field { + transaction_fee() + } + fn chain_id(self) -> Field { chain_id() } fn version(self) -> Field { version() } - fn selector(self) -> FunctionSelector { - FunctionSelector::from_field(self.inputs.selector) + fn block_number(self) -> Field { + block_number() } - fn get_args_hash(self) -> Field { - self.inputs.args_hash + fn timestamp(self) -> u64 { + timestamp() } + pub fn fee_per_l2_gas(self) -> Field { + fee_per_l2_gas() + } + pub fn fee_per_da_gas(self) -> Field { + fee_per_da_gas() + } + fn l2_gas_left(self) -> Field { l2_gas_left() } @@ -209,11 +206,8 @@ unconstrained fn sender() -> AztecAddress { unconstrained fn portal() -> EthAddress { portal_opcode() } -unconstrained fn fee_per_l2_gas() -> Field { - fee_per_l2_gas_opcode() -} -unconstrained fn fee_per_da_gas() -> Field { - fee_per_da_gas_opcode() +unconstrained fn function_selector() -> u32 { + function_selector_opcode() } unconstrained fn transaction_fee() -> Field { transaction_fee_opcode() @@ -230,6 +224,12 @@ unconstrained fn block_number() -> Field { unconstrained fn timestamp() -> u64 { timestamp_opcode() } +unconstrained fn fee_per_l2_gas() -> Field { + fee_per_l2_gas_opcode() +} +unconstrained fn fee_per_da_gas() -> Field { + fee_per_da_gas_opcode() +} unconstrained fn l2_gas_left() -> Field { l2_gas_left_opcode() } @@ -301,11 +301,8 @@ unconstrained fn sender_opcode() -> AztecAddress {} #[oracle(avmOpcodePortal)] unconstrained fn portal_opcode() -> EthAddress {} -#[oracle(avmOpcodeFeePerL2Gas)] -unconstrained fn fee_per_l2_gas_opcode() -> Field {} - -#[oracle(avmOpcodeFeePerDaGas)] -unconstrained fn fee_per_da_gas_opcode() -> Field {} +#[oracle(avmOpcodeFunctionSelector)] +unconstrained fn function_selector_opcode() -> u32 {} #[oracle(avmOpcodeTransactionFee)] unconstrained fn transaction_fee_opcode() -> Field {} @@ -322,6 +319,12 @@ unconstrained fn block_number_opcode() -> Field {} #[oracle(avmOpcodeTimestamp)] unconstrained fn timestamp_opcode() -> u64 {} +#[oracle(avmOpcodeFeePerL2Gas)] +unconstrained fn fee_per_l2_gas_opcode() -> Field {} + +#[oracle(avmOpcodeFeePerDaGas)] +unconstrained fn fee_per_da_gas_opcode() -> Field {} + #[oracle(avmOpcodeL2GasLeft)] unconstrained fn l2_gas_left_opcode() -> Field {} diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index 9b66e64264b..e07b411e012 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -164,7 +164,6 @@ impl TestEnvironment { cheatcodes::set_contract_address(target_address); cheatcodes::set_msg_sender(original_contract_address); let mut inputs = cheatcodes::get_public_context_inputs(); - inputs.selector = call_interface.get_selector().to_field(); inputs.args_hash = hash_args(call_interface.get_args()); inputs.is_static_call = call_interface.get_is_static(); let result = original_fn(inputs); diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr index 808b5ad37f5..87639e0fb73 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr @@ -82,7 +82,6 @@ impl Deployer { cheatcodes::set_contract_address(instance.to_address()); cheatcodes::set_msg_sender(original_contract_address); let mut inputs = cheatcodes::get_public_context_inputs(); - inputs.selector = call_interface.get_selector().to_field(); inputs.args_hash = hash_args(call_interface.get_args()); let _result: T = original_fn(inputs); diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 16274f1db46..6132c880cb3 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -273,13 +273,8 @@ contract AvmTest { } #[aztec(public)] - fn get_fee_per_l2_gas() -> Field { - context.fee_per_l2_gas() - } - - #[aztec(public)] - fn get_fee_per_da_gas() -> Field { - context.fee_per_da_gas() + fn get_function_selector() -> FunctionSelector { + context.selector() } #[aztec(public)] @@ -307,6 +302,16 @@ contract AvmTest { context.timestamp() } + #[aztec(public)] + fn get_fee_per_l2_gas() -> Field { + context.fee_per_l2_gas() + } + + #[aztec(public)] + fn get_fee_per_da_gas() -> Field { + context.fee_per_da_gas() + } + #[aztec(public)] fn get_l2_gas_left() -> Field { context.l2_gas_left() diff --git a/yarn-project/bb-prover/src/avm_proving.test.ts b/yarn-project/bb-prover/src/avm_proving.test.ts index 6f465bf4d95..5f721dd565b 100644 --- a/yarn-project/bb-prover/src/avm_proving.test.ts +++ b/yarn-project/bb-prover/src/avm_proving.test.ts @@ -3,6 +3,7 @@ import { AztecAddress, ContractStorageRead, ContractStorageUpdateRequest, + FunctionSelector, Gas, GlobalVariables, Header, @@ -168,6 +169,7 @@ describe('AVM WitGen, proof generation and verification', () => { 'get_fee_per_l2_gas', 'get_fee_per_da_gas', 'get_transaction_fee', + 'get_function_selector', 'get_chain_id', 'get_version', 'get_block_number', @@ -201,9 +203,10 @@ const proveAndVerifyAvmTestContract = async ( assertionErrString?: string, ) => { const startSideEffectCounter = 0; + const functionSelector = FunctionSelector.random(); const globals = GlobalVariables.empty(); globals.timestamp = TIMESTAMP; - const environment = initExecutionEnvironment({ calldata, globals }); + const environment = initExecutionEnvironment({ functionSelector, calldata, globals }); const contractsDb = mock(); const contractInstance = new SerializableContractInstance({ diff --git a/yarn-project/simulator/src/avm/avm_context.ts b/yarn-project/simulator/src/avm/avm_context.ts index c9c5e13ef76..b0ca8d3b2df 100644 --- a/yarn-project/simulator/src/avm/avm_context.ts +++ b/yarn-project/simulator/src/avm/avm_context.ts @@ -43,13 +43,13 @@ export class AvmContext { calldata: Fr[], allocatedGas: Gas, callType: 'CALL' | 'STATICCALL', - temporaryFunctionSelector: FunctionSelector = FunctionSelector.empty(), + functionSelector: FunctionSelector = FunctionSelector.empty(), ): AvmContext { const deriveFn = callType === 'CALL' ? this.environment.deriveEnvironmentForNestedCall : this.environment.deriveEnvironmentForNestedStaticCall; - const newExecutionEnvironment = deriveFn.call(this.environment, address, calldata, temporaryFunctionSelector); + const newExecutionEnvironment = deriveFn.call(this.environment, address, calldata, functionSelector); const forkedWorldState = this.persistableState.fork(); const machineState = AvmMachineState.fromState(gasToGasLeft(allocatedGas)); return new AvmContext(forkedWorldState, newExecutionEnvironment, machineState); diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index 2e73d8e384e..27a1e32ec9c 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -1,15 +1,15 @@ -import { FunctionSelector, type GasSettings, type GlobalVariables, type Header } from '@aztec/circuits.js'; +import { FunctionSelector, type GlobalVariables, type Header } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; export class AvmContextInputs { - static readonly SIZE = 3; + static readonly SIZE = 2; - constructor(private selector: Fr, private argsHash: Fr, private isStaticCall: boolean) {} + constructor(private argsHash: Fr, private isStaticCall: boolean) {} public toFields(): Fr[] { - return [this.selector, this.argsHash, new Fr(this.isStaticCall)]; + return [this.argsHash, new Fr(this.isStaticCall)]; } } @@ -18,36 +18,23 @@ export class AvmContextInputs { * These variables are provided by the public kernel circuit */ export class AvmExecutionEnvironment { - private readonly calldataPrefixLength; constructor( public readonly address: AztecAddress, public readonly storageAddress: AztecAddress, public readonly sender: AztecAddress, - public readonly feePerL2Gas: Fr, - public readonly feePerDaGas: Fr, + public readonly functionSelector: FunctionSelector, // may be temporary (#7224) public readonly contractCallDepth: Fr, + public readonly transactionFee: Fr, public readonly header: Header, public readonly globals: GlobalVariables, public readonly isStaticCall: boolean, public readonly isDelegateCall: boolean, public readonly calldata: Fr[], - public readonly gasSettings: GasSettings, - public readonly transactionFee: Fr, - - // Function selector may be temporary since eventually public contract bytecode will likely be one - // blob containing all functions, and function selector will become an application-level mechanism - // (e.g. first few bytes of calldata + compiler-generated jump table) - public readonly functionSelector: FunctionSelector, ) { // We encode some extra inputs (AvmContextInputs) in calldata. // This will have to go once we move away from one proof per call. - const inputs = new AvmContextInputs( - functionSelector.toField(), - computeVarArgsHash(calldata), - isStaticCall, - ).toFields(); + const inputs = new AvmContextInputs(computeVarArgsHash(calldata), isStaticCall).toFields(); this.calldata = [...inputs, ...calldata]; - this.calldataPrefixLength = inputs.length; } private deriveEnvironmentForNestedCallInternal( @@ -61,17 +48,14 @@ export class AvmExecutionEnvironment { /*address=*/ targetAddress, /*storageAddress=*/ targetAddress, /*sender=*/ this.address, - this.feePerL2Gas, - this.feePerDaGas, + functionSelector, this.contractCallDepth.add(Fr.ONE), + this.transactionFee, this.header, this.globals, isStaticCall, isDelegateCall, calldata, - this.gasSettings, - this.transactionFee, - functionSelector, ); } @@ -113,6 +97,6 @@ export class AvmExecutionEnvironment { public getCalldataWithoutPrefix(): Fr[] { // clip off the first few entries - return this.calldata.slice(this.calldataPrefixLength); + return this.calldata.slice(AvmContextInputs.SIZE); } } diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index d951f20fa32..d571234ee25 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -76,7 +76,7 @@ const BaseGasCosts: Record = { [Opcode.FEEPERL2GAS]: DefaultBaseGasCost, [Opcode.FEEPERDAGAS]: DefaultBaseGasCost, [Opcode.TRANSACTIONFEE]: DefaultBaseGasCost, - [Opcode.CONTRACTCALLDEPTH]: DefaultBaseGasCost, + [Opcode.FUNCTIONSELECTOR]: DefaultBaseGasCost, [Opcode.CHAINID]: DefaultBaseGasCost, [Opcode.VERSION]: DefaultBaseGasCost, [Opcode.BLOCKNUMBER]: DefaultBaseGasCost, diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 097a19cdfb4..b8475277283 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -1,3 +1,4 @@ +import { GasFees } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { FunctionSelector } from '@aztec/foundation/abi'; @@ -6,9 +7,11 @@ import { keccak256, pedersenHash, poseidon2Hash, sha256 } from '@aztec/foundatio import { Fq, Fr } from '@aztec/foundation/fields'; import { type Fieldable } from '@aztec/foundation/serialize'; +import { randomInt } from 'crypto'; import { mock } from 'jest-mock-extended'; import { type PublicSideEffectTraceInterface } from '../public/side_effect_trace_interface.js'; +import { type AvmContext } from './avm_context.js'; import { type AvmExecutionEnvironment } from './avm_execution_environment.js'; import { AvmMachineState } from './avm_machine_state.js'; import { type MemoryValue, TypeTag, type Uint8 } from './avm_memory_types.js'; @@ -234,73 +237,58 @@ describe('AVM simulator: transpiled Noir contracts', () => { }); describe('Environment getters', () => { - const testEnvGetter = async (valueName: string, value: any, functionName: string, globalVar: boolean = false) => { - // Execute - let overrides = {}; - if (globalVar === true) { - const globals = initGlobalVariables({ [valueName]: value }); - overrides = { globals }; - } else { - overrides = { [valueName]: value }; - } - const context = initContext({ env: initExecutionEnvironment(overrides) }); - const bytecode = getAvmTestContractBytecode(functionName); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - - const returnData = results.output; - expect(returnData).toEqual([value.toField()]); - }; - - it('address', async () => { - const address = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('address', address, 'get_address'); - }); - - it('storageAddress', async () => { - const storageAddress = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('storageAddress', storageAddress, 'get_storage_address'); + const address = AztecAddress.random(); + const storageAddress = AztecAddress.random(); + const sender = AztecAddress.random(); + const functionSelector = FunctionSelector.random(); + const transactionFee = Fr.random(); + const chainId = Fr.random(); + const version = Fr.random(); + const blockNumber = Fr.random(); + const timestamp = new Fr(randomInt(100000)); // cap timestamp since must fit in u64 + const feePerDaGas = Fr.random(); + const feePerL2Gas = Fr.random(); + const gasFees = new GasFees(feePerDaGas, feePerL2Gas); + const globals = initGlobalVariables({ + chainId, + version, + blockNumber, + timestamp, + gasFees, }); - - it('sender', async () => { - const sender = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('sender', sender, 'get_sender'); - }); - - it('getFeePerL2Gas', async () => { - const fee = new Fr(1); - await testEnvGetter('feePerL2Gas', fee, 'get_fee_per_l2_gas'); + const env = initExecutionEnvironment({ + address, + storageAddress, + sender, + functionSelector, + transactionFee, + globals, }); - - it('getFeePerDaGas', async () => { - const fee = new Fr(1); - await testEnvGetter('feePerDaGas', fee, 'get_fee_per_da_gas'); - }); - - it('getTransactionFee', async () => { - const fee = new Fr(1); - await testEnvGetter('transactionFee', fee, 'get_transaction_fee'); - }); - - it('chainId', async () => { - const chainId = new Fr(1); - await testEnvGetter('chainId', chainId, 'get_chain_id', /*globalVar=*/ true); + let context: AvmContext; + beforeEach(() => { + context = initContext({ env }); }); - it('version', async () => { - const version = new Fr(1); - await testEnvGetter('version', version, 'get_version', /*globalVar=*/ true); - }); + it.each([ + ['address', address.toField(), 'get_address'], + ['storageAddress', storageAddress.toField(), 'get_storage_address'], + ['sender', sender.toField(), 'get_sender'], + ['functionSelector', functionSelector.toField(), 'get_function_selector'], + ['transactionFee', transactionFee.toField(), 'get_transaction_fee'], + ['chainId', chainId.toField(), 'get_chain_id'], + ['version', version.toField(), 'get_version'], + ['blockNumber', blockNumber.toField(), 'get_block_number'], + ['timestamp', timestamp.toField(), 'get_timestamp'], + ['feePerDaGas', feePerDaGas.toField(), 'get_fee_per_da_gas'], + ['feePerL2Gas', feePerL2Gas.toField(), 'get_fee_per_l2_gas'], + ])('%s getter', async (_name: string, value: Fr, functionName: string) => { + const bytecode = getAvmTestContractBytecode(functionName); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - it('blockNumber', async () => { - const blockNumber = new Fr(1); - await testEnvGetter('blockNumber', blockNumber, 'get_block_number', /*globalVar=*/ true); - }); + expect(results.reverted).toBe(false); - it('timestamp', async () => { - const timestamp = new Fr(1); - await testEnvGetter('timestamp', timestamp, 'get_timestamp', /*globalVar=*/ true); + const returnData = results.output; + expect(returnData).toEqual([value]); }); }); diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index fdcb07c8d31..4534dd90587 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -1,4 +1,4 @@ -import { GasFees, GasSettings, GlobalVariables, Header } from '@aztec/circuits.js'; +import { GasFees, GlobalVariables, Header } from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -72,17 +72,14 @@ export function initExecutionEnvironment(overrides?: Partial> = new Map(); - // FIXME: storage ^ should be private, but its value is used in tests for "currentStorageValue" + // FIXME: storage ^ should be private, but its value is used in commitToDB /** * Read a staged value from storage, if it has been previously written to. diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts index 3b447af01a4..abf0b7e3936 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.test.ts @@ -1,5 +1,11 @@ +import { GasFees } from '@aztec/circuits.js'; +import { FunctionSelector as FunctionSelectorType } from '@aztec/foundation/abi'; +import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; +import { randomInt } from 'crypto'; + +import { type AvmContext } from '../avm_context.js'; import { TypeTag } from '../avm_memory_types.js'; import { initContext, initExecutionEnvironment, initGlobalVariables } from '../fixtures/index.js'; import { @@ -8,6 +14,7 @@ import { ChainId, FeePerDAGas, FeePerL2Gas, + FunctionSelector, Sender, StorageAddress, Timestamp, @@ -15,76 +22,84 @@ import { Version, } from './environment_getters.js'; -type EnvInstruction = - | typeof FeePerL2Gas - | typeof FeePerDAGas +type GetterInstruction = | typeof Sender | typeof StorageAddress | typeof Address - | typeof TransactionFee; - -describe.each([ - [FeePerL2Gas, 'feePerL2Gas'], - [FeePerDAGas, 'feePerDaGas'], - [Sender, 'sender'], - [StorageAddress, 'storageAddress'], - [Address, 'address'], - [TransactionFee, 'transactionFee'], -])('Environment getters instructions', (clsValue: EnvInstruction, key: string) => { - it(`${clsValue.name} should (de)serialize correctly`, () => { - const buf = Buffer.from([ - clsValue.opcode, // opcode - 0x01, // indirect - ...Buffer.from('12345678', 'hex'), // dstOffset - ]); - const inst = new clsValue(/*indirect=*/ 0x01, /*dstOffset=*/ 0x12345678); + | typeof FunctionSelector + | typeof TransactionFee + | typeof ChainId + | typeof Version + | typeof BlockNumber + | typeof Timestamp + | typeof FeePerDAGas + | typeof FeePerL2Gas; - expect(clsValue.deserialize(buf)).toEqual(inst); - expect(inst.serialize()).toEqual(buf); +describe('Environment getters', () => { + const address = AztecAddress.random(); + const storageAddress = AztecAddress.random(); + const sender = AztecAddress.random(); + const functionSelector = FunctionSelectorType.random(); + const transactionFee = Fr.random(); + const chainId = Fr.random(); + const version = Fr.random(); + const blockNumber = Fr.random(); + const timestamp = new Fr(randomInt(100000)); // cap timestamp since must fit in u64 + const feePerDaGas = Fr.random(); + const feePerL2Gas = Fr.random(); + const gasFees = new GasFees(feePerDaGas, feePerL2Gas); + const globals = initGlobalVariables({ + chainId, + version, + blockNumber, + timestamp, + gasFees, }); - - it(`${clsValue.name} should read '${key}' correctly`, async () => { - const value = new Fr(123456n); - const instruction = new clsValue(/*indirect=*/ 0, /*dstOffset=*/ 0); - const context = initContext({ env: initExecutionEnvironment({ [key]: value }) }); - - await instruction.execute(context); - - expect(context.machineState.memory.getTag(0)).toBe(TypeTag.FIELD); - const actual = context.machineState.memory.get(0).toFr(); - expect(actual).toEqual(value); + const env = initExecutionEnvironment({ + address, + storageAddress, + sender, + functionSelector, + transactionFee, + globals, }); -}); - -type GlobalsInstruction = typeof ChainId | typeof Version | typeof BlockNumber | typeof Timestamp; -describe.each([ - [ChainId, 'chainId', TypeTag.FIELD], - [Version, 'version', TypeTag.FIELD], - [BlockNumber, 'blockNumber', TypeTag.FIELD], - [Timestamp, 'timestamp', TypeTag.UINT64], -])('Global Variables', (clsValue: GlobalsInstruction, key: string, tag: TypeTag) => { - it(`${clsValue.name} should (de)serialize correctly`, () => { - const buf = Buffer.from([ - clsValue.opcode, // opcode - 0x01, // indirect - ...Buffer.from('12345678', 'hex'), // dstOffset - ]); - const inst = new clsValue(/*indirect=*/ 0x01, /*dstOffset=*/ 0x12345678); - - expect(clsValue.deserialize(buf)).toEqual(inst); - expect(inst.serialize()).toEqual(buf); + let context: AvmContext; + beforeEach(() => { + context = initContext({ env }); }); - it(`${clsValue.name} should read '${key}' correctly`, async () => { - const value = new Fr(123456n); - const instruction = new clsValue(/*indirect=*/ 0, /*dstOffset=*/ 0); - const globals = initGlobalVariables({ [key]: value }); - const context = initContext({ env: initExecutionEnvironment({ globals }) }); + describe.each([ + [Address, address.toField()], + [StorageAddress, storageAddress.toField()], + [Sender, sender.toField()], + [FunctionSelector, functionSelector.toField(), TypeTag.UINT32], + [TransactionFee, transactionFee.toField()], + [ChainId, chainId.toField()], + [Version, version.toField()], + [BlockNumber, blockNumber.toField()], + [Timestamp, timestamp.toField(), TypeTag.UINT64], + [FeePerDAGas, feePerDaGas.toField()], + [FeePerL2Gas, feePerL2Gas.toField()], + ])('Environment getters instructions', (instrClass: GetterInstruction, value: Fr, tag: TypeTag = TypeTag.FIELD) => { + it(`${instrClass.name} should (de)serialize correctly`, () => { + const buf = Buffer.from([ + instrClass.opcode, // opcode + 0x01, // indirect + ...Buffer.from('12345678', 'hex'), // dstOffset + ]); + const instr = new instrClass(/*indirect=*/ 0x01, /*dstOffset=*/ 0x12345678); + + expect(instrClass.deserialize(buf)).toEqual(instr); + expect(instr.serialize()).toEqual(buf); + }); + it(`${instrClass.name} should read '${instrClass.type}' correctly`, async () => { + const instruction = new instrClass(/*indirect=*/ 0, /*dstOffset=*/ 0); - await instruction.execute(context); + await instruction.execute(context); - expect(context.machineState.memory.getTag(0)).toBe(tag); - const actual = context.machineState.memory.get(0).toFr(); - expect(actual).toEqual(value); + expect(context.machineState.memory.getTag(0)).toBe(tag); + const actual = context.machineState.memory.get(0).toFr(); + expect(actual).toEqual(value); + }); }); }); diff --git a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts index 53dbb24cfe5..6373382acf6 100644 --- a/yarn-project/simulator/src/avm/opcodes/environment_getters.ts +++ b/yarn-project/simulator/src/avm/opcodes/environment_getters.ts @@ -1,6 +1,6 @@ import type { AvmContext } from '../avm_context.js'; import type { AvmExecutionEnvironment } from '../avm_execution_environment.js'; -import { Field, type MemoryValue, Uint64 } from '../avm_memory_types.js'; +import { Field, type MemoryValue, Uint32, Uint64 } from '../avm_memory_types.js'; import { Opcode } from '../serialization/instruction_serialization.js'; import { GetterInstruction } from './instruction_impl.js'; @@ -39,21 +39,12 @@ export class Sender extends EnvironmentGetterInstruction { } } -export class FeePerL2Gas extends EnvironmentGetterInstruction { - static type: string = 'FEEPERL2GAS'; - static readonly opcode: Opcode = Opcode.FEEPERL2GAS; - - protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return new Field(env.feePerL2Gas); - } -} - -export class FeePerDAGas extends EnvironmentGetterInstruction { - static type: string = 'FEEPERDAGAS'; - static readonly opcode: Opcode = Opcode.FEEPERDAGAS; +export class FunctionSelector extends EnvironmentGetterInstruction { + static type: string = 'FUNCTIONSELECTOR'; + static readonly opcode: Opcode = Opcode.FUNCTIONSELECTOR; protected getEnvironmentValue(env: AvmExecutionEnvironment) { - return new Field(env.feePerDaGas); + return new Uint32(env.functionSelector.value); } } @@ -101,3 +92,21 @@ export class Timestamp extends EnvironmentGetterInstruction { return new Uint64(env.globals.timestamp.toBigInt()); } } + +export class FeePerL2Gas extends EnvironmentGetterInstruction { + static type: string = 'FEEPERL2GAS'; + static readonly opcode: Opcode = Opcode.FEEPERL2GAS; + + protected getEnvironmentValue(env: AvmExecutionEnvironment) { + return new Field(env.globals.gasFees.feePerL2Gas); + } +} + +export class FeePerDAGas extends EnvironmentGetterInstruction { + static type: string = 'FEEPERDAGAS'; + static readonly opcode: Opcode = Opcode.FEEPERDAGAS; + + protected getEnvironmentValue(env: AvmExecutionEnvironment) { + return new Field(env.globals.gasFees.feePerDaGas); + } +} diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts index 82641334b25..4dd26fb13dd 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts @@ -84,7 +84,7 @@ describe('Bytecode Serialization', () => { /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, - /*temporaryFunctionSelectorOffset=*/ 0xf3345678, + /*functionSelectorOffset=*/ 0xf3345678, ), new StaticCall( /*indirect=*/ 0x01, @@ -95,7 +95,7 @@ describe('Bytecode Serialization', () => { /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, - /*temporaryFunctionSelectorOffset=*/ 0xf3345678, + /*functionSelectorOffset=*/ 0xf3345678, ), ]; const bytecode = Buffer.concat(instructions.map(i => i.serialize())); @@ -119,7 +119,7 @@ describe('Bytecode Serialization', () => { /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, - /*temporaryFunctionSelectorOffset=*/ 0xf3345678, + /*functionSelectorOffset=*/ 0xf3345678, ), new StaticCall( /*indirect=*/ 0x01, @@ -130,7 +130,7 @@ describe('Bytecode Serialization', () => { /*retOffset=*/ 0xd2345678, /*retSize=*/ 0xe2345678, /*successOffset=*/ 0xf2345678, - /*temporaryFunctionSelectorOffset=*/ 0xf3345678, + /*functionSelectorOffset=*/ 0xf3345678, ), ]; diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index f3afe05e088..c011b3a33cb 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -21,6 +21,7 @@ import { FeePerDAGas, FeePerL2Gas, FieldDiv, + FunctionSelector, GetContractInstance, InternalCall, InternalReturn, @@ -85,16 +86,16 @@ const INSTRUCTION_SET = () => [Address.opcode, Address], [StorageAddress.opcode, StorageAddress], [Sender.opcode, Sender], - [FeePerL2Gas.opcode, FeePerL2Gas], - [FeePerDAGas.opcode, FeePerDAGas], + [FunctionSelector.opcode, FunctionSelector], [TransactionFee.opcode, TransactionFee], - //[Contractcalldepth.opcode, Contractcalldepth], // Execution Environment - Globals [ChainId.opcode, ChainId], [Version.opcode, Version], [BlockNumber.opcode, BlockNumber], [Timestamp.opcode, Timestamp], //[Coinbase.opcode, Coinbase], + [FeePerL2Gas.opcode, FeePerL2Gas], + [FeePerDAGas.opcode, FeePerDAGas], //[Blockl2gaslimit.opcode, Blockl2gaslimit], //[Blockdagaslimit.opcode, Blockdagaslimit], // Execution Environment - Calldata diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index 0a4ee888fcf..27aa64d3e1f 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -27,15 +27,15 @@ export enum Opcode { ADDRESS, STORAGEADDRESS, SENDER, - FEEPERL2GAS, - FEEPERDAGAS, + FUNCTIONSELECTOR, TRANSACTIONFEE, - CONTRACTCALLDEPTH, CHAINID, VERSION, BLOCKNUMBER, TIMESTAMP, COINBASE, + FEEPERL2GAS, + FEEPERDAGAS, BLOCKL2GASLIMIT, BLOCKDAGASLIMIT, CALLDATACOPY, diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index 3eefbba2dea..9a524c458c8 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -1,13 +1,5 @@ import { type AvmSimulationStats } from '@aztec/circuit-types/stats'; -import { - Fr, - Gas, - type GasSettings, - type GlobalVariables, - type Header, - type Nullifier, - type TxContext, -} from '@aztec/circuits.js'; +import { Fr, Gas, type GlobalVariables, type Header, type Nullifier, type TxContext } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; @@ -18,7 +10,7 @@ import { AvmSimulator } from '../avm/avm_simulator.js'; import { HostStorage } from '../avm/journal/host_storage.js'; import { AvmPersistableStateManager } from '../avm/journal/index.js'; import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db_interfaces.js'; -import { type PublicExecutionRequest, type PublicExecutionResult, checkValidStaticCall } from './execution.js'; +import { type PublicExecutionRequest, type PublicExecutionResult } from './execution.js'; import { PublicSideEffectTrace } from './side_effect_trace.js'; /** @@ -26,7 +18,7 @@ import { PublicSideEffectTrace } from './side_effect_trace.js'; */ export class PublicExecutor { constructor( - private readonly stateDb: PublicStateDB, + private readonly publicStorageDB: PublicStateDB, private readonly contractsDb: PublicContractsDB, private readonly commitmentsDb: CommitmentsDB, private readonly header: Header, @@ -49,7 +41,7 @@ export class PublicExecutor { executionRequest: PublicExecutionRequest, globalVariables: GlobalVariables, availableGas: Gas, - txContext: TxContext, + _txContext: TxContext, pendingSiloedNullifiers: Nullifier[], transactionFee: Fr = Fr.ZERO, startSideEffectCounter: number = 0, @@ -61,7 +53,7 @@ export class PublicExecutor { PublicExecutor.log.verbose(`[AVM] Executing public external function ${fnName}.`); const timer = new Timer(); - const hostStorage = new HostStorage(this.stateDb, this.contractsDb, this.commitmentsDb); + const hostStorage = new HostStorage(this.publicStorageDB, this.contractsDb, this.commitmentsDb); const trace = new PublicSideEffectTrace(startSideEffectCounter); const avmPersistableState = AvmPersistableStateManager.newWithPendingSiloedNullifiers( hostStorage, @@ -73,7 +65,6 @@ export class PublicExecutor { executionRequest, this.header, globalVariables, - txContext.gasSettings, transactionFee, ); @@ -83,7 +74,7 @@ export class PublicExecutor { const avmResult = await simulator.execute(); const bytecode = simulator.getBytecode()!; - // Commit the journals state to the DBs since this is a top-level execution. + // Commit the public storage state to the DBs since this is a top-level execution. // Observe that this will write all the state changes to the DBs, not only the latest for each slot. // However, the underlying DB keep a cache and will only write the latest state to disk. // TODO(dbanks12): this should be unnecessary here or should be exposed by state manager @@ -113,18 +104,6 @@ export class PublicExecutor { // (which counts the request itself) ); - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5818): is this really needed? - // should already be handled in simulation. - if (executionRequest.callContext.isStaticCall) { - checkValidStaticCall( - publicExecutionResult.newNoteHashes, - publicExecutionResult.newNullifiers, - publicExecutionResult.contractStorageUpdateRequests, - publicExecutionResult.newL2ToL1Messages, - publicExecutionResult.unencryptedLogs, - ); - } - return publicExecutionResult; } } @@ -140,23 +119,19 @@ function createAvmExecutionEnvironment( executionRequest: PublicExecutionRequest, header: Header, globalVariables: GlobalVariables, - gasSettings: GasSettings, transactionFee: Fr, ): AvmExecutionEnvironment { return new AvmExecutionEnvironment( executionRequest.contractAddress, executionRequest.callContext.storageContractAddress, executionRequest.callContext.msgSender, - globalVariables.gasFees.feePerL2Gas, - globalVariables.gasFees.feePerDaGas, + executionRequest.functionSelector, /*contractCallDepth=*/ Fr.zero(), + transactionFee, header, globalVariables, executionRequest.callContext.isStaticCall, executionRequest.callContext.isDelegateCall, executionRequest.args, - gasSettings, - transactionFee, - executionRequest.functionSelector, ); }