Skip to content

Commit

Permalink
feat(avm): base and dynamic gas in TS and CPP (part 2) (#8016)
Browse files Browse the repository at this point in the history
  • Loading branch information
fcarreiro authored Aug 15, 2024
1 parent 0d82c79 commit 5801732
Show file tree
Hide file tree
Showing 20 changed files with 788 additions and 284 deletions.
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

0 comments on commit 5801732

Please sign in to comment.