Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions barretenberg/cpp/pil/avm/gas.pil
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#include <string>
#include <vector>

static const uint32_t DEFAULT_INITIAL_DA_GAS = 100000;
static const uint32_t DEFAULT_INITIAL_L2_GAS = 100000;
static const uint32_t DEFAULT_INITIAL_DA_GAS = 1000000;
static const uint32_t DEFAULT_INITIAL_L2_GAS = 1000000;
5 changes: 5 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
151 changes: 79 additions & 72 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp
Original file line number Diff line number Diff line change
@@ -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 <unordered_map>

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<OpCode, FixedGasTable::GasRow> 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
Expand Down
88 changes: 81 additions & 7 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ void AvmGasTraceBuilder::reset()
gas_trace.clear();
}

std::vector<AvmGasTraceBuilder::GasTraceEntry> 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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -103,4 +98,83 @@ void AvmGasTraceBuilder::constrain_gas_for_external_call(uint32_t clk,
});
}

void AvmGasTraceBuilder::finalize(std::vector<AvmFullRow<FF>>& 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<uint8_t>(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<uint16_t>(abs_l2_gas_remaining);
dest.main_abs_da_rem_gas_lo = static_cast<uint16_t>(abs_da_gas_remaining);

// lookups counting
rem_gas_rng_check_counts[L2_HI_GAS_COUNTS_IDX][static_cast<uint16_t>(dest.main_abs_l2_rem_gas_hi)]++;
rem_gas_rng_check_counts[L2_LO_GAS_COUNTS_IDX][static_cast<uint16_t>(dest.main_abs_l2_rem_gas_lo)]++;
rem_gas_rng_check_counts[DA_HI_GAS_COUNTS_IDX][static_cast<uint16_t>(dest.main_abs_da_rem_gas_hi)]++;
rem_gas_rng_check_counts[DA_LO_GAS_COUNTS_IDX][static_cast<uint16_t>(dest.main_abs_da_rem_gas_lo)]++;

dest.main_l2_out_of_gas = static_cast<uint32_t>(l2_out_of_gas);
dest.main_da_out_of_gas = static_cast<uint32_t>(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<AvmFullRow<FF>>& 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<uint8_t>(opcode)).lookup_opcode_gas_counts = count;
}
}

} // namespace bb::avm_trace
24 changes: 15 additions & 9 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#include <cstdint>
#include <vector>

#include "barretenberg/vm/avm/generated/full_row.hpp"
#include "barretenberg/vm/avm/trace/common.hpp"
#include "barretenberg/vm/avm/trace/opcode.hpp"

Expand All @@ -21,14 +23,14 @@ class AvmGasTraceBuilder {
uint32_t remaining_da_gas = 0;
};

// Counts each time an opcode is read
// opcode -> count
std::unordered_map<OpCode, uint32_t> gas_opcode_lookup_counter;

AvmGasTraceBuilder() = default;

size_t size() const { return gas_trace.size(); }
void reset();
std::vector<GasTraceEntry> 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<AvmFullRow<FF>>& trace);
void finalize_lookups(std::vector<AvmFullRow<FF>>& trace);

void constrain_gas(uint32_t clk, OpCode opcode, uint32_t dyn_gas_multiplier = 0);
void constrain_gas_for_external_call(uint32_t clk,
Expand All @@ -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<OpCode, uint32_t> gas_opcode_lookup_counter;
// Data structure to collect all lookup counts pertaining to 16-bit range checks related to remaining gas
std::array<std::unordered_map<uint16_t, uint32_t>, 4> rem_gas_rng_check_counts;

private:
std::vector<GasTraceEntry> 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;
};
Expand Down
Loading