diff --git a/barretenberg/cpp/pil/avm/gas.pil b/barretenberg/cpp/pil/avm/gas.pil index 476d9bd569c..ec344c393ee 100644 --- a/barretenberg/cpp/pil/avm/gas.pil +++ b/barretenberg/cpp/pil/avm/gas.pil @@ -57,8 +57,9 @@ namespace main(256); sel_execution_row * (1 - sel_op_external_call) * (l2_gas_remaining' - l2_gas_remaining + base_l2_gas_op_cost + (dyn_l2_gas_op_cost * dyn_gas_multiplier)) = 0; #[DA_GAS_REMAINING_DECREMENT_NOT_CALL] sel_execution_row * (1 - sel_op_external_call) * (da_gas_remaining' - da_gas_remaining + base_da_gas_op_cost + (dyn_da_gas_op_cost * dyn_gas_multiplier)) = 0; - // We need to special-case external calls - // TODO: for the moment, unconstrained. + // We need to special-case external calls since the gas cost format is + // base_l2 + nested_call_cost + dyn_gas_cost * dyn_gas_multiplier. + // TODO: Unconstrained until CALL is properly implemented. // #[L2_GAS_REMAINING_DECREMENT_CALL] // sel_execution_row * sel_op_external_call * (l2_gas_remaining' - l2_gas_remaining + base_l2_gas_op_cost + (dyn_l2_gas_op_cost * dyn_gas_multiplier)) = 0; // #[DA_GAS_REMAINING_DECREMENT_CALL] diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/common.test.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/common.test.hpp index 9f874ab9cc8..e7fc9a715e9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/common.test.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/common.test.hpp @@ -13,5 +13,5 @@ #include #include -static const uint32_t DEFAULT_INITIAL_DA_GAS = 100000; -static const uint32_t DEFAULT_INITIAL_L2_GAS = 100000; \ No newline at end of file +static const uint32_t DEFAULT_INITIAL_DA_GAS = 1000000; +static const uint32_t DEFAULT_INITIAL_L2_GAS = 1000000; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp index f548146b07a..1710120b7dc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp @@ -30,6 +30,11 @@ static const size_t KERNEL_OUTPUTS_VALUE = 1; static const size_t KERNEL_OUTPUTS_SIDE_EFFECT_COUNTER = 2; static const size_t KERNEL_OUTPUTS_METADATA = 3; +constexpr size_t L2_HI_GAS_COUNTS_IDX = 0; +constexpr size_t L2_LO_GAS_COUNTS_IDX = 1; +constexpr size_t DA_HI_GAS_COUNTS_IDX = 2; +constexpr size_t DA_LO_GAS_COUNTS_IDX = 3; + // Number of rows static const size_t AVM_TRACE_SIZE = 1 << 18; enum class IntermRegister : uint32_t { IA = 0, IB = 1, IC = 2, ID = 3 }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp index a091c319f71..996ddc00fdd 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp @@ -1,85 +1,92 @@ #include "barretenberg/vm/avm/trace/fixed_gas.hpp" #include "barretenberg/vm/avm/trace/opcode.hpp" +#include "barretenberg/vm/aztec_constants.hpp" #include namespace bb::avm_trace { namespace { -const auto DEFAULT_COST = FixedGasTable::GasRow{ - .base_l2_gas_fixed_table = 10, - .base_da_gas_fixed_table = 0, - .dyn_l2_gas_fixed_table = 0, - .dyn_da_gas_fixed_table = 0, -}; +constexpr auto make_cost(uint16_t l2_base, uint16_t da_base, uint16_t l2_dyn, uint16_t da_dyn) +{ + return FixedGasTable::GasRow{ + .base_l2_gas_fixed_table = l2_base, + .base_da_gas_fixed_table = da_base, + .dyn_l2_gas_fixed_table = l2_dyn, + .dyn_da_gas_fixed_table = da_dyn, + }; +} const std::unordered_map GAS_COST_TABLE = { - { OpCode::ADD, DEFAULT_COST }, - { OpCode::SUB, DEFAULT_COST }, - { OpCode::MUL, DEFAULT_COST }, - { OpCode::DIV, DEFAULT_COST }, - { OpCode::FDIV, DEFAULT_COST }, - { OpCode::EQ, DEFAULT_COST }, - { OpCode::LT, DEFAULT_COST }, - { OpCode::LTE, DEFAULT_COST }, - { OpCode::AND, DEFAULT_COST }, - { OpCode::OR, DEFAULT_COST }, - { OpCode::XOR, DEFAULT_COST }, - { OpCode::NOT, DEFAULT_COST }, - { OpCode::SHL, DEFAULT_COST }, - { OpCode::SHR, DEFAULT_COST }, - { OpCode::CAST, DEFAULT_COST }, - { OpCode::ADDRESS, DEFAULT_COST }, - { OpCode::STORAGEADDRESS, DEFAULT_COST }, - { OpCode::SENDER, DEFAULT_COST }, - { OpCode::FUNCTIONSELECTOR, DEFAULT_COST }, - { OpCode::TRANSACTIONFEE, DEFAULT_COST }, - { OpCode::CHAINID, DEFAULT_COST }, - { OpCode::VERSION, DEFAULT_COST }, - { OpCode::BLOCKNUMBER, DEFAULT_COST }, - { OpCode::TIMESTAMP, DEFAULT_COST }, - { OpCode::COINBASE, DEFAULT_COST }, - { OpCode::FEEPERL2GAS, DEFAULT_COST }, - { OpCode::FEEPERDAGAS, DEFAULT_COST }, - { OpCode::BLOCKL2GASLIMIT, DEFAULT_COST }, - { OpCode::BLOCKDAGASLIMIT, DEFAULT_COST }, - { OpCode::CALLDATACOPY, DEFAULT_COST }, - { OpCode::L2GASLEFT, DEFAULT_COST }, - { OpCode::DAGASLEFT, DEFAULT_COST }, - { OpCode::JUMP, DEFAULT_COST }, - { OpCode::JUMPI, DEFAULT_COST }, - { OpCode::INTERNALCALL, DEFAULT_COST }, - { OpCode::INTERNALRETURN, DEFAULT_COST }, - { OpCode::SET, DEFAULT_COST }, - { OpCode::MOV, DEFAULT_COST }, - { OpCode::CMOV, DEFAULT_COST }, - { OpCode::SLOAD, DEFAULT_COST }, - { OpCode::SSTORE, DEFAULT_COST }, - { OpCode::NOTEHASHEXISTS, DEFAULT_COST }, - { OpCode::EMITNOTEHASH, DEFAULT_COST }, - { OpCode::NULLIFIEREXISTS, DEFAULT_COST }, - { OpCode::EMITNULLIFIER, DEFAULT_COST }, - { OpCode::L1TOL2MSGEXISTS, DEFAULT_COST }, - { OpCode::HEADERMEMBER, DEFAULT_COST }, - { OpCode::GETCONTRACTINSTANCE, DEFAULT_COST }, - { OpCode::EMITUNENCRYPTEDLOG, DEFAULT_COST }, - { OpCode::SENDL2TOL1MSG, DEFAULT_COST }, - { OpCode::CALL, DEFAULT_COST }, - { OpCode::STATICCALL, DEFAULT_COST }, - { OpCode::DELEGATECALL, DEFAULT_COST }, - { OpCode::RETURN, DEFAULT_COST }, - { OpCode::REVERT, DEFAULT_COST }, - { OpCode::DEBUGLOG, DEFAULT_COST }, - { OpCode::KECCAK, DEFAULT_COST }, - { OpCode::POSEIDON2, DEFAULT_COST }, - { OpCode::SHA256, DEFAULT_COST }, - { OpCode::PEDERSEN, DEFAULT_COST }, - { OpCode::ECADD, DEFAULT_COST }, - { OpCode::MSM, DEFAULT_COST }, - { OpCode::PEDERSENCOMMITMENT, DEFAULT_COST }, - { OpCode::TORADIXLE, DEFAULT_COST }, - { OpCode::SHA256COMPRESSION, DEFAULT_COST }, - { OpCode::KECCAKF1600, DEFAULT_COST }, + { OpCode::ADD, make_cost(AVM_ADD_BASE_L2_GAS, 0, AVM_ADD_DYN_L2_GAS, 0) }, + { OpCode::SUB, make_cost(AVM_SUB_BASE_L2_GAS, 0, AVM_SUB_DYN_L2_GAS, 0) }, + { OpCode::MUL, make_cost(AVM_MUL_BASE_L2_GAS, 0, AVM_MUL_DYN_L2_GAS, 0) }, + { OpCode::DIV, make_cost(AVM_DIV_BASE_L2_GAS, 0, AVM_DIV_DYN_L2_GAS, 0) }, + { OpCode::FDIV, make_cost(AVM_FDIV_BASE_L2_GAS, 0, AVM_FDIV_DYN_L2_GAS, 0) }, + { OpCode::EQ, make_cost(AVM_EQ_BASE_L2_GAS, 0, AVM_EQ_DYN_L2_GAS, 0) }, + { OpCode::LT, make_cost(AVM_LT_BASE_L2_GAS, 0, AVM_LT_DYN_L2_GAS, 0) }, + { OpCode::LTE, make_cost(AVM_LTE_BASE_L2_GAS, 0, AVM_LTE_DYN_L2_GAS, 0) }, + { OpCode::AND, make_cost(AVM_AND_BASE_L2_GAS, 0, AVM_AND_DYN_L2_GAS, 0) }, + { OpCode::OR, make_cost(AVM_OR_BASE_L2_GAS, 0, AVM_OR_DYN_L2_GAS, 0) }, + { OpCode::XOR, make_cost(AVM_XOR_BASE_L2_GAS, 0, AVM_XOR_DYN_L2_GAS, 0) }, + { OpCode::NOT, make_cost(AVM_NOT_BASE_L2_GAS, 0, AVM_NOT_DYN_L2_GAS, 0) }, + { OpCode::SHL, make_cost(AVM_SHL_BASE_L2_GAS, 0, AVM_SHL_DYN_L2_GAS, 0) }, + { OpCode::SHR, make_cost(AVM_SHR_BASE_L2_GAS, 0, AVM_SHR_DYN_L2_GAS, 0) }, + { OpCode::CAST, make_cost(AVM_CAST_BASE_L2_GAS, 0, AVM_CAST_DYN_L2_GAS, 0) }, + { OpCode::ADDRESS, make_cost(AVM_ADDRESS_BASE_L2_GAS, 0, AVM_ADDRESS_DYN_L2_GAS, 0) }, + { OpCode::STORAGEADDRESS, make_cost(AVM_STORAGEADDRESS_BASE_L2_GAS, 0, AVM_STORAGEADDRESS_DYN_L2_GAS, 0) }, + { OpCode::SENDER, make_cost(AVM_SENDER_BASE_L2_GAS, 0, AVM_SENDER_DYN_L2_GAS, 0) }, + { OpCode::FUNCTIONSELECTOR, make_cost(AVM_FUNCTIONSELECTOR_BASE_L2_GAS, 0, AVM_FUNCTIONSELECTOR_DYN_L2_GAS, 0) }, + { OpCode::TRANSACTIONFEE, make_cost(AVM_TRANSACTIONFEE_BASE_L2_GAS, 0, AVM_TRANSACTIONFEE_DYN_L2_GAS, 0) }, + { OpCode::CHAINID, make_cost(AVM_CHAINID_BASE_L2_GAS, 0, AVM_CHAINID_DYN_L2_GAS, 0) }, + { OpCode::VERSION, make_cost(AVM_VERSION_BASE_L2_GAS, 0, AVM_VERSION_DYN_L2_GAS, 0) }, + { OpCode::BLOCKNUMBER, make_cost(AVM_BLOCKNUMBER_BASE_L2_GAS, 0, AVM_BLOCKNUMBER_DYN_L2_GAS, 0) }, + { OpCode::TIMESTAMP, make_cost(AVM_TIMESTAMP_BASE_L2_GAS, 0, AVM_TIMESTAMP_DYN_L2_GAS, 0) }, + { OpCode::COINBASE, make_cost(AVM_COINBASE_BASE_L2_GAS, 0, AVM_COINBASE_DYN_L2_GAS, 0) }, + { OpCode::FEEPERL2GAS, make_cost(AVM_FEEPERL2GAS_BASE_L2_GAS, 0, AVM_FEEPERL2GAS_DYN_L2_GAS, 0) }, + { OpCode::FEEPERDAGAS, make_cost(AVM_FEEPERDAGAS_BASE_L2_GAS, 0, AVM_FEEPERDAGAS_DYN_L2_GAS, 0) }, + { OpCode::BLOCKL2GASLIMIT, make_cost(AVM_BLOCKL2GASLIMIT_BASE_L2_GAS, 0, AVM_BLOCKL2GASLIMIT_DYN_L2_GAS, 0) }, + { OpCode::BLOCKDAGASLIMIT, make_cost(AVM_BLOCKDAGASLIMIT_BASE_L2_GAS, 0, AVM_BLOCKDAGASLIMIT_DYN_L2_GAS, 0) }, + { OpCode::CALLDATACOPY, make_cost(AVM_CALLDATACOPY_BASE_L2_GAS, 0, AVM_CALLDATACOPY_DYN_L2_GAS, 0) }, + { OpCode::L2GASLEFT, make_cost(AVM_L2GASLEFT_BASE_L2_GAS, 0, AVM_L2GASLEFT_DYN_L2_GAS, 0) }, + { OpCode::DAGASLEFT, make_cost(AVM_DAGASLEFT_BASE_L2_GAS, 0, AVM_DAGASLEFT_DYN_L2_GAS, 0) }, + { OpCode::JUMP, make_cost(AVM_JUMP_BASE_L2_GAS, 0, AVM_JUMP_DYN_L2_GAS, 0) }, + { OpCode::JUMPI, make_cost(AVM_JUMPI_BASE_L2_GAS, 0, AVM_JUMPI_DYN_L2_GAS, 0) }, + { OpCode::INTERNALCALL, make_cost(AVM_INTERNALCALL_BASE_L2_GAS, 0, AVM_INTERNALCALL_DYN_L2_GAS, 0) }, + { OpCode::INTERNALRETURN, make_cost(AVM_INTERNALRETURN_BASE_L2_GAS, 0, AVM_INTERNALRETURN_DYN_L2_GAS, 0) }, + { OpCode::SET, make_cost(AVM_SET_BASE_L2_GAS, 0, AVM_SET_DYN_L2_GAS, 0) }, + { OpCode::MOV, make_cost(AVM_MOV_BASE_L2_GAS, 0, AVM_MOV_DYN_L2_GAS, 0) }, + { OpCode::CMOV, make_cost(AVM_CMOV_BASE_L2_GAS, 0, AVM_CMOV_DYN_L2_GAS, 0) }, + { OpCode::SLOAD, make_cost(AVM_SLOAD_BASE_L2_GAS, 0, AVM_SLOAD_DYN_L2_GAS, 0) }, + { OpCode::SSTORE, make_cost(AVM_SSTORE_BASE_L2_GAS, 0, AVM_SSTORE_DYN_L2_GAS, 0) }, + { OpCode::NOTEHASHEXISTS, make_cost(AVM_NOTEHASHEXISTS_BASE_L2_GAS, 0, AVM_NOTEHASHEXISTS_DYN_L2_GAS, 0) }, + { OpCode::EMITNOTEHASH, make_cost(AVM_EMITNOTEHASH_BASE_L2_GAS, 0, AVM_EMITNOTEHASH_DYN_L2_GAS, 0) }, + { OpCode::NULLIFIEREXISTS, make_cost(AVM_NULLIFIEREXISTS_BASE_L2_GAS, 0, AVM_NULLIFIEREXISTS_DYN_L2_GAS, 0) }, + { OpCode::EMITNULLIFIER, make_cost(AVM_EMITNULLIFIER_BASE_L2_GAS, 0, AVM_EMITNULLIFIER_DYN_L2_GAS, 0) }, + { OpCode::L1TOL2MSGEXISTS, make_cost(AVM_L1TOL2MSGEXISTS_BASE_L2_GAS, 0, AVM_L1TOL2MSGEXISTS_DYN_L2_GAS, 0) }, + { OpCode::HEADERMEMBER, make_cost(AVM_HEADERMEMBER_BASE_L2_GAS, 0, AVM_HEADERMEMBER_DYN_L2_GAS, 0) }, + { OpCode::GETCONTRACTINSTANCE, + make_cost(AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, 0, AVM_GETCONTRACTINSTANCE_DYN_L2_GAS, 0) }, + { OpCode::EMITUNENCRYPTEDLOG, + make_cost(AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS, 0, AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS, 0) }, + { OpCode::SENDL2TOL1MSG, make_cost(AVM_SENDL2TOL1MSG_BASE_L2_GAS, 0, AVM_SENDL2TOL1MSG_DYN_L2_GAS, 0) }, + { OpCode::CALL, make_cost(AVM_CALL_BASE_L2_GAS, 0, AVM_CALL_DYN_L2_GAS, 0) }, + { OpCode::STATICCALL, make_cost(AVM_STATICCALL_BASE_L2_GAS, 0, AVM_STATICCALL_DYN_L2_GAS, 0) }, + { OpCode::DELEGATECALL, make_cost(AVM_DELEGATECALL_BASE_L2_GAS, 0, AVM_DELEGATECALL_DYN_L2_GAS, 0) }, + { OpCode::RETURN, make_cost(AVM_RETURN_BASE_L2_GAS, 0, AVM_RETURN_DYN_L2_GAS, 0) }, + { OpCode::REVERT, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) }, + { OpCode::DEBUGLOG, make_cost(AVM_DEBUGLOG_BASE_L2_GAS, 0, AVM_DEBUGLOG_DYN_L2_GAS, 0) }, + { OpCode::KECCAK, make_cost(AVM_KECCAK_BASE_L2_GAS, 0, AVM_KECCAK_DYN_L2_GAS, 0) }, + { OpCode::POSEIDON2, make_cost(AVM_POSEIDON2_BASE_L2_GAS, 0, AVM_POSEIDON2_DYN_L2_GAS, 0) }, + { OpCode::SHA256, make_cost(AVM_SHA256_BASE_L2_GAS, 0, AVM_SHA256_DYN_L2_GAS, 0) }, + { OpCode::PEDERSEN, make_cost(AVM_PEDERSEN_BASE_L2_GAS, 0, AVM_PEDERSEN_DYN_L2_GAS, 0) }, + { OpCode::ECADD, make_cost(AVM_ECADD_BASE_L2_GAS, 0, AVM_ECADD_DYN_L2_GAS, 0) }, + { OpCode::MSM, make_cost(AVM_MSM_BASE_L2_GAS, 0, AVM_MSM_DYN_L2_GAS, 0) }, + { OpCode::PEDERSENCOMMITMENT, + make_cost(AVM_PEDERSENCOMMITMENT_BASE_L2_GAS, 0, AVM_PEDERSENCOMMITMENT_DYN_L2_GAS, 0) }, + { OpCode::TORADIXLE, make_cost(AVM_TORADIXLE_BASE_L2_GAS, 0, AVM_TORADIXLE_DYN_L2_GAS, 0) }, + { OpCode::SHA256COMPRESSION, make_cost(AVM_SHA256COMPRESSION_BASE_L2_GAS, 0, AVM_SHA256COMPRESSION_DYN_L2_GAS, 0) }, + { OpCode::KECCAKF1600, make_cost(AVM_KECCAKF1600_BASE_L2_GAS, 0, AVM_KECCAKF1600_DYN_L2_GAS, 0) }, }; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp index d3c9b4b784c..90af2d5baf8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp @@ -13,11 +13,6 @@ void AvmGasTraceBuilder::reset() gas_trace.clear(); } -std::vector AvmGasTraceBuilder::finalize() -{ - return std::move(gas_trace); -} - void AvmGasTraceBuilder::set_initial_gas(uint32_t l2_gas, uint32_t da_gas) { initial_l2_gas = l2_gas; @@ -28,12 +23,12 @@ void AvmGasTraceBuilder::set_initial_gas(uint32_t l2_gas, uint32_t da_gas) remaining_da_gas = da_gas; } -uint32_t AvmGasTraceBuilder::get_l2_gas_left() +uint32_t AvmGasTraceBuilder::get_l2_gas_left() const { return gas_trace.back().remaining_l2_gas; } -uint32_t AvmGasTraceBuilder::get_da_gas_left() +uint32_t AvmGasTraceBuilder::get_da_gas_left() const { return gas_trace.back().remaining_da_gas; } @@ -103,4 +98,83 @@ void AvmGasTraceBuilder::constrain_gas_for_external_call(uint32_t clk, }); } +void AvmGasTraceBuilder::finalize(std::vector>& main_trace) +{ + // Add the gas cost table to the main trace + // TODO: do i need a way to produce an interupt that will stop the execution of the trace when the gas left + // becomes zero in the gas_trace_builder Does all of the gas trace information need to be added to this main + // machine????? + + // Add the gas accounting for each row + // We can assume that the gas trace will never be larger than the main trace + // We infer that a row is active for gas (.main_gas_cost_active = 1) based on the presence + // of a gas entry row. + // Set the initial gas + auto& first_opcode_row = main_trace.at(0); + first_opcode_row.main_l2_gas_remaining = initial_l2_gas; + first_opcode_row.main_da_gas_remaining = initial_da_gas; + + uint32_t current_clk = 1; + uint32_t current_l2_gas_remaining = initial_l2_gas; + uint32_t current_da_gas_remaining = initial_da_gas; + + // Assume that gas_trace entries are ordered by a strictly increasing clk sequence. + for (auto const& gas_entry : gas_trace) { + // There should be no gaps in the gas_trace. + ASSERT(gas_entry.clk == current_clk); + + auto& dest = main_trace.at(gas_entry.clk - 1); + auto& next = main_trace.at(gas_entry.clk); + + // Write each of the relevant gas accounting values + dest.main_opcode_val = static_cast(gas_entry.opcode); + dest.main_base_l2_gas_op_cost = gas_entry.base_l2_gas_cost; + dest.main_base_da_gas_op_cost = gas_entry.base_da_gas_cost; + dest.main_dyn_l2_gas_op_cost = gas_entry.dyn_l2_gas_cost; + dest.main_dyn_da_gas_op_cost = gas_entry.dyn_da_gas_cost; + dest.main_dyn_gas_multiplier = gas_entry.dyn_gas_multiplier; + + // If gas remaining is increasing, it means we underflowed in uint32_t + bool l2_out_of_gas = current_l2_gas_remaining < gas_entry.remaining_l2_gas; + bool da_out_of_gas = current_da_gas_remaining < gas_entry.remaining_da_gas; + + uint32_t abs_l2_gas_remaining = l2_out_of_gas ? -gas_entry.remaining_l2_gas : gas_entry.remaining_l2_gas; + uint32_t abs_da_gas_remaining = da_out_of_gas ? -gas_entry.remaining_da_gas : gas_entry.remaining_da_gas; + + dest.main_abs_l2_rem_gas_hi = abs_l2_gas_remaining >> 16; + dest.main_abs_da_rem_gas_hi = abs_da_gas_remaining >> 16; + dest.main_abs_l2_rem_gas_lo = static_cast(abs_l2_gas_remaining); + dest.main_abs_da_rem_gas_lo = static_cast(abs_da_gas_remaining); + + // lookups counting + rem_gas_rng_check_counts[L2_HI_GAS_COUNTS_IDX][static_cast(dest.main_abs_l2_rem_gas_hi)]++; + rem_gas_rng_check_counts[L2_LO_GAS_COUNTS_IDX][static_cast(dest.main_abs_l2_rem_gas_lo)]++; + rem_gas_rng_check_counts[DA_HI_GAS_COUNTS_IDX][static_cast(dest.main_abs_da_rem_gas_hi)]++; + rem_gas_rng_check_counts[DA_LO_GAS_COUNTS_IDX][static_cast(dest.main_abs_da_rem_gas_lo)]++; + + dest.main_l2_out_of_gas = static_cast(l2_out_of_gas); + dest.main_da_out_of_gas = static_cast(da_out_of_gas); + + current_l2_gas_remaining = gas_entry.remaining_l2_gas; + current_da_gas_remaining = gas_entry.remaining_da_gas; + next.main_l2_gas_remaining = + l2_out_of_gas ? FF::modulus - uint256_t(abs_l2_gas_remaining) : current_l2_gas_remaining; + next.main_da_gas_remaining = + da_out_of_gas ? FF::modulus - uint256_t(abs_da_gas_remaining) : current_da_gas_remaining; + + current_clk++; + } + + reset(); +} + +void AvmGasTraceBuilder::finalize_lookups(std::vector>& main_trace) +{ + // Finalise gas left lookup counts + // TODO: find the right place for this. This is not really over the main trace, but over the opcode trace. + for (auto const& [opcode, count] : gas_opcode_lookup_counter) { + main_trace.at(static_cast(opcode)).lookup_opcode_gas_counts = count; + } +} + } // namespace bb::avm_trace \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp index 915f74bb71d..412343933f8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp @@ -1,7 +1,9 @@ #pragma once #include +#include +#include "barretenberg/vm/avm/generated/full_row.hpp" #include "barretenberg/vm/avm/trace/common.hpp" #include "barretenberg/vm/avm/trace/opcode.hpp" @@ -21,14 +23,14 @@ class AvmGasTraceBuilder { uint32_t remaining_da_gas = 0; }; - // Counts each time an opcode is read - // opcode -> count - std::unordered_map gas_opcode_lookup_counter; - AvmGasTraceBuilder() = default; + size_t size() const { return gas_trace.size(); } void reset(); - std::vector finalize(); + // These two have to be separate, because the lookup counts have to be + // finalized after the extra first row gets added. + void finalize(std::vector>& trace); + void finalize_lookups(std::vector>& trace); void constrain_gas(uint32_t clk, OpCode opcode, uint32_t dyn_gas_multiplier = 0); void constrain_gas_for_external_call(uint32_t clk, @@ -37,15 +39,19 @@ class AvmGasTraceBuilder { uint32_t nested_da_gas_cost); void set_initial_gas(uint32_t l2_gas, uint32_t da_gas); - uint32_t get_l2_gas_left(); - uint32_t get_da_gas_left(); + uint32_t get_l2_gas_left() const; + uint32_t get_da_gas_left() const; + + // Counts each time an opcode is read: opcode -> count + std::unordered_map gas_opcode_lookup_counter; + // Data structure to collect all lookup counts pertaining to 16-bit range checks related to remaining gas + std::array, 4> rem_gas_rng_check_counts; + private: std::vector gas_trace; uint32_t initial_l2_gas = 0; uint32_t initial_da_gas = 0; - - private: uint32_t remaining_l2_gas = 0; uint32_t remaining_da_gas = 0; }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index fe6d4382dc0..680a61995d8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -36,11 +36,6 @@ namespace bb::avm_trace { **************************************************************************************************/ namespace { -constexpr size_t L2_HI_GAS_COUNTS_IDX = 0; -constexpr size_t L2_LO_GAS_COUNTS_IDX = 1; -constexpr size_t DA_HI_GAS_COUNTS_IDX = 2; -constexpr size_t DA_LO_GAS_COUNTS_IDX = 3; - // WARNING: FOR TESTING ONLY // Generates the lookup table for the range checks without doing a full 2**16 rows uint32_t finalize_rng_chks_for_testing( @@ -2534,7 +2529,7 @@ void AvmTraceBuilder::op_call(uint8_t indirect, uint32_t gas_offset, uint32_t addr_offset, uint32_t args_offset, - uint32_t args_size, + uint32_t args_size_offset, uint32_t ret_offset, uint32_t ret_size, uint32_t success_offset, @@ -2543,18 +2538,14 @@ void AvmTraceBuilder::op_call(uint8_t indirect, auto clk = static_cast(main_trace.size()) + 1; const ExternalCallHint& hint = execution_hints.externalcall_hints.at(external_call_counter); - gas_trace_builder.constrain_gas_for_external_call(clk, - /*dyn_gas_multiplier=*/0, - static_cast(hint.l2_gas_used), - static_cast(hint.da_gas_used)); - auto [resolved_gas_offset, resolved_addr_offset, resolved_args_offset, - resolved_args_size, + resolved_args_size_offset, resolved_ret_offset, resolved_success_offset] = - unpack_indirects<6>(indirect, { gas_offset, addr_offset, args_offset, args_size, ret_offset, success_offset }); + unpack_indirects<6>(indirect, + { gas_offset, addr_offset, args_offset, args_size_offset, ret_offset, success_offset }); // Should read the address next to read_gas as well (tuple of gas values (l2Gas, daGas)) auto read_gas_l2 = constrained_read_from_memory( @@ -2567,6 +2558,14 @@ void AvmTraceBuilder::op_call(uint8_t indirect, call_ptr, clk, resolved_args_offset, AvmMemoryTag::FF, AvmMemoryTag::U0, IntermRegister::ID); bool tag_match = read_gas_l2.tag_match && read_gas_da.tag_match && read_addr.tag_match && read_args.tag_match; + // TODO: constrain this + auto args_size = static_cast(unconstrained_read_from_memory(resolved_args_size_offset)); + + gas_trace_builder.constrain_gas_for_external_call(clk, + /*dyn_gas_multiplier=*/args_size + ret_size, + static_cast(hint.l2_gas_used), + static_cast(hint.da_gas_used)); + // We read the input and output addresses in one row as they should contain FF elements main_trace.push_back(Row{ .main_clk = clk, @@ -3419,7 +3418,6 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) auto poseidon2_trace = poseidon2_trace_builder.finalize(); auto keccak_trace = keccak_trace_builder.finalize(); auto pedersen_trace = pedersen_trace_builder.finalize(); - auto gas_trace = gas_trace_builder.finalize(); auto slice_trace = slice_trace_builder.finalize(); const auto& fixed_gas_table = FixedGasTable::get(); size_t mem_trace_size = mem_trace.size(); @@ -3431,7 +3429,7 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) size_t keccak_trace_size = keccak_trace.size(); size_t pedersen_trace_size = pedersen_trace.size(); size_t bin_trace_size = bin_trace_builder.size(); - size_t gas_trace_size = gas_trace.size(); + size_t gas_trace_size = gas_trace_builder.size(); size_t slice_trace_size = slice_trace.size(); // Data structure to collect all lookup counts pertaining to 16-bit/32-bit range checks in memory trace @@ -3831,79 +3829,14 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) * GAS TRACE INCLUSION **********************************************************************************************/ - // Add the gas cost table to the main trace - // TODO: do i need a way to produce an interupt that will stop the execution of the trace when the gas left - // becomes zero in the gas_trace_builder Does all of the gas trace information need to be added to this main - // machine????? - - // Add the gas accounting for each row - // We can assume that the gas trace will never be larger than the main trace - // We infer that a row is active for gas (.main_gas_cost_active = 1) based on the presence - // of a gas entry row. - // Set the initial gas - auto& first_opcode_row = main_trace.at(0); - first_opcode_row.main_l2_gas_remaining = gas_trace_builder.initial_l2_gas; - first_opcode_row.main_da_gas_remaining = gas_trace_builder.initial_da_gas; - uint32_t current_clk = 1; - uint32_t current_l2_gas_remaining = gas_trace_builder.initial_l2_gas; - uint32_t current_da_gas_remaining = gas_trace_builder.initial_da_gas; - - // Data structure to collect all lookup counts pertaining to 16-bit range checks related to remaining gas - std::array, 4> rem_gas_rng_check_counts; - - std::unordered_map l2_rem_gas_rng_check_hi_counts; - std::unordered_map l2_rem_gas_rng_check_lo_counts; - std::unordered_map da_rem_gas_rng_check_hi_counts; - std::unordered_map da_rem_gas_rng_check_lo_counts; - - // Assume that gas_trace entries are ordered by a strictly increasing clk sequence. - for (auto const& gas_entry : gas_trace) { - // There should be no gaps in the gas_trace. - ASSERT(gas_entry.clk == current_clk); - - auto& dest = main_trace.at(gas_entry.clk - 1); - auto& next = main_trace.at(gas_entry.clk); - - // Write each of the relevant gas accounting values - dest.main_opcode_val = static_cast(gas_entry.opcode); - dest.main_base_l2_gas_op_cost = gas_entry.base_l2_gas_cost; - dest.main_base_da_gas_op_cost = gas_entry.base_da_gas_cost; - dest.main_dyn_l2_gas_op_cost = gas_entry.dyn_l2_gas_cost; - dest.main_dyn_da_gas_op_cost = gas_entry.dyn_da_gas_cost; - dest.main_dyn_gas_multiplier = gas_entry.dyn_gas_multiplier; - - // If gas remaining is increasing, it means we underflowed in uint32_t - bool l2_out_of_gas = current_l2_gas_remaining < gas_entry.remaining_l2_gas; - bool da_out_of_gas = current_da_gas_remaining < gas_entry.remaining_da_gas; - - uint32_t abs_l2_gas_remaining = l2_out_of_gas ? -gas_entry.remaining_l2_gas : gas_entry.remaining_l2_gas; - uint32_t abs_da_gas_remaining = da_out_of_gas ? -gas_entry.remaining_da_gas : gas_entry.remaining_da_gas; - - dest.main_abs_l2_rem_gas_hi = abs_l2_gas_remaining >> 16; - dest.main_abs_da_rem_gas_hi = abs_da_gas_remaining >> 16; - dest.main_abs_l2_rem_gas_lo = static_cast(abs_l2_gas_remaining); - dest.main_abs_da_rem_gas_lo = static_cast(abs_da_gas_remaining); - - // lookups counting - rem_gas_rng_check_counts[L2_HI_GAS_COUNTS_IDX][static_cast(dest.main_abs_l2_rem_gas_hi)]++; - rem_gas_rng_check_counts[L2_LO_GAS_COUNTS_IDX][static_cast(dest.main_abs_l2_rem_gas_lo)]++; - rem_gas_rng_check_counts[DA_HI_GAS_COUNTS_IDX][static_cast(dest.main_abs_da_rem_gas_hi)]++; - rem_gas_rng_check_counts[DA_LO_GAS_COUNTS_IDX][static_cast(dest.main_abs_da_rem_gas_lo)]++; - - dest.main_l2_out_of_gas = static_cast(l2_out_of_gas); - dest.main_da_out_of_gas = static_cast(da_out_of_gas); - - current_l2_gas_remaining = gas_entry.remaining_l2_gas; - current_da_gas_remaining = gas_entry.remaining_da_gas; - next.main_l2_gas_remaining = - l2_out_of_gas ? FF::modulus - uint256_t(abs_l2_gas_remaining) : current_l2_gas_remaining; - next.main_da_gas_remaining = - da_out_of_gas ? FF::modulus - uint256_t(abs_da_gas_remaining) : current_da_gas_remaining; - - current_clk++; - } + gas_trace_builder.finalize(main_trace); + const auto& rem_gas_rng_check_counts = gas_trace_builder.rem_gas_rng_check_counts; + + /********************************************************************************************** + * ONLY FIXED TABLES FROM HERE ON + **********************************************************************************************/ - // Adding extra row for the shifted values at the top of the execution trace. + // Adding extra row for the shifted values at the top of the traces with shifts. Row first_row = Row{ .main_sel_first = FF(1), .mem_lastAccess = FF(1) }; main_trace.insert(main_trace.begin(), first_row); @@ -4002,14 +3935,16 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) r.lookup_div_u16_6_counts = alu_trace_builder.div_u64_range_chk_counters[6][static_cast(counter)]; r.lookup_div_u16_7_counts = alu_trace_builder.div_u64_range_chk_counters[7][static_cast(counter)]; + auto at_or_zero = [](const auto& map, auto idx) { return map.contains(idx) ? map.at(idx) : 0; }; + r.range_check_l2_gas_hi_counts = - rem_gas_rng_check_counts[L2_HI_GAS_COUNTS_IDX][static_cast(counter)]; + at_or_zero(rem_gas_rng_check_counts[L2_HI_GAS_COUNTS_IDX], static_cast(counter)); r.range_check_l2_gas_lo_counts = - rem_gas_rng_check_counts[L2_LO_GAS_COUNTS_IDX][static_cast(counter)]; + at_or_zero(rem_gas_rng_check_counts[L2_LO_GAS_COUNTS_IDX], static_cast(counter)); r.range_check_da_gas_hi_counts = - rem_gas_rng_check_counts[DA_HI_GAS_COUNTS_IDX][static_cast(counter)]; + at_or_zero(rem_gas_rng_check_counts[DA_HI_GAS_COUNTS_IDX], static_cast(counter)); r.range_check_da_gas_lo_counts = - rem_gas_rng_check_counts[DA_LO_GAS_COUNTS_IDX][static_cast(counter)]; + at_or_zero(rem_gas_rng_check_counts[DA_LO_GAS_COUNTS_IDX], static_cast(counter)); r.main_sel_rng_16 = FF(1); } @@ -4229,11 +4164,8 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) for (size_t i = 0; i < fixed_gas_table.size(); i++) { merge_into(main_trace.at(i), fixed_gas_table.at(i)); } - - // Finalise gas left lookup counts - for (auto const& [opcode, count] : gas_trace_builder.gas_opcode_lookup_counter) { - main_trace.at(static_cast(opcode)).lookup_opcode_gas_counts = count; - } + // Finalize the gas -> fixed gas lookup counts. + gas_trace_builder.finalize_lookups(main_trace); auto trace = std::move(main_trace); reset(); diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index 666e7aa807e..09119cec699 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -58,3 +58,137 @@ #define START_EMIT_NULLIFIER_WRITE_OFFSET 144 #define START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET 160 #define START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET 162 +#define AVM_DEFAULT_BASE_GAS_L2 100 +#define AVM_DEFAULT_DYN_GAS_L2 0 +#define AVM_ADD_BASE_L2_GAS 320 +#define AVM_SUB_BASE_L2_GAS 320 +#define AVM_MUL_BASE_L2_GAS 330 +#define AVM_DIV_BASE_L2_GAS 430 +#define AVM_FDIV_BASE_L2_GAS 320 +#define AVM_EQ_BASE_L2_GAS 320 +#define AVM_LT_BASE_L2_GAS 640 +#define AVM_LTE_BASE_L2_GAS 640 +#define AVM_AND_BASE_L2_GAS 330 +#define AVM_OR_BASE_L2_GAS 330 +#define AVM_XOR_BASE_L2_GAS 320 +#define AVM_NOT_BASE_L2_GAS 270 +#define AVM_SHL_BASE_L2_GAS 320 +#define AVM_SHR_BASE_L2_GAS 320 +#define AVM_CAST_BASE_L2_GAS 300 +#define AVM_ADDRESS_BASE_L2_GAS 200 +#define AVM_STORAGEADDRESS_BASE_L2_GAS 200 +#define AVM_SENDER_BASE_L2_GAS 200 +#define AVM_FUNCTIONSELECTOR_BASE_L2_GAS 200 +#define AVM_TRANSACTIONFEE_BASE_L2_GAS 200 +#define AVM_CHAINID_BASE_L2_GAS 200 +#define AVM_VERSION_BASE_L2_GAS 200 +#define AVM_BLOCKNUMBER_BASE_L2_GAS 200 +#define AVM_TIMESTAMP_BASE_L2_GAS 200 +#define AVM_COINBASE_BASE_L2_GAS 200 +#define AVM_FEEPERL2GAS_BASE_L2_GAS 200 +#define AVM_FEEPERDAGAS_BASE_L2_GAS 200 +#define AVM_BLOCKL2GASLIMIT_BASE_L2_GAS 200 +#define AVM_BLOCKDAGASLIMIT_BASE_L2_GAS 200 +#define AVM_CALLDATACOPY_BASE_L2_GAS 290 +#define AVM_L2GASLEFT_BASE_L2_GAS 180 +#define AVM_DAGASLEFT_BASE_L2_GAS 180 +#define AVM_JUMP_BASE_L2_GAS 120 +#define AVM_JUMPI_BASE_L2_GAS 180 +#define AVM_INTERNALCALL_BASE_L2_GAS 180 +#define AVM_INTERNALRETURN_BASE_L2_GAS 180 +#define AVM_SET_BASE_L2_GAS 180 +#define AVM_MOV_BASE_L2_GAS 230 +#define AVM_CMOV_BASE_L2_GAS 340 +#define AVM_SLOAD_BASE_L2_GAS 180 +#define AVM_SSTORE_BASE_L2_GAS 180 +#define AVM_NOTEHASHEXISTS_BASE_L2_GAS 260 +#define AVM_EMITNOTEHASH_BASE_L2_GAS 260 +#define AVM_NULLIFIEREXISTS_BASE_L2_GAS 260 +#define AVM_EMITNULLIFIER_BASE_L2_GAS 260 +#define AVM_L1TOL2MSGEXISTS_BASE_L2_GAS 260 +#define AVM_HEADERMEMBER_BASE_L2_GAS 0 +#define AVM_GETCONTRACTINSTANCE_BASE_L2_GAS 480 +#define AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS 180 +#define AVM_SENDL2TOL1MSG_BASE_L2_GAS 260 +#define AVM_CALL_BASE_L2_GAS 450 +#define AVM_STATICCALL_BASE_L2_GAS 450 +#define AVM_DELEGATECALL_BASE_L2_GAS 0 +#define AVM_RETURN_BASE_L2_GAS 140 +#define AVM_REVERT_BASE_L2_GAS 140 +#define AVM_DEBUGLOG_BASE_L2_GAS 100 +#define AVM_KECCAK_BASE_L2_GAS 3000 +#define AVM_POSEIDON2_BASE_L2_GAS 670 +#define AVM_SHA256_BASE_L2_GAS 3000 +#define AVM_PEDERSEN_BASE_L2_GAS 3000 +#define AVM_ECADD_BASE_L2_GAS 900 +#define AVM_MSM_BASE_L2_GAS 900 +#define AVM_PEDERSENCOMMITMENT_BASE_L2_GAS 3000 +#define AVM_TORADIXLE_BASE_L2_GAS 200 +#define AVM_SHA256COMPRESSION_BASE_L2_GAS 3000 +#define AVM_KECCAKF1600_BASE_L2_GAS 3000 +#define AVM_ADD_DYN_L2_GAS 0 +#define AVM_SUB_DYN_L2_GAS 0 +#define AVM_MUL_DYN_L2_GAS 0 +#define AVM_DIV_DYN_L2_GAS 0 +#define AVM_FDIV_DYN_L2_GAS 0 +#define AVM_EQ_DYN_L2_GAS 0 +#define AVM_LT_DYN_L2_GAS 0 +#define AVM_LTE_DYN_L2_GAS 0 +#define AVM_AND_DYN_L2_GAS 0 +#define AVM_OR_DYN_L2_GAS 0 +#define AVM_XOR_DYN_L2_GAS 0 +#define AVM_NOT_DYN_L2_GAS 0 +#define AVM_SHL_DYN_L2_GAS 0 +#define AVM_SHR_DYN_L2_GAS 0 +#define AVM_CAST_DYN_L2_GAS 0 +#define AVM_ADDRESS_DYN_L2_GAS 0 +#define AVM_STORAGEADDRESS_DYN_L2_GAS 0 +#define AVM_SENDER_DYN_L2_GAS 0 +#define AVM_FUNCTIONSELECTOR_DYN_L2_GAS 0 +#define AVM_TRANSACTIONFEE_DYN_L2_GAS 0 +#define AVM_CHAINID_DYN_L2_GAS 0 +#define AVM_VERSION_DYN_L2_GAS 0 +#define AVM_BLOCKNUMBER_DYN_L2_GAS 0 +#define AVM_TIMESTAMP_DYN_L2_GAS 0 +#define AVM_COINBASE_DYN_L2_GAS 0 +#define AVM_FEEPERL2GAS_DYN_L2_GAS 0 +#define AVM_FEEPERDAGAS_DYN_L2_GAS 0 +#define AVM_BLOCKL2GASLIMIT_DYN_L2_GAS 0 +#define AVM_BLOCKDAGASLIMIT_DYN_L2_GAS 0 +#define AVM_CALLDATACOPY_DYN_L2_GAS 50 +#define AVM_L2GASLEFT_DYN_L2_GAS 0 +#define AVM_DAGASLEFT_DYN_L2_GAS 0 +#define AVM_JUMP_DYN_L2_GAS 0 +#define AVM_JUMPI_DYN_L2_GAS 0 +#define AVM_INTERNALCALL_DYN_L2_GAS 0 +#define AVM_INTERNALRETURN_DYN_L2_GAS 0 +#define AVM_SET_DYN_L2_GAS 0 +#define AVM_MOV_DYN_L2_GAS 0 +#define AVM_CMOV_DYN_L2_GAS 0 +#define AVM_SLOAD_DYN_L2_GAS 180 +#define AVM_SSTORE_DYN_L2_GAS 180 +#define AVM_NOTEHASHEXISTS_DYN_L2_GAS 0 +#define AVM_EMITNOTEHASH_DYN_L2_GAS 0 +#define AVM_NULLIFIEREXISTS_DYN_L2_GAS 0 +#define AVM_EMITNULLIFIER_DYN_L2_GAS 0 +#define AVM_L1TOL2MSGEXISTS_DYN_L2_GAS 0 +#define AVM_HEADERMEMBER_DYN_L2_GAS 0 +#define AVM_GETCONTRACTINSTANCE_DYN_L2_GAS 0 +#define AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS 180 +#define AVM_SENDL2TOL1MSG_DYN_L2_GAS 0 +#define AVM_CALL_DYN_L2_GAS 50 +#define AVM_STATICCALL_DYN_L2_GAS 50 +#define AVM_DELEGATECALL_DYN_L2_GAS 50 +#define AVM_RETURN_DYN_L2_GAS 50 +#define AVM_REVERT_DYN_L2_GAS 50 +#define AVM_DEBUGLOG_DYN_L2_GAS 0 +#define AVM_KECCAK_DYN_L2_GAS 0 +#define AVM_POSEIDON2_DYN_L2_GAS 0 +#define AVM_SHA256_DYN_L2_GAS 0 +#define AVM_PEDERSEN_DYN_L2_GAS 0 +#define AVM_ECADD_DYN_L2_GAS 0 +#define AVM_MSM_DYN_L2_GAS 0 +#define AVM_PEDERSENCOMMITMENT_DYN_L2_GAS 0 +#define AVM_TORADIXLE_DYN_L2_GAS 200 +#define AVM_SHA256COMPRESSION_DYN_L2_GAS 0 +#define AVM_KECCAKF1600_DYN_L2_GAS 0 diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 9c2aaa1c480..48fe455905e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -375,3 +375,144 @@ global START_EMIT_NOTE_HASH_WRITE_OFFSET: u32 = START_SLOAD_WRITE_OFFSET + MAX_P global START_EMIT_NULLIFIER_WRITE_OFFSET: u32 = START_EMIT_NOTE_HASH_WRITE_OFFSET + MAX_NOTE_HASHES_PER_CALL; global START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET: u32 = START_EMIT_NULLIFIER_WRITE_OFFSET + MAX_NULLIFIERS_PER_CALL; global START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET: u32 = START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET + MAX_L2_TO_L1_MSGS_PER_CALL; + +/** + * GAS COSTS FOR AVM OPCODES + * They are used in TS and C++ + */ +global AVM_DEFAULT_BASE_GAS_L2: u16 = 100; +global AVM_DEFAULT_DYN_GAS_L2: u16 = 0; +// Base GAS. +global AVM_ADD_BASE_L2_GAS: u16 = 320; +global AVM_SUB_BASE_L2_GAS: u16 = 320; +global AVM_MUL_BASE_L2_GAS: u16 = 330; +global AVM_DIV_BASE_L2_GAS: u16 = 430; +global AVM_FDIV_BASE_L2_GAS: u16 = 320; +global AVM_EQ_BASE_L2_GAS: u16 = 320; +global AVM_LT_BASE_L2_GAS: u16 = 640; +global AVM_LTE_BASE_L2_GAS: u16 = 640; +global AVM_AND_BASE_L2_GAS: u16 = 330; +global AVM_OR_BASE_L2_GAS: u16 = 330; +global AVM_XOR_BASE_L2_GAS: u16 = 320; +global AVM_NOT_BASE_L2_GAS: u16 = 270; +global AVM_SHL_BASE_L2_GAS: u16 = 320; +global AVM_SHR_BASE_L2_GAS: u16 = 320; +global AVM_CAST_BASE_L2_GAS: u16 = 300; +global AVM_ADDRESS_BASE_L2_GAS: u16 = 200; +global AVM_STORAGEADDRESS_BASE_L2_GAS: u16 = 200; +global AVM_SENDER_BASE_L2_GAS: u16 = 200; +global AVM_FUNCTIONSELECTOR_BASE_L2_GAS: u16 = 200; +global AVM_TRANSACTIONFEE_BASE_L2_GAS: u16 = 200; +global AVM_CHAINID_BASE_L2_GAS: u16 = 200; +global AVM_VERSION_BASE_L2_GAS: u16 = 200; +global AVM_BLOCKNUMBER_BASE_L2_GAS: u16 = 200; +global AVM_TIMESTAMP_BASE_L2_GAS: u16 = 200; +global AVM_COINBASE_BASE_L2_GAS: u16 = 200; +global AVM_FEEPERL2GAS_BASE_L2_GAS: u16 = 200; +global AVM_FEEPERDAGAS_BASE_L2_GAS: u16 = 200; +global AVM_BLOCKL2GASLIMIT_BASE_L2_GAS: u16 = 200; +global AVM_BLOCKDAGASLIMIT_BASE_L2_GAS: u16 = 200; +global AVM_CALLDATACOPY_BASE_L2_GAS: u16 = 290; +global AVM_L2GASLEFT_BASE_L2_GAS: u16 = 180; +global AVM_DAGASLEFT_BASE_L2_GAS: u16 = 180; +global AVM_JUMP_BASE_L2_GAS: u16 = 120; +global AVM_JUMPI_BASE_L2_GAS: u16 = 180; +global AVM_INTERNALCALL_BASE_L2_GAS: u16 = 180; +global AVM_INTERNALRETURN_BASE_L2_GAS: u16 = 180; +global AVM_SET_BASE_L2_GAS: u16 = 180; +global AVM_MOV_BASE_L2_GAS: u16 = 230; +global AVM_CMOV_BASE_L2_GAS: u16 = 340; +global AVM_SLOAD_BASE_L2_GAS: u16 = 180; +global AVM_SSTORE_BASE_L2_GAS: u16 = 180; +global AVM_NOTEHASHEXISTS_BASE_L2_GAS: u16 = 260; +global AVM_EMITNOTEHASH_BASE_L2_GAS: u16 = 260; +global AVM_NULLIFIEREXISTS_BASE_L2_GAS: u16 = 260; +global AVM_EMITNULLIFIER_BASE_L2_GAS: u16 = 260; +global AVM_L1TOL2MSGEXISTS_BASE_L2_GAS: u16 = 260; +global AVM_HEADERMEMBER_BASE_L2_GAS: u16 = 0; +global AVM_GETCONTRACTINSTANCE_BASE_L2_GAS: u16 = 480; +global AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS: u16 = 180; +global AVM_SENDL2TOL1MSG_BASE_L2_GAS: u16 = 260; +global AVM_CALL_BASE_L2_GAS: u16 = 450; +global AVM_STATICCALL_BASE_L2_GAS: u16 = 450; +global AVM_DELEGATECALL_BASE_L2_GAS: u16 = 0; +global AVM_RETURN_BASE_L2_GAS: u16 = 140; +global AVM_REVERT_BASE_L2_GAS: u16 = 140; +global AVM_DEBUGLOG_BASE_L2_GAS: u16 = 100; +global AVM_KECCAK_BASE_L2_GAS: u16 = 3000; +global AVM_POSEIDON2_BASE_L2_GAS: u16 = 670; +global AVM_SHA256_BASE_L2_GAS: u16 = 3000; +global AVM_PEDERSEN_BASE_L2_GAS: u16 = 3000; +global AVM_ECADD_BASE_L2_GAS: u16 = 900; +global AVM_MSM_BASE_L2_GAS: u16 = 900; +global AVM_PEDERSENCOMMITMENT_BASE_L2_GAS: u16 = 3000; +global AVM_TORADIXLE_BASE_L2_GAS: u16 = 200; +global AVM_SHA256COMPRESSION_BASE_L2_GAS: u16 = 3000; +global AVM_KECCAKF1600_BASE_L2_GAS: u16 = 3000; +// Dynamic GAS +global AVM_ADD_DYN_L2_GAS: u16 = 0; +global AVM_SUB_DYN_L2_GAS: u16 = 0; +global AVM_MUL_DYN_L2_GAS: u16 = 0; +global AVM_DIV_DYN_L2_GAS: u16 = 0; +global AVM_FDIV_DYN_L2_GAS: u16 = 0; +global AVM_EQ_DYN_L2_GAS: u16 = 0; +global AVM_LT_DYN_L2_GAS: u16 = 0; +global AVM_LTE_DYN_L2_GAS: u16 = 0; +global AVM_AND_DYN_L2_GAS: u16 = 0; +global AVM_OR_DYN_L2_GAS: u16 = 0; +global AVM_XOR_DYN_L2_GAS: u16 = 0; +global AVM_NOT_DYN_L2_GAS: u16 = 0; +global AVM_SHL_DYN_L2_GAS: u16 = 0; +global AVM_SHR_DYN_L2_GAS: u16 = 0; +global AVM_CAST_DYN_L2_GAS: u16 = 0; +global AVM_ADDRESS_DYN_L2_GAS: u16 = 0; +global AVM_STORAGEADDRESS_DYN_L2_GAS: u16 = 0; +global AVM_SENDER_DYN_L2_GAS: u16 = 0; +global AVM_FUNCTIONSELECTOR_DYN_L2_GAS: u16 = 0; +global AVM_TRANSACTIONFEE_DYN_L2_GAS: u16 = 0; +global AVM_CHAINID_DYN_L2_GAS: u16 = 0; +global AVM_VERSION_DYN_L2_GAS: u16 = 0; +global AVM_BLOCKNUMBER_DYN_L2_GAS: u16 = 0; +global AVM_TIMESTAMP_DYN_L2_GAS: u16 = 0; +global AVM_COINBASE_DYN_L2_GAS: u16 = 0; +global AVM_FEEPERL2GAS_DYN_L2_GAS: u16 = 0; +global AVM_FEEPERDAGAS_DYN_L2_GAS: u16 = 0; +global AVM_BLOCKL2GASLIMIT_DYN_L2_GAS: u16 = 0; +global AVM_BLOCKDAGASLIMIT_DYN_L2_GAS: u16 = 0; +global AVM_CALLDATACOPY_DYN_L2_GAS: u16 = 50; +global AVM_L2GASLEFT_DYN_L2_GAS: u16 = 0; +global AVM_DAGASLEFT_DYN_L2_GAS: u16 = 0; +global AVM_JUMP_DYN_L2_GAS: u16 = 0; +global AVM_JUMPI_DYN_L2_GAS: u16 = 0; +global AVM_INTERNALCALL_DYN_L2_GAS: u16 = 0; +global AVM_INTERNALRETURN_DYN_L2_GAS: u16 = 0; +global AVM_SET_DYN_L2_GAS: u16 = 0; +global AVM_MOV_DYN_L2_GAS: u16 = 0; +global AVM_CMOV_DYN_L2_GAS: u16 = 0; +global AVM_SLOAD_DYN_L2_GAS: u16 = 180; +global AVM_SSTORE_DYN_L2_GAS: u16 = 180; +global AVM_NOTEHASHEXISTS_DYN_L2_GAS: u16 = 0; +global AVM_EMITNOTEHASH_DYN_L2_GAS: u16 = 0; +global AVM_NULLIFIEREXISTS_DYN_L2_GAS: u16 = 0; +global AVM_EMITNULLIFIER_DYN_L2_GAS: u16 = 0; +global AVM_L1TOL2MSGEXISTS_DYN_L2_GAS: u16 = 0; +global AVM_HEADERMEMBER_DYN_L2_GAS: u16 = 0; +global AVM_GETCONTRACTINSTANCE_DYN_L2_GAS: u16 = 0; +global AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS: u16 = 180; +global AVM_SENDL2TOL1MSG_DYN_L2_GAS: u16 = 0; +global AVM_CALL_DYN_L2_GAS: u16 = 50; +global AVM_STATICCALL_DYN_L2_GAS: u16 = 50; +global AVM_DELEGATECALL_DYN_L2_GAS: u16 = 50; +global AVM_RETURN_DYN_L2_GAS: u16 = 50; +global AVM_REVERT_DYN_L2_GAS: u16 = 50; +global AVM_DEBUGLOG_DYN_L2_GAS: u16 = 0; +global AVM_KECCAK_DYN_L2_GAS: u16 = 0; +global AVM_POSEIDON2_DYN_L2_GAS: u16 = 0; +global AVM_SHA256_DYN_L2_GAS: u16 = 0; +global AVM_PEDERSEN_DYN_L2_GAS: u16 = 0; +global AVM_ECADD_DYN_L2_GAS: u16 = 0; +global AVM_MSM_DYN_L2_GAS: u16 = 0; +global AVM_PEDERSENCOMMITMENT_DYN_L2_GAS: u16 = 0; +global AVM_TORADIXLE_DYN_L2_GAS: u16 = 200; +global AVM_SHA256COMPRESSION_DYN_L2_GAS: u16 = 0; +global AVM_KECCAKF1600_DYN_L2_GAS: u16 = 0; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index e28d7e01cae..5f2c6dbc988 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -222,6 +222,140 @@ export const START_EMIT_NOTE_HASH_WRITE_OFFSET = 128; export const START_EMIT_NULLIFIER_WRITE_OFFSET = 144; export const START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET = 160; export const START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET = 162; +export const AVM_DEFAULT_BASE_GAS_L2 = 100; +export const AVM_DEFAULT_DYN_GAS_L2 = 0; +export const AVM_ADD_BASE_L2_GAS = 320; +export const AVM_SUB_BASE_L2_GAS = 320; +export const AVM_MUL_BASE_L2_GAS = 330; +export const AVM_DIV_BASE_L2_GAS = 430; +export const AVM_FDIV_BASE_L2_GAS = 320; +export const AVM_EQ_BASE_L2_GAS = 320; +export const AVM_LT_BASE_L2_GAS = 640; +export const AVM_LTE_BASE_L2_GAS = 640; +export const AVM_AND_BASE_L2_GAS = 330; +export const AVM_OR_BASE_L2_GAS = 330; +export const AVM_XOR_BASE_L2_GAS = 320; +export const AVM_NOT_BASE_L2_GAS = 270; +export const AVM_SHL_BASE_L2_GAS = 320; +export const AVM_SHR_BASE_L2_GAS = 320; +export const AVM_CAST_BASE_L2_GAS = 300; +export const AVM_ADDRESS_BASE_L2_GAS = 200; +export const AVM_STORAGEADDRESS_BASE_L2_GAS = 200; +export const AVM_SENDER_BASE_L2_GAS = 200; +export const AVM_FUNCTIONSELECTOR_BASE_L2_GAS = 200; +export const AVM_TRANSACTIONFEE_BASE_L2_GAS = 200; +export const AVM_CHAINID_BASE_L2_GAS = 200; +export const AVM_VERSION_BASE_L2_GAS = 200; +export const AVM_BLOCKNUMBER_BASE_L2_GAS = 200; +export const AVM_TIMESTAMP_BASE_L2_GAS = 200; +export const AVM_COINBASE_BASE_L2_GAS = 200; +export const AVM_FEEPERL2GAS_BASE_L2_GAS = 200; +export const AVM_FEEPERDAGAS_BASE_L2_GAS = 200; +export const AVM_BLOCKL2GASLIMIT_BASE_L2_GAS = 200; +export const AVM_BLOCKDAGASLIMIT_BASE_L2_GAS = 200; +export const AVM_CALLDATACOPY_BASE_L2_GAS = 290; +export const AVM_L2GASLEFT_BASE_L2_GAS = 180; +export const AVM_DAGASLEFT_BASE_L2_GAS = 180; +export const AVM_JUMP_BASE_L2_GAS = 120; +export const AVM_JUMPI_BASE_L2_GAS = 180; +export const AVM_INTERNALCALL_BASE_L2_GAS = 180; +export const AVM_INTERNALRETURN_BASE_L2_GAS = 180; +export const AVM_SET_BASE_L2_GAS = 180; +export const AVM_MOV_BASE_L2_GAS = 230; +export const AVM_CMOV_BASE_L2_GAS = 340; +export const AVM_SLOAD_BASE_L2_GAS = 180; +export const AVM_SSTORE_BASE_L2_GAS = 180; +export const AVM_NOTEHASHEXISTS_BASE_L2_GAS = 260; +export const AVM_EMITNOTEHASH_BASE_L2_GAS = 260; +export const AVM_NULLIFIEREXISTS_BASE_L2_GAS = 260; +export const AVM_EMITNULLIFIER_BASE_L2_GAS = 260; +export const AVM_L1TOL2MSGEXISTS_BASE_L2_GAS = 260; +export const AVM_HEADERMEMBER_BASE_L2_GAS = 0; +export const AVM_GETCONTRACTINSTANCE_BASE_L2_GAS = 480; +export const AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS = 180; +export const AVM_SENDL2TOL1MSG_BASE_L2_GAS = 260; +export const AVM_CALL_BASE_L2_GAS = 450; +export const AVM_STATICCALL_BASE_L2_GAS = 450; +export const AVM_DELEGATECALL_BASE_L2_GAS = 0; +export const AVM_RETURN_BASE_L2_GAS = 140; +export const AVM_REVERT_BASE_L2_GAS = 140; +export const AVM_DEBUGLOG_BASE_L2_GAS = 100; +export const AVM_KECCAK_BASE_L2_GAS = 3000; +export const AVM_POSEIDON2_BASE_L2_GAS = 670; +export const AVM_SHA256_BASE_L2_GAS = 3000; +export const AVM_PEDERSEN_BASE_L2_GAS = 3000; +export const AVM_ECADD_BASE_L2_GAS = 900; +export const AVM_MSM_BASE_L2_GAS = 900; +export const AVM_PEDERSENCOMMITMENT_BASE_L2_GAS = 3000; +export const AVM_TORADIXLE_BASE_L2_GAS = 200; +export const AVM_SHA256COMPRESSION_BASE_L2_GAS = 3000; +export const AVM_KECCAKF1600_BASE_L2_GAS = 3000; +export const AVM_ADD_DYN_L2_GAS = 0; +export const AVM_SUB_DYN_L2_GAS = 0; +export const AVM_MUL_DYN_L2_GAS = 0; +export const AVM_DIV_DYN_L2_GAS = 0; +export const AVM_FDIV_DYN_L2_GAS = 0; +export const AVM_EQ_DYN_L2_GAS = 0; +export const AVM_LT_DYN_L2_GAS = 0; +export const AVM_LTE_DYN_L2_GAS = 0; +export const AVM_AND_DYN_L2_GAS = 0; +export const AVM_OR_DYN_L2_GAS = 0; +export const AVM_XOR_DYN_L2_GAS = 0; +export const AVM_NOT_DYN_L2_GAS = 0; +export const AVM_SHL_DYN_L2_GAS = 0; +export const AVM_SHR_DYN_L2_GAS = 0; +export const AVM_CAST_DYN_L2_GAS = 0; +export const AVM_ADDRESS_DYN_L2_GAS = 0; +export const AVM_STORAGEADDRESS_DYN_L2_GAS = 0; +export const AVM_SENDER_DYN_L2_GAS = 0; +export const AVM_FUNCTIONSELECTOR_DYN_L2_GAS = 0; +export const AVM_TRANSACTIONFEE_DYN_L2_GAS = 0; +export const AVM_CHAINID_DYN_L2_GAS = 0; +export const AVM_VERSION_DYN_L2_GAS = 0; +export const AVM_BLOCKNUMBER_DYN_L2_GAS = 0; +export const AVM_TIMESTAMP_DYN_L2_GAS = 0; +export const AVM_COINBASE_DYN_L2_GAS = 0; +export const AVM_FEEPERL2GAS_DYN_L2_GAS = 0; +export const AVM_FEEPERDAGAS_DYN_L2_GAS = 0; +export const AVM_BLOCKL2GASLIMIT_DYN_L2_GAS = 0; +export const AVM_BLOCKDAGASLIMIT_DYN_L2_GAS = 0; +export const AVM_CALLDATACOPY_DYN_L2_GAS = 50; +export const AVM_L2GASLEFT_DYN_L2_GAS = 0; +export const AVM_DAGASLEFT_DYN_L2_GAS = 0; +export const AVM_JUMP_DYN_L2_GAS = 0; +export const AVM_JUMPI_DYN_L2_GAS = 0; +export const AVM_INTERNALCALL_DYN_L2_GAS = 0; +export const AVM_INTERNALRETURN_DYN_L2_GAS = 0; +export const AVM_SET_DYN_L2_GAS = 0; +export const AVM_MOV_DYN_L2_GAS = 0; +export const AVM_CMOV_DYN_L2_GAS = 0; +export const AVM_SLOAD_DYN_L2_GAS = 180; +export const AVM_SSTORE_DYN_L2_GAS = 180; +export const AVM_NOTEHASHEXISTS_DYN_L2_GAS = 0; +export const AVM_EMITNOTEHASH_DYN_L2_GAS = 0; +export const AVM_NULLIFIEREXISTS_DYN_L2_GAS = 0; +export const AVM_EMITNULLIFIER_DYN_L2_GAS = 0; +export const AVM_L1TOL2MSGEXISTS_DYN_L2_GAS = 0; +export const AVM_HEADERMEMBER_DYN_L2_GAS = 0; +export const AVM_GETCONTRACTINSTANCE_DYN_L2_GAS = 0; +export const AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS = 180; +export const AVM_SENDL2TOL1MSG_DYN_L2_GAS = 0; +export const AVM_CALL_DYN_L2_GAS = 50; +export const AVM_STATICCALL_DYN_L2_GAS = 50; +export const AVM_DELEGATECALL_DYN_L2_GAS = 50; +export const AVM_RETURN_DYN_L2_GAS = 50; +export const AVM_REVERT_DYN_L2_GAS = 50; +export const AVM_DEBUGLOG_DYN_L2_GAS = 0; +export const AVM_KECCAK_DYN_L2_GAS = 0; +export const AVM_POSEIDON2_DYN_L2_GAS = 0; +export const AVM_SHA256_DYN_L2_GAS = 0; +export const AVM_PEDERSEN_DYN_L2_GAS = 0; +export const AVM_ECADD_DYN_L2_GAS = 0; +export const AVM_MSM_DYN_L2_GAS = 0; +export const AVM_PEDERSENCOMMITMENT_DYN_L2_GAS = 0; +export const AVM_TORADIXLE_DYN_L2_GAS = 200; +export const AVM_SHA256COMPRESSION_DYN_L2_GAS = 0; +export const AVM_KECCAKF1600_DYN_L2_GAS = 0; export enum GeneratorIndex { NOTE_HASH = 1, NOTE_HASH_NONCE = 2, diff --git a/yarn-project/circuits.js/src/scripts/constants.in.ts b/yarn-project/circuits.js/src/scripts/constants.in.ts index 4f7701cedcd..a74a37a8f7c 100644 --- a/yarn-project/circuits.js/src/scripts/constants.in.ts +++ b/yarn-project/circuits.js/src/scripts/constants.in.ts @@ -149,7 +149,7 @@ function processConstantsTS(constants: { [key: string]: string }): string { function processConstantsCpp(constants: { [key: string]: string }): string { const code: string[] = []; Object.entries(constants).forEach(([key, value]) => { - if (CPP_CONSTANTS.includes(key)) { + if (CPP_CONSTANTS.includes(key) || key.startsWith('AVM_')) { code.push(`#define ${key} ${value}`); } }); @@ -203,7 +203,9 @@ function processEnumTS(enumName: string, enumValues: { [key: string]: number }): function processConstantsSolidity(constants: { [key: string]: string }, prefix = ''): string { const code: string[] = []; Object.entries(constants).forEach(([key, value]) => { - code.push(` uint256 internal constant ${prefix}${key} = ${value};`); + if (!key.startsWith('AVM_')) { + code.push(` uint256 internal constant ${prefix}${key} = ${value};`); + } }); return code.join('\n'); } diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index bdb8ef86097..3889a72050e 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -1,3 +1,5 @@ +import * as c from '@aztec/circuits.js/constants'; + import { TypeTag } from './avm_memory_types.js'; import { InstructionExecutionError } from './errors.js'; import { Addressing, AddressingMode } from './opcodes/addressing_mode.js'; @@ -46,90 +48,150 @@ export const EmptyGas: Gas = { daGas: 0, }; +function makeCost(l2Gas: number, daGas: number): Gas { + return { l2Gas, daGas }; +} + /** Dimensions of gas usage: L1, L2, and DA. */ export const GasDimensions = ['l2Gas', 'daGas'] as const; -/** Default gas cost for an opcode. */ -const DefaultBaseGasCost: Gas = { l2Gas: 10, daGas: 0 }; - /** Base gas costs for each instruction. Additional gas cost may be added on top due to memory or storage accesses, etc. */ const BaseGasCosts: Record = { - [Opcode.ADD]: DefaultBaseGasCost, - [Opcode.SUB]: DefaultBaseGasCost, - [Opcode.MUL]: DefaultBaseGasCost, - [Opcode.DIV]: DefaultBaseGasCost, - [Opcode.FDIV]: DefaultBaseGasCost, - [Opcode.EQ]: DefaultBaseGasCost, - [Opcode.LT]: DefaultBaseGasCost, - [Opcode.LTE]: DefaultBaseGasCost, - [Opcode.AND]: DefaultBaseGasCost, - [Opcode.OR]: DefaultBaseGasCost, - [Opcode.XOR]: DefaultBaseGasCost, - [Opcode.NOT]: DefaultBaseGasCost, - [Opcode.SHL]: DefaultBaseGasCost, - [Opcode.SHR]: DefaultBaseGasCost, - [Opcode.CAST]: DefaultBaseGasCost, - // Execution environment - [Opcode.ADDRESS]: DefaultBaseGasCost, - [Opcode.STORAGEADDRESS]: DefaultBaseGasCost, - [Opcode.SENDER]: DefaultBaseGasCost, - [Opcode.FEEPERL2GAS]: DefaultBaseGasCost, - [Opcode.FEEPERDAGAS]: DefaultBaseGasCost, - [Opcode.TRANSACTIONFEE]: DefaultBaseGasCost, - [Opcode.FUNCTIONSELECTOR]: DefaultBaseGasCost, - [Opcode.CHAINID]: DefaultBaseGasCost, - [Opcode.VERSION]: DefaultBaseGasCost, - [Opcode.BLOCKNUMBER]: DefaultBaseGasCost, - [Opcode.TIMESTAMP]: DefaultBaseGasCost, - [Opcode.COINBASE]: DefaultBaseGasCost, - [Opcode.BLOCKL2GASLIMIT]: DefaultBaseGasCost, - [Opcode.BLOCKDAGASLIMIT]: DefaultBaseGasCost, - [Opcode.CALLDATACOPY]: DefaultBaseGasCost, - // Gas - [Opcode.L2GASLEFT]: DefaultBaseGasCost, - [Opcode.DAGASLEFT]: DefaultBaseGasCost, - // Control flow - [Opcode.JUMP]: DefaultBaseGasCost, - [Opcode.JUMPI]: DefaultBaseGasCost, - [Opcode.INTERNALCALL]: DefaultBaseGasCost, - [Opcode.INTERNALRETURN]: DefaultBaseGasCost, - // Memory - [Opcode.SET]: DefaultBaseGasCost, - [Opcode.MOV]: DefaultBaseGasCost, - [Opcode.CMOV]: DefaultBaseGasCost, - // World state - [Opcode.SLOAD]: DefaultBaseGasCost, - [Opcode.SSTORE]: DefaultBaseGasCost, - [Opcode.NOTEHASHEXISTS]: DefaultBaseGasCost, - [Opcode.EMITNOTEHASH]: DefaultBaseGasCost, - [Opcode.NULLIFIEREXISTS]: DefaultBaseGasCost, - [Opcode.EMITNULLIFIER]: DefaultBaseGasCost, - [Opcode.L1TOL2MSGEXISTS]: DefaultBaseGasCost, - [Opcode.HEADERMEMBER]: DefaultBaseGasCost, - [Opcode.EMITUNENCRYPTEDLOG]: DefaultBaseGasCost, - [Opcode.SENDL2TOL1MSG]: DefaultBaseGasCost, - [Opcode.GETCONTRACTINSTANCE]: DefaultBaseGasCost, - // External calls - [Opcode.CALL]: DefaultBaseGasCost, - [Opcode.STATICCALL]: DefaultBaseGasCost, - [Opcode.DELEGATECALL]: DefaultBaseGasCost, - [Opcode.RETURN]: DefaultBaseGasCost, - [Opcode.REVERT]: DefaultBaseGasCost, - // Misc - [Opcode.DEBUGLOG]: DefaultBaseGasCost, - // Gadgets - [Opcode.KECCAK]: DefaultBaseGasCost, - [Opcode.POSEIDON2]: DefaultBaseGasCost, - [Opcode.SHA256]: DefaultBaseGasCost, - [Opcode.PEDERSEN]: DefaultBaseGasCost, - [Opcode.ECADD]: DefaultBaseGasCost, - [Opcode.MSM]: DefaultBaseGasCost, - [Opcode.PEDERSENCOMMITMENT]: DefaultBaseGasCost, - // Conversions - [Opcode.TORADIXLE]: DefaultBaseGasCost, - // Other - [Opcode.SHA256COMPRESSION]: DefaultBaseGasCost, - [Opcode.KECCAKF1600]: DefaultBaseGasCost, + [Opcode.ADD]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0), + [Opcode.SUB]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0), + [Opcode.MUL]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0), + [Opcode.DIV]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0), + [Opcode.FDIV]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0), + [Opcode.EQ]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0), + [Opcode.LT]: makeCost(c.AVM_LT_BASE_L2_GAS, 0), + [Opcode.LTE]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0), + [Opcode.AND]: makeCost(c.AVM_AND_BASE_L2_GAS, 0), + [Opcode.OR]: makeCost(c.AVM_OR_BASE_L2_GAS, 0), + [Opcode.XOR]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0), + [Opcode.NOT]: makeCost(c.AVM_NOT_BASE_L2_GAS, 0), + [Opcode.SHL]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0), + [Opcode.SHR]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0), + [Opcode.CAST]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0), + [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_BASE_L2_GAS, 0), + [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_BASE_L2_GAS, 0), + [Opcode.SENDER]: makeCost(c.AVM_SENDER_BASE_L2_GAS, 0), + [Opcode.FEEPERL2GAS]: makeCost(c.AVM_FEEPERL2GAS_BASE_L2_GAS, 0), + [Opcode.FEEPERDAGAS]: makeCost(c.AVM_FEEPERDAGAS_BASE_L2_GAS, 0), + [Opcode.TRANSACTIONFEE]: makeCost(c.AVM_TRANSACTIONFEE_BASE_L2_GAS, 0), + [Opcode.FUNCTIONSELECTOR]: makeCost(c.AVM_FUNCTIONSELECTOR_BASE_L2_GAS, 0), + [Opcode.CHAINID]: makeCost(c.AVM_CHAINID_BASE_L2_GAS, 0), + [Opcode.VERSION]: makeCost(c.AVM_VERSION_BASE_L2_GAS, 0), + [Opcode.BLOCKNUMBER]: makeCost(c.AVM_BLOCKNUMBER_BASE_L2_GAS, 0), + [Opcode.TIMESTAMP]: makeCost(c.AVM_TIMESTAMP_BASE_L2_GAS, 0), + [Opcode.COINBASE]: makeCost(c.AVM_COINBASE_BASE_L2_GAS, 0), + [Opcode.BLOCKL2GASLIMIT]: makeCost(c.AVM_BLOCKL2GASLIMIT_BASE_L2_GAS, 0), + [Opcode.BLOCKDAGASLIMIT]: makeCost(c.AVM_BLOCKDAGASLIMIT_BASE_L2_GAS, 0), + [Opcode.CALLDATACOPY]: makeCost(c.AVM_CALLDATACOPY_BASE_L2_GAS, 0), + [Opcode.L2GASLEFT]: makeCost(c.AVM_L2GASLEFT_BASE_L2_GAS, 0), + [Opcode.DAGASLEFT]: makeCost(c.AVM_DAGASLEFT_BASE_L2_GAS, 0), + [Opcode.JUMP]: makeCost(c.AVM_JUMP_BASE_L2_GAS, 0), + [Opcode.JUMPI]: makeCost(c.AVM_JUMPI_BASE_L2_GAS, 0), + [Opcode.INTERNALCALL]: makeCost(c.AVM_INTERNALCALL_BASE_L2_GAS, 0), + [Opcode.INTERNALRETURN]: makeCost(c.AVM_INTERNALRETURN_BASE_L2_GAS, 0), + [Opcode.SET]: makeCost(c.AVM_SET_BASE_L2_GAS, 0), + [Opcode.MOV]: makeCost(c.AVM_MOV_BASE_L2_GAS, 0), + [Opcode.CMOV]: makeCost(c.AVM_CMOV_BASE_L2_GAS, 0), + [Opcode.SLOAD]: makeCost(c.AVM_SLOAD_BASE_L2_GAS, 0), + [Opcode.SSTORE]: makeCost(c.AVM_SSTORE_BASE_L2_GAS, 0), + [Opcode.NOTEHASHEXISTS]: makeCost(c.AVM_NOTEHASHEXISTS_BASE_L2_GAS, 0), + [Opcode.EMITNOTEHASH]: makeCost(c.AVM_EMITNOTEHASH_BASE_L2_GAS, 0), + [Opcode.NULLIFIEREXISTS]: makeCost(c.AVM_NULLIFIEREXISTS_BASE_L2_GAS, 0), + [Opcode.EMITNULLIFIER]: makeCost(c.AVM_EMITNULLIFIER_BASE_L2_GAS, 0), + [Opcode.L1TOL2MSGEXISTS]: makeCost(c.AVM_L1TOL2MSGEXISTS_BASE_L2_GAS, 0), + [Opcode.HEADERMEMBER]: makeCost(c.AVM_HEADERMEMBER_BASE_L2_GAS, 0), + [Opcode.EMITUNENCRYPTEDLOG]: makeCost(c.AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS, 0), + [Opcode.SENDL2TOL1MSG]: makeCost(c.AVM_SENDL2TOL1MSG_BASE_L2_GAS, 0), + [Opcode.GETCONTRACTINSTANCE]: makeCost(c.AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, 0), + [Opcode.CALL]: makeCost(c.AVM_CALL_BASE_L2_GAS, 0), + [Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_BASE_L2_GAS, 0), + [Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_BASE_L2_GAS, 0), + [Opcode.RETURN]: makeCost(c.AVM_RETURN_BASE_L2_GAS, 0), + [Opcode.REVERT]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0), + [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_BASE_L2_GAS, 0), + [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_BASE_L2_GAS, 0), + [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_BASE_L2_GAS, 0), + [Opcode.SHA256]: makeCost(c.AVM_SHA256_BASE_L2_GAS, 0), + [Opcode.PEDERSEN]: makeCost(c.AVM_PEDERSEN_BASE_L2_GAS, 0), + [Opcode.ECADD]: makeCost(c.AVM_ECADD_BASE_L2_GAS, 0), + [Opcode.MSM]: makeCost(c.AVM_MSM_BASE_L2_GAS, 0), + [Opcode.PEDERSENCOMMITMENT]: makeCost(c.AVM_PEDERSENCOMMITMENT_BASE_L2_GAS, 0), + [Opcode.TORADIXLE]: makeCost(c.AVM_TORADIXLE_BASE_L2_GAS, 0), + [Opcode.SHA256COMPRESSION]: makeCost(c.AVM_SHA256COMPRESSION_BASE_L2_GAS, 0), + [Opcode.KECCAKF1600]: makeCost(c.AVM_KECCAKF1600_BASE_L2_GAS, 0), +}; + +const DynamicGasCosts: Record = { + [Opcode.ADD]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0), + [Opcode.SUB]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0), + [Opcode.MUL]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0), + [Opcode.DIV]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0), + [Opcode.FDIV]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0), + [Opcode.EQ]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0), + [Opcode.LT]: makeCost(c.AVM_LT_DYN_L2_GAS, 0), + [Opcode.LTE]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0), + [Opcode.AND]: makeCost(c.AVM_AND_DYN_L2_GAS, 0), + [Opcode.OR]: makeCost(c.AVM_OR_DYN_L2_GAS, 0), + [Opcode.XOR]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0), + [Opcode.NOT]: makeCost(c.AVM_NOT_DYN_L2_GAS, 0), + [Opcode.SHL]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0), + [Opcode.SHR]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0), + [Opcode.CAST]: makeCost(c.AVM_CAST_DYN_L2_GAS, 0), + [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_DYN_L2_GAS, 0), + [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_DYN_L2_GAS, 0), + [Opcode.SENDER]: makeCost(c.AVM_SENDER_DYN_L2_GAS, 0), + [Opcode.FEEPERL2GAS]: makeCost(c.AVM_FEEPERL2GAS_DYN_L2_GAS, 0), + [Opcode.FEEPERDAGAS]: makeCost(c.AVM_FEEPERDAGAS_DYN_L2_GAS, 0), + [Opcode.TRANSACTIONFEE]: makeCost(c.AVM_TRANSACTIONFEE_DYN_L2_GAS, 0), + [Opcode.FUNCTIONSELECTOR]: makeCost(c.AVM_FUNCTIONSELECTOR_DYN_L2_GAS, 0), + [Opcode.CHAINID]: makeCost(c.AVM_CHAINID_DYN_L2_GAS, 0), + [Opcode.VERSION]: makeCost(c.AVM_VERSION_DYN_L2_GAS, 0), + [Opcode.BLOCKNUMBER]: makeCost(c.AVM_BLOCKNUMBER_DYN_L2_GAS, 0), + [Opcode.TIMESTAMP]: makeCost(c.AVM_TIMESTAMP_DYN_L2_GAS, 0), + [Opcode.COINBASE]: makeCost(c.AVM_COINBASE_DYN_L2_GAS, 0), + [Opcode.BLOCKL2GASLIMIT]: makeCost(c.AVM_BLOCKL2GASLIMIT_DYN_L2_GAS, 0), + [Opcode.BLOCKDAGASLIMIT]: makeCost(c.AVM_BLOCKDAGASLIMIT_DYN_L2_GAS, 0), + [Opcode.CALLDATACOPY]: makeCost(c.AVM_CALLDATACOPY_DYN_L2_GAS, 0), + [Opcode.L2GASLEFT]: makeCost(c.AVM_L2GASLEFT_DYN_L2_GAS, 0), + [Opcode.DAGASLEFT]: makeCost(c.AVM_DAGASLEFT_DYN_L2_GAS, 0), + [Opcode.JUMP]: makeCost(c.AVM_JUMP_DYN_L2_GAS, 0), + [Opcode.JUMPI]: makeCost(c.AVM_JUMPI_DYN_L2_GAS, 0), + [Opcode.INTERNALCALL]: makeCost(c.AVM_INTERNALCALL_DYN_L2_GAS, 0), + [Opcode.INTERNALRETURN]: makeCost(c.AVM_INTERNALRETURN_DYN_L2_GAS, 0), + [Opcode.SET]: makeCost(c.AVM_SET_DYN_L2_GAS, 0), + [Opcode.MOV]: makeCost(c.AVM_MOV_DYN_L2_GAS, 0), + [Opcode.CMOV]: makeCost(c.AVM_CMOV_DYN_L2_GAS, 0), + [Opcode.SLOAD]: makeCost(c.AVM_SLOAD_DYN_L2_GAS, 0), + [Opcode.SSTORE]: makeCost(c.AVM_SSTORE_DYN_L2_GAS, 0), + [Opcode.NOTEHASHEXISTS]: makeCost(c.AVM_NOTEHASHEXISTS_DYN_L2_GAS, 0), + [Opcode.EMITNOTEHASH]: makeCost(c.AVM_EMITNOTEHASH_DYN_L2_GAS, 0), + [Opcode.NULLIFIEREXISTS]: makeCost(c.AVM_NULLIFIEREXISTS_DYN_L2_GAS, 0), + [Opcode.EMITNULLIFIER]: makeCost(c.AVM_EMITNULLIFIER_DYN_L2_GAS, 0), + [Opcode.L1TOL2MSGEXISTS]: makeCost(c.AVM_L1TOL2MSGEXISTS_DYN_L2_GAS, 0), + [Opcode.HEADERMEMBER]: makeCost(c.AVM_HEADERMEMBER_DYN_L2_GAS, 0), + [Opcode.EMITUNENCRYPTEDLOG]: makeCost(c.AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS, 0), + [Opcode.SENDL2TOL1MSG]: makeCost(c.AVM_SENDL2TOL1MSG_DYN_L2_GAS, 0), + [Opcode.GETCONTRACTINSTANCE]: makeCost(c.AVM_GETCONTRACTINSTANCE_DYN_L2_GAS, 0), + [Opcode.CALL]: makeCost(c.AVM_CALL_DYN_L2_GAS, 0), + [Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_DYN_L2_GAS, 0), + [Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_DYN_L2_GAS, 0), + [Opcode.RETURN]: makeCost(c.AVM_RETURN_DYN_L2_GAS, 0), + [Opcode.REVERT]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0), + [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0), + [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_DYN_L2_GAS, 0), + [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_DYN_L2_GAS, 0), + [Opcode.SHA256]: makeCost(c.AVM_SHA256_DYN_L2_GAS, 0), + [Opcode.PEDERSEN]: makeCost(c.AVM_PEDERSEN_DYN_L2_GAS, 0), + [Opcode.ECADD]: makeCost(c.AVM_ECADD_DYN_L2_GAS, 0), + [Opcode.MSM]: makeCost(c.AVM_MSM_DYN_L2_GAS, 0), + [Opcode.PEDERSENCOMMITMENT]: makeCost(c.AVM_PEDERSENCOMMITMENT_DYN_L2_GAS, 0), + [Opcode.TORADIXLE]: makeCost(c.AVM_TORADIXLE_DYN_L2_GAS, 0), + [Opcode.SHA256COMPRESSION]: makeCost(c.AVM_SHA256COMPRESSION_DYN_L2_GAS, 0), + [Opcode.KECCAKF1600]: makeCost(c.AVM_KECCAKF1600_DYN_L2_GAS, 0), }; /** Returns the fixed base gas cost for a given opcode. */ @@ -137,6 +199,10 @@ export function getBaseGasCost(opcode: Opcode): Gas { return BaseGasCosts[opcode]; } +export function getDynamicGasCost(opcode: Opcode): Gas { + return DynamicGasCosts[opcode]; +} + /** Returns the gas cost associated with the memory operations performed. */ export function getMemoryGasCost(args: { reads?: number; writes?: number; indirect?: number }) { const { reads, writes, indirect } = args; diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 0cf7a3c6e12..7118684483d 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -63,12 +63,11 @@ describe('AVM simulator: injected bytecode', () => { it('Should execute bytecode that performs basic addition', async () => { const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const { l2Gas: initialL2GasLeft } = context.machineState.gasLeft; const results = await new AvmSimulator(context).executeBytecode(markBytecodeAsAvm(bytecode)); expect(results.reverted).toBe(false); expect(results.output).toEqual([new Fr(3)]); - expect(context.machineState.l2GasLeft).toEqual(initialL2GasLeft - 30); + expect(context.machineState.l2GasLeft).toEqual(99999100); }); it('Should halt if runs out of gas', async () => { diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts index 6be6d2d8192..1a7277d9515 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts @@ -241,7 +241,7 @@ export class EmitUnencryptedLog extends Instruction { const contractAddress = context.environment.address; const memoryOperations = { reads: 1 + logSize, indirect: this.indirect }; - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: logSize })); const log = memory.getSlice(logOffset, logSize).map(f => f.toFr()); context.persistableState.writeUnencryptedLog(contractAddress, log); diff --git a/yarn-project/simulator/src/avm/opcodes/context_getters.test.ts b/yarn-project/simulator/src/avm/opcodes/context_getters.test.ts index 03e146785e6..b865d30de2b 100644 --- a/yarn-project/simulator/src/avm/opcodes/context_getters.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/context_getters.test.ts @@ -25,7 +25,7 @@ describe.each([ await instruction.execute(context); const actual = context.machineState.memory.get(0).toNumber(); - const expected = key === 'l2GasLeft' ? value - 10 : value; // l2gascost decreases when it's executed + const expected = key === 'l2GasLeft' ? 123276 : value; // l2gascost decreases when it's executed expect(actual).toEqual(expected); }); }); diff --git a/yarn-project/simulator/src/avm/opcodes/conversion.ts b/yarn-project/simulator/src/avm/opcodes/conversion.ts index 035a8899f7f..70e29969973 100644 --- a/yarn-project/simulator/src/avm/opcodes/conversion.ts +++ b/yarn-project/simulator/src/avm/opcodes/conversion.ts @@ -35,7 +35,7 @@ export class ToRadixLE extends Instruction { const memory = context.machineState.memory.track(this.type); const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory); const memoryOperations = { reads: 1, writes: this.numLimbs, indirect: this.indirect }; - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.numLimbs })); // The radix gadget only takes in a Field memory.checkTag(TypeTag.FIELD, srcOffset); diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.ts index 034f666cb7f..cf58f60189e 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.ts @@ -67,7 +67,7 @@ abstract class ExternalCall extends Instruction { // First we consume the gas for this operation. const memoryOperations = { reads: calldataSize + 5, writes: 1 + this.retSize, indirect: this.indirect }; - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: calldataSize + this.retSize })); // Then we consume the gas allocated for the nested call. The excess will be refunded later. // Gas allocation is capped by the amount of gas left in the current context. // We have to do some dancing here because the gas allocation is a field, @@ -170,7 +170,7 @@ export class Return extends Instruction { public async execute(context: AvmContext): Promise { const memoryOperations = { reads: this.copySize, indirect: this.indirect }; const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.copySize })); const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory); @@ -199,7 +199,7 @@ export class Revert extends Instruction { public async execute(context: AvmContext): Promise { const memoryOperations = { reads: this.retSize, indirect: this.indirect }; const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.retSize })); const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory); diff --git a/yarn-project/simulator/src/avm/opcodes/instruction.ts b/yarn-project/simulator/src/avm/opcodes/instruction.ts index 3b9d2097694..3eb22810bbd 100644 --- a/yarn-project/simulator/src/avm/opcodes/instruction.ts +++ b/yarn-project/simulator/src/avm/opcodes/instruction.ts @@ -1,7 +1,7 @@ import { strict as assert } from 'assert'; import type { AvmContext } from '../avm_context.js'; -import { getBaseGasCost, sumGas } from '../avm_gas.js'; +import { getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js'; import { type MemoryOperations } from '../avm_memory_types.js'; import { type BufferCursor } from '../serialization/buffer_cursor.js'; import { Opcode, type OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js'; @@ -67,12 +67,15 @@ export abstract class Instruction { * @param memoryOps Memory operations performed by the instruction. * @returns Gas cost. */ - protected gasCost(_memoryOps: Partial = {}) { + protected gasCost(ops: Partial = {}) { const baseGasCost = getBaseGasCost(this.opcode); + // TODO: We are using a simplified gas model to reduce complexity in the circuit. + // Memory accounting will probably be removed. // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6861): reconsider. // const memoryGasCost = getMemoryGasCost(memoryOps); - const memoryGasCost = { l2Gas: 0, daGas: 0 }; - return sumGas(baseGasCost, memoryGasCost); + // const memoryGasCost = { l2Gas: 0, daGas: 0 }; + const dynGasCost = mulGas(getDynamicGasCost(this.opcode), ops.dynMultiplier ?? 0); + return sumGas(baseGasCost, dynGasCost); } /** diff --git a/yarn-project/simulator/src/avm/opcodes/memory.ts b/yarn-project/simulator/src/avm/opcodes/memory.ts index 35139cbbcff..5bf4c56c623 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.ts @@ -208,7 +208,7 @@ export class CalldataCopy extends Instruction { public async execute(context: AvmContext): Promise { const memoryOperations = { writes: this.copySize, indirect: this.indirect }; const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.copySize })); // We don't need to check tags here because: (1) the calldata is NOT in memory, and (2) we are the ones writing to destination. const [cdOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.cdOffset, this.dstOffset], memory); diff --git a/yarn-project/simulator/src/avm/opcodes/storage.ts b/yarn-project/simulator/src/avm/opcodes/storage.ts index 15320d1112f..0e5cc6cdf2a 100644 --- a/yarn-project/simulator/src/avm/opcodes/storage.ts +++ b/yarn-project/simulator/src/avm/opcodes/storage.ts @@ -42,7 +42,7 @@ export class SStore extends BaseStorageInstruction { const memoryOperations = { reads: this.size + 1, indirect: this.indirect }; const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.size })); const [srcOffset, slotOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.bOffset], memory); memory.checkTag(TypeTag.FIELD, slotOffset); @@ -72,7 +72,7 @@ export class SLoad extends BaseStorageInstruction { public async execute(context: AvmContext): Promise { const memoryOperations = { writes: this.size, reads: 1, indirect: this.indirect }; const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); + context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.size })); const [slotOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.bOffset], memory); memory.checkTag(TypeTag.FIELD, slotOffset);