Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
gas_tracker.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4
6
7namespace bb::avm2::simulation {
8namespace {
9
10// Wider type used for intermediate gas calculations.
11struct IntermediateGas {
12 uint64_t l2_gas = 0;
13 uint64_t da_gas = 0;
14
15 IntermediateGas operator+(const IntermediateGas& other) const
16 {
17 return IntermediateGas{ .l2_gas = this->l2_gas + other.l2_gas, .da_gas = this->da_gas + other.da_gas };
18 }
19
20 IntermediateGas operator*(const IntermediateGas& other) const
21 {
22 return IntermediateGas{ .l2_gas = this->l2_gas * other.l2_gas, .da_gas = this->da_gas * other.da_gas };
23 }
24
25 Gas to_gas() const
26 {
27 BB_ASSERT_LTE(l2_gas, std::numeric_limits<uint32_t>::max(), "L2 gas out of bounds");
28 BB_ASSERT_LTE(da_gas, std::numeric_limits<uint32_t>::max(), "DA gas out of bounds");
29 return Gas{ .l2_gas = static_cast<uint32_t>(l2_gas), .da_gas = static_cast<uint32_t>(da_gas) };
30 }
31};
32
39IntermediateGas to_intermediate_gas(const Gas& gas)
40{
41 return IntermediateGas{ .l2_gas = static_cast<uint64_t>(gas.l2_gas), .da_gas = static_cast<uint64_t>(gas.da_gas) };
42}
43
44} // namespace
45
58
65void GasTracker::consume_gas(const Gas& dynamic_gas_factor)
66{
67 // Previous gas used + base gas (for L2 is addressing gas + opcode gas, for DA is base DA gas) +
68 // dynamic gas (for L2 is dyn_l2 * dynamic_gas_factor.l2_gas, for DA is dyn_da * dynamic_gas_factor.da_gas).
69 const IntermediateGas total_gas_used =
70 to_intermediate_gas(context.get_gas_used()) + // Previous gas used (can be up to 2**32 - 1).
72 (IntermediateGas{ spec.gas_cost.dyn_l2, spec.gas_cost.dyn_da } * // Dynamic gas.
73 to_intermediate_gas(dynamic_gas_factor));
74
75 // Base L2 gas (gas_event.addressing_gas + spec.gas_cost.opcode_gas) does not overflow uint32_t. It is guaranteed by
76 // the static assert in compute_addressing_gas() that addressing gas fits in 16 bits and spec.gas_cost.opcode_gas is
77 // uint16_t. Note also that dyn_l2 and dyn_da are uint16_t so that the product does not overflow uint64_t.
78
79 const IntermediateGas gas_limit = to_intermediate_gas(context.get_gas_limit());
80
81 // Populate gas event values.
82 gas_event.dynamic_gas_factor = dynamic_gas_factor;
83 gas_event.total_gas_used_l2 = total_gas_used.l2_gas;
84 gas_event.total_gas_used_da = total_gas_used.da_gas;
85 // Check whether we are out of gas.
86 gas_event.oog_l2 = greater_than.gt(total_gas_used.l2_gas, gas_limit.l2_gas);
87 gas_event.oog_da = greater_than.gt(total_gas_used.da_gas, gas_limit.da_gas);
88
90 throw OutOfGasException(format("Out of gas: total L2 used ",
91 total_gas_used.l2_gas,
92 " of ",
93 gas_limit.l2_gas,
94 ", total DA used ",
95 total_gas_used.da_gas,
96 " of ",
97 gas_limit.da_gas));
98 }
99
100 // Safe downcast since if we were over 32 bits, we would have OOG'd.
101 context.set_gas_used(total_gas_used.to_gas());
102}
103
113{
114 Gas gas_left = context.gas_left();
115
116 bool is_l2_gas_left_gt_allocated = greater_than.gt(gas_left.l2_gas, allocated_gas.l2_gas);
117 bool is_da_gas_left_gt_allocated = greater_than.gt(gas_left.da_gas, allocated_gas.da_gas);
118
119 return {
120 .l2_gas = is_l2_gas_left_gt_allocated ? allocated_gas.l2_gas : gas_left.l2_gas,
121 .da_gas = is_da_gas_left_gt_allocated ? allocated_gas.da_gas : gas_left.da_gas,
122 };
123}
124
125} // namespace bb::avm2::simulation
GreaterThan greater_than
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:168
Gas compute_gas_limit_for_call(const Gas &allocated_gas) override
Computes the gas limit for a call (CALL and STATICCALL opcodes) as the minimum between the gas alloca...
GreaterThanInterface & greater_than
const ExecInstructionSpec & spec
void consume_gas(const Gas &dynamic_gas_factor={ 0, 0 }) override
Consumes gas for the current instruction.
GasTracker(GasEvent &gas_event, const Instruction &instruction, const InstructionInfoDBInterface &instruction_info_db, ContextInterface &context, GreaterThanInterface &greater_than)
virtual bool gt(const FF &a, const FF &b)=0
std::string format(Args... args)
Definition log.hpp:24
uint64_t da_gas
uint64_t l2_gas
InstructionInfoDB instruction_info_db
GasEvent gas_event
Instruction instruction
uint16_t compute_addressing_gas(uint16_t addressing_mode)
Computes the gas cost for addressing.
Definition gas.cpp:16
Univariate< Fr, domain_end > operator+(const Fr &ff, const Univariate< Fr, domain_end > &uv)
Univariate< Fr, domain_end > operator*(const Fr &ff, const Univariate< Fr, domain_end > &uv)