Skip to content

Commit aa96990

Browse files
committed
feat(avm): gas mutations
1 parent 3c26110 commit aa96990

File tree

5 files changed

+234
-116
lines changed

5 files changed

+234
-116
lines changed

barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzzer_lib.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "barretenberg/avm_fuzzer/fuzzer_comparison_helper.hpp"
1414
#include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp"
1515
#include "barretenberg/avm_fuzzer/mutations/tx_data.hpp"
16+
#include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp"
1617
#include "barretenberg/common/log.hpp"
1718
#include "barretenberg/vm2/avm_api.hpp"
1819
#include "barretenberg/vm2/common/avm_io.hpp"
@@ -332,6 +333,12 @@ size_t mutate_tx_data(uint8_t* serialized_fuzzer_data,
332333
.calldata_hash = calldata_hash },
333334
.calldata = calldata });
334335
}
336+
337+
// Compute effective gas fees matching TS computeEffectiveGasFees
338+
// This must be done after any mutation that could affect gas settings or global variables
339+
tx_data.tx.effective_gas_fees =
340+
compute_effective_gas_fees(tx_data.global_variables.gas_fees, tx_data.tx.gas_settings);
341+
335342
auto [mutated_serialized_fuzzer_data, mutated_serialized_fuzzer_data_size] = msgpack_encode_buffer(tx_data);
336343
if (mutated_serialized_fuzzer_data_size > max_size) {
337344
delete[] mutated_serialized_fuzzer_data;

barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp

Lines changed: 30 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp"
77
#include "barretenberg/avm_fuzzer/mutations/instructions/instruction_block.hpp"
88
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp"
9+
#include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp"
910
#include "barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp"
1011
#include "barretenberg/vm2/common/avm_io.hpp"
1112
#include "barretenberg/vm2/common/aztec_constants.hpp"
@@ -58,20 +59,6 @@ void mutate_teardown(std::optional<PublicCallRequestWithCalldata>& teardown_call
5859

5960
namespace bb::avm2::fuzzer {
6061

61-
// Gas bounds for mutation
62-
constexpr uint32_t MIN_GAS = 1000;
63-
constexpr uint32_t MAX_GAS = 10000000;
64-
65-
// Fee bounds for mutation
66-
constexpr uint128_t MIN_FEE = 1;
67-
constexpr uint128_t MAX_FEE = 1000;
68-
69-
constexpr uint32_t AVM_MAX_PROCESSABLE_DA_GAS = (MAX_NOTE_HASHES_PER_TX * AVM_EMITNOTEHASH_BASE_DA_GAS) +
70-
(MAX_NULLIFIERS_PER_TX * AVM_EMITNULLIFIER_BASE_DA_GAS) +
71-
(MAX_L2_TO_L1_MSGS_PER_TX * AVM_SENDL2TOL1MSG_BASE_DA_GAS) +
72-
(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * AVM_SSTORE_DYN_DA_GAS) +
73-
(PUBLIC_LOGS_LENGTH * AVM_EMITUNENCRYPTEDLOG_BASE_DA_GAS);
74-
7562
void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt19937_64& rng)
7663
{
7764
auto choice = TX_MUTATION_CONFIGURATION.select(rng);
@@ -102,98 +89,35 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
10289
fuzz_info("Mutating revertible accumulated data");
10390
mutate_revertible_accumulated_data(tx.revertible_accumulated_data, rng);
10491
break;
105-
106-
// case 2:
107-
// // Mutate gas_settings
108-
// mutate_gas_settings(tx.gas_settings, rng);
109-
// break;
110-
// case 3:
111-
// // Mutate effective_gas_fees
112-
// mutate_gas_fees(tx.effective_gas_fees, rng);
113-
// break;
114-
// case 4:
115-
// // Mutate Deployment data
116-
// break;
117-
// case 8:
118-
// // Mutate gas_used_by_private
119-
// break;
120-
// case 9:
121-
// // Mutate fee_payer
122-
// break;
123-
//}
124-
}
125-
}
126-
127-
void mutate_gas_settings(GasSettings& gas_settings, std::mt19937_64& rng)
128-
{
129-
auto choice = std::uniform_int_distribution<uint8_t>(0, 3)(rng);
130-
131-
switch (choice) {
132-
case 0:
133-
// Pick a Gas Limit between [0, AVM_MAX_PROCESSABLE_L2_GAS]
134-
// fixme: probably should not mutate both l2_gas and da_gas to max in one go
135-
gas_settings.gas_limits.l2_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_L2_GAS)(rng);
136-
gas_settings.gas_limits.da_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_DA_GAS)(rng);
137-
break;
138-
case 1:
139-
// Mutate teardown_gas_limits
140-
gas_settings.teardown_gas_limits.l2_gas =
141-
std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_L2_GAS)(rng);
142-
gas_settings.teardown_gas_limits.da_gas =
143-
std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_DA_GAS)(rng);
144-
break;
145-
case 2:
146-
// Mutate max_fees_per_gas
147-
// mutate_gas_fees(gas_settings.max_fees_per_gas, rng);
148-
break;
149-
case 3:
150-
// Mutate max_priority_fees_per_gas
151-
// mutate_gas_fees(gas_settings.max_priority_fees_per_gas, rng);
152-
break;
153-
}
154-
}
155-
156-
void mutate_gas(Gas& gas, std::mt19937_64& rng)
157-
{
158-
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);
159-
160-
switch (choice) {
161-
case 0:
162-
// Mutate l2_gas
163-
gas.l2_gas = std::uniform_int_distribution<uint32_t>(MIN_GAS, MAX_GAS)(rng);
164-
break;
165-
case 1:
166-
// Mutate da_gas
167-
gas.da_gas = std::uniform_int_distribution<uint32_t>(MIN_GAS, MAX_GAS)(rng);
168-
break;
169-
case 2:
170-
// Set both to same value
171-
gas.l2_gas = gas.da_gas = std::uniform_int_distribution<uint32_t>(MIN_GAS, MAX_GAS)(rng);
172-
break;
173-
}
174-
}
175-
176-
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng)
177-
{
178-
auto choice = std::uniform_int_distribution<uint8_t>(0, 3)(rng);
179-
180-
switch (choice) {
181-
case 0:
182-
// Mutate fee_per_da_gas
183-
fees.fee_per_da_gas = std::uniform_int_distribution<uint64_t>(MIN_FEE, MAX_FEE)(rng);
184-
break;
185-
case 1:
186-
// Mutate fee_per_l2_gas
187-
fees.fee_per_l2_gas = std::uniform_int_distribution<uint64_t>(MIN_FEE, MAX_FEE)(rng);
188-
break;
189-
case 2:
190-
// Set both to zero
191-
fees.fee_per_da_gas = 0;
192-
fees.fee_per_l2_gas = 0;
193-
break;
194-
case 3:
195-
// Set both to same non-zero value
196-
fees.fee_per_da_gas = fees.fee_per_l2_gas = std::uniform_int_distribution<uint64_t>(1, MAX_FEE)(rng);
92+
case TxMutationOptions::GasSettings:
93+
// Mutate gas_settings
94+
fuzz_info("Mutating gas settings");
95+
mutate_gas_settings(tx.gas_settings, rng);
96+
// Ensure effective_gas_fees <= max_fees_per_gas after mutation
97+
tx.effective_gas_fees.fee_per_da_gas =
98+
std::min(tx.effective_gas_fees.fee_per_da_gas, tx.gas_settings.max_fees_per_gas.fee_per_da_gas);
99+
tx.effective_gas_fees.fee_per_l2_gas =
100+
std::min(tx.effective_gas_fees.fee_per_l2_gas, tx.gas_settings.max_fees_per_gas.fee_per_l2_gas);
101+
break;
102+
case TxMutationOptions::GasFees:
103+
// Mutate effective_gas_fees
104+
fuzz_info("Mutating effective gas fees");
105+
mutate_gas_fees(tx.effective_gas_fees, rng);
106+
// Ensure effective_gas_fees <= max_fees_per_gas after mutation
107+
tx.effective_gas_fees.fee_per_da_gas =
108+
std::min(tx.effective_gas_fees.fee_per_da_gas, tx.gas_settings.max_fees_per_gas.fee_per_da_gas);
109+
tx.effective_gas_fees.fee_per_l2_gas =
110+
std::min(tx.effective_gas_fees.fee_per_l2_gas, tx.gas_settings.max_fees_per_gas.fee_per_l2_gas);
111+
break;
112+
case TxMutationOptions::GasUsedByPrivate:
113+
// Mutate gas_used_by_private
114+
fuzz_info("Mutating gas used by private");
115+
mutate_gas(tx.gas_used_by_private, rng);
116+
break;
117+
case TxMutationOptions::FeePayer:
118+
// Mutate fee_payer
119+
fuzz_info("Mutating fee payer");
120+
mutate_field(tx.fee_payer, rng, BASIC_FIELD_MUTATION_CONFIGURATION);
197121
break;
198122
}
199123
}

barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,30 @@ enum class TxMutationOptions {
1414
TearDownEnqueuedCall,
1515
NonRevertibleData,
1616
RevertibleData,
17+
GasSettings,
18+
GasFees,
19+
GasUsedByPrivate,
20+
FeePayer
1721
};
1822

19-
using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 5>;
23+
using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 9>;
2024

2125
constexpr TxMutationConfig TX_MUTATION_CONFIGURATION = TxMutationConfig({
2226
{ TxMutationOptions::SetupEnqueuedCalls, 30 },
2327
{ TxMutationOptions::AppLogicEnqueuedCalls, 30 },
2428
{ TxMutationOptions::TearDownEnqueuedCall, 10 },
2529
{ TxMutationOptions::NonRevertibleData, 15 },
2630
{ TxMutationOptions::RevertibleData, 15 },
31+
{ TxMutationOptions::GasSettings, 5 },
32+
{ TxMutationOptions::GasFees, 3 },
33+
{ TxMutationOptions::GasUsedByPrivate, 1 },
34+
{ TxMutationOptions::FeePayer, 1 },
2735
});
2836

2937
namespace bb::avm2::fuzzer {
3038

3139
void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt19937_64& rng);
3240

33-
// GasSettings mutation
34-
void mutate_gas_settings(GasSettings& gas_settings, std::mt19937_64& rng);
35-
36-
// Gas mutation
37-
void mutate_gas(Gas& gas, std::mt19937_64& rng);
38-
39-
// GasFees mutation
40-
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng);
41-
4241
void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt19937_64& rng, size_t max_size = 10);
4342

4443
} // namespace bb::avm2::fuzzer
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include "barretenberg/avm_fuzzer/mutations/tx_types/gas.hpp"
2+
3+
#include "barretenberg/avm_fuzzer/fuzz_lib/constants.hpp"
4+
#include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp"
5+
#include "barretenberg/avm_fuzzer/mutations/basic_types/vector.hpp"
6+
#include "barretenberg/avm_fuzzer/mutations/configuration.hpp"
7+
#include "barretenberg/vm2/common/avm_io.hpp"
8+
9+
using bb::avm2::AztecAddress;
10+
using bb::avm2::FF;
11+
12+
namespace {} // namespace
13+
14+
namespace bb::avm2::fuzzer {
15+
16+
Gas generate_gas(std::mt19937_64& rng)
17+
{
18+
uint32_t l2_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_L2_GAS)(rng);
19+
uint32_t da_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_DA_GAS)(rng);
20+
21+
return Gas{ l2_gas, da_gas };
22+
}
23+
24+
void mutate_gas(Gas& gas, std::mt19937_64& rng)
25+
{
26+
auto choice = GAS_MUTATION_CONFIGURATION.select(rng);
27+
28+
switch (choice) {
29+
case GasMutationOptions::L2Gas:
30+
// Mutate l2_gas
31+
gas.l2_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_L2_GAS)(rng);
32+
break;
33+
case GasMutationOptions::DAGas:
34+
// Mutate da_gas
35+
gas.da_gas = std::uniform_int_distribution<uint32_t>(0, AVM_MAX_PROCESSABLE_DA_GAS)(rng);
36+
break;
37+
}
38+
}
39+
40+
GasFees generate_gas_fees(std::mt19937_64& rng)
41+
{
42+
uint128_t fee_per_da_gas = static_cast<uint128_t>(generate_random_field(rng));
43+
uint128_t fee_per_l2_gas = static_cast<uint128_t>(generate_random_field(rng));
44+
45+
return GasFees{
46+
fee_per_da_gas,
47+
fee_per_l2_gas,
48+
};
49+
}
50+
51+
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng)
52+
{
53+
auto choice = std::uniform_int_distribution<uint8_t>(0, 1)(rng);
54+
55+
switch (choice) {
56+
case 0:
57+
// Mutate fee_per_da_gas
58+
fees.fee_per_da_gas = std::uniform_int_distribution<uint64_t>(MIN_FEE, MAX_FEE)(rng);
59+
break;
60+
case 1:
61+
// Mutate fee_per_l2_gas
62+
fees.fee_per_l2_gas = std::uniform_int_distribution<uint64_t>(MIN_FEE, MAX_FEE)(rng);
63+
break;
64+
}
65+
}
66+
67+
GasSettings generate_gas_settings(std::mt19937_64& rng)
68+
{
69+
Gas gas_limits = generate_gas(rng);
70+
Gas teardown_gas_limits = generate_gas(rng);
71+
GasFees max_fees_per_gas = generate_gas_fees(rng);
72+
GasFees max_priority_fees_per_gas = generate_gas_fees(rng);
73+
74+
return GasSettings{
75+
gas_limits,
76+
teardown_gas_limits,
77+
max_fees_per_gas,
78+
max_priority_fees_per_gas,
79+
};
80+
}
81+
82+
void mutate_gas_settings(GasSettings& gas_settings, std::mt19937_64& rng)
83+
{
84+
auto choice = GAS_SETTINGS_MUTATION_CONFIGURATION.select(rng);
85+
86+
switch (choice) {
87+
case GasSettingsMutationOptions::GasLimits:
88+
// Mutate gas_limits
89+
mutate_gas(gas_settings.gas_limits, rng);
90+
break;
91+
case GasSettingsMutationOptions::TeardownGasLimits:
92+
// Mutate teardown_gas_limits
93+
mutate_gas(gas_settings.teardown_gas_limits, rng);
94+
break;
95+
case GasSettingsMutationOptions::MaxFeesPerGas:
96+
// Mutate max_fees_per_gas
97+
mutate_gas_fees(gas_settings.max_fees_per_gas, rng);
98+
break;
99+
case GasSettingsMutationOptions::MaxPriorityFeesPerGas:
100+
// Mutate max_priority_fees_per_gas
101+
mutate_gas_fees(gas_settings.max_priority_fees_per_gas, rng);
102+
break;
103+
}
104+
}
105+
106+
GasFees compute_effective_gas_fees(const GasFees& gas_fees, const GasSettings& gas_settings)
107+
{
108+
// Match TS computeEffectiveGasFees from yarn-project/stdlib/src/fees/transaction_fee.ts
109+
// priorityFees = min(maxPriorityFeesPerGas, maxFeesPerGas - gasFees)
110+
// effectiveFees = gasFees + priorityFees
111+
auto min_u128 = [](uint128_t a, uint128_t b) { return a < b ? a : b; };
112+
113+
uint128_t priority_da = min_u128(gas_settings.max_priority_fees_per_gas.fee_per_da_gas,
114+
gas_settings.max_fees_per_gas.fee_per_da_gas - gas_fees.fee_per_da_gas);
115+
uint128_t priority_l2 = min_u128(gas_settings.max_priority_fees_per_gas.fee_per_l2_gas,
116+
gas_settings.max_fees_per_gas.fee_per_l2_gas - gas_fees.fee_per_l2_gas);
117+
118+
return GasFees{
119+
.fee_per_da_gas = gas_fees.fee_per_da_gas + priority_da,
120+
.fee_per_l2_gas = gas_fees.fee_per_l2_gas + priority_l2,
121+
};
122+
}
123+
124+
} // namespace bb::avm2::fuzzer

0 commit comments

Comments
 (0)