Skip to content

Commit ae09b1d

Browse files
committed
feat(avm): mutations for accumulated data
1 parent 97782de commit ae09b1d

File tree

4 files changed

+228
-59
lines changed

4 files changed

+228
-59
lines changed

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

Lines changed: 11 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "barretenberg/avm_fuzzer/mutations/basic_types/vector.hpp"
66
#include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp"
77
#include "barretenberg/avm_fuzzer/mutations/instructions/instruction_block.hpp"
8+
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp"
89
#include "barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp"
910
#include "barretenberg/vm2/common/avm_io.hpp"
1011
#include "barretenberg/vm2/common/aztec_constants.hpp"
@@ -91,6 +92,16 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
9192
fuzz_info("Mutating teardown enqueued call");
9293
mutate_teardown(tx.teardown_enqueued_call, contract_addresses, rng);
9394
break;
95+
case TxMutationOptions::NonRevertibleData:
96+
// Mutate non-revertible accumulated data
97+
fuzz_info("Mutating non-revertible accumulated data");
98+
mutate_non_revertible_accumulated_data(tx.non_revertible_accumulated_data, rng);
99+
break;
100+
case TxMutationOptions::RevertibleData:
101+
// Mutate revertible accumulated data
102+
fuzz_info("Mutating revertible accumulated data");
103+
mutate_revertible_accumulated_data(tx.revertible_accumulated_data, rng);
104+
break;
94105

95106
// case 2:
96107
// // Mutate gas_settings
@@ -103,32 +114,6 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
103114
// case 4:
104115
// // Mutate Deployment data
105116
// break;
106-
// case 5:
107-
// // Mutate non-revertible accumulated data
108-
// // fixme: maybe don't change all stuff
109-
// mutate_ff_vec(tx.non_revertible_accumulated_data.note_hashes, rng, MAX_NOTE_HASHES_PER_TX);
110-
// mutate_ff_vec(tx.non_revertible_accumulated_data.nullifiers, rng, MAX_NULLIFIERS_PER_TX);
111-
// mutate_vec<ScopedL2ToL1Message>(tx.non_revertible_accumulated_data.l2_to_l1_messages,
112-
// rng,
113-
// mutate_l2_to_l1_msg,
114-
// generate_l2_to_l1_msg,
115-
// BASIC_VEC_MUTATION_CONFIGURATION);
116-
// if (tx.non_revertible_accumulated_data.nullifiers.empty()) {
117-
// // Need to ensure the "tx nullifier" exists
118-
// tx.non_revertible_accumulated_data.nullifiers.push_back(generate_random_field(rng));
119-
// }
120-
// break;
121-
// case 6:
122-
// // Mutate revertible accumulated data
123-
// mutate_ff_vec(tx.revertible_accumulated_data.note_hashes, rng, MAX_NOTE_HASHES_PER_TX);
124-
// mutate_ff_vec(tx.revertible_accumulated_data.nullifiers, rng, MAX_NULLIFIERS_PER_TX);
125-
// mutate_vec<ScopedL2ToL1Message>(tx.revertible_accumulated_data.l2_to_l1_messages,
126-
// rng,
127-
// mutate_l2_to_l1_msg,
128-
// generate_l2_to_l1_msg,
129-
// BASIC_VEC_MUTATION_CONFIGURATION);
130-
// break;
131-
// break;
132117
// case 8:
133118
// // Mutate gas_used_by_private
134119
// break;
@@ -213,34 +198,6 @@ void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng)
213198
}
214199
}
215200

216-
void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
217-
{
218-
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);
219-
220-
switch (choice) {
221-
case 0:
222-
// Mutate recipient
223-
msg.message.recipient = generate_random_field(rng);
224-
break;
225-
case 1:
226-
// Mutate content
227-
msg.message.content = generate_random_field(rng);
228-
break;
229-
case 2:
230-
// Mutate contract_address
231-
msg.contract_address = generate_random_field(rng);
232-
break;
233-
}
234-
}
235-
236-
ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng)
237-
{
238-
return ScopedL2ToL1Message{
239-
.message = L2ToL1Message{ .recipient = generate_random_field(rng), .content = generate_random_field(rng) },
240-
.contract_address = generate_random_field(rng),
241-
};
242-
}
243-
244201
void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt19937_64& rng, size_t max_size)
245202
{
246203
auto choice = std::uniform_int_distribution<uint8_t>(0, 1)(rng);

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ enum class TxMutationOptions {
1212
SetupEnqueuedCalls,
1313
AppLogicEnqueuedCalls,
1414
TearDownEnqueuedCall,
15+
NonRevertibleData,
16+
RevertibleData,
1517
};
1618

17-
using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 3>;
19+
using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 5>;
1820

1921
constexpr TxMutationConfig TX_MUTATION_CONFIGURATION = TxMutationConfig({
2022
{ TxMutationOptions::SetupEnqueuedCalls, 30 },
2123
{ TxMutationOptions::AppLogicEnqueuedCalls, 30 },
2224
{ TxMutationOptions::TearDownEnqueuedCall, 10 },
25+
{ TxMutationOptions::NonRevertibleData, 15 },
26+
{ TxMutationOptions::RevertibleData, 15 },
2327
});
2428

2529
namespace bb::avm2::fuzzer {
@@ -35,10 +39,6 @@ void mutate_gas(Gas& gas, std::mt19937_64& rng);
3539
// GasFees mutation
3640
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng);
3741

38-
// L2ToL1Msg vector mutation
39-
void mutate_l2_to_l1_msg(ScopedL2ToL1Message& vec, std::mt19937_64& rng);
40-
ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng);
41-
4242
void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt19937_64& rng, size_t max_size = 10);
4343

4444
} // namespace bb::avm2::fuzzer
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.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 {
13+
14+
// Generate a random note hash
15+
FF generate_note_hash(std::mt19937_64& rng)
16+
{
17+
return generate_random_field(rng);
18+
}
19+
20+
void mutate_note_hash(FF& note_hash, std::mt19937_64& rng)
21+
{
22+
mutate_field(note_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION);
23+
}
24+
25+
// Generate a random nullifier
26+
FF generate_nullifier(std::mt19937_64& rng)
27+
{
28+
return generate_random_field(rng);
29+
}
30+
31+
void mutate_nullifier(FF& nullifier, std::mt19937_64& rng)
32+
{
33+
mutate_field(nullifier, rng, BASIC_FIELD_MUTATION_CONFIGURATION);
34+
}
35+
36+
// Generate a random L2 to L1 message
37+
ScopedL2ToL1Message generate_l2_to_l1_message(std::mt19937_64& rng)
38+
{
39+
return ScopedL2ToL1Message{
40+
.message = L2ToL1Message{ .recipient = generate_random_field(rng), .content = generate_random_field(rng) },
41+
.contract_address = generate_random_field(rng),
42+
};
43+
}
44+
45+
void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
46+
{
47+
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);
48+
49+
switch (choice) {
50+
case 0:
51+
// Mutate recipient
52+
msg.message.recipient = generate_random_field(rng);
53+
break;
54+
case 1:
55+
// Mutate content
56+
msg.message.content = generate_random_field(rng);
57+
break;
58+
case 2:
59+
// Mutate contract_address
60+
msg.contract_address = generate_random_field(rng);
61+
break;
62+
default:
63+
break;
64+
}
65+
}
66+
67+
AccumulatedData generate_accumulated_data(std::mt19937_64& rng)
68+
{
69+
// When we generate new accumulated data we can simply generate a small number of entries
70+
// We test the limits during mutation
71+
std::vector<FF> note_hashes;
72+
size_t num_note_hashes = std::uniform_int_distribution<size_t>(0, 4)(rng);
73+
note_hashes.reserve(num_note_hashes);
74+
for (size_t i = 0; i < num_note_hashes; i++) {
75+
note_hashes.push_back(generate_note_hash(rng));
76+
}
77+
std::vector<FF> nullifiers;
78+
size_t num_nullifiers = std::uniform_int_distribution<size_t>(0, 4)(rng);
79+
nullifiers.reserve(num_nullifiers);
80+
for (size_t i = 0; i < num_nullifiers; i++) {
81+
nullifiers.push_back(generate_nullifier(rng));
82+
}
83+
std::vector<ScopedL2ToL1Message> l2_to_l1_messages;
84+
size_t num_messages = std::uniform_int_distribution<size_t>(0, 4)(rng);
85+
l2_to_l1_messages.reserve(num_messages);
86+
for (size_t i = 0; i < num_messages; i++) {
87+
l2_to_l1_messages.push_back(generate_l2_to_l1_message(rng));
88+
}
89+
90+
return AccumulatedData{
91+
.note_hashes = note_hashes,
92+
.nullifiers = nullifiers,
93+
.l2_to_l1_messages = l2_to_l1_messages,
94+
};
95+
}
96+
97+
void mutate_accumulated_data(AccumulatedData& input, std::mt19937_64& rng)
98+
{
99+
using namespace bb::avm2::fuzzer;
100+
// We only really care about the existence of note hashes, nullifiers, and L2 to L1 messages
101+
// or if these values end up triggering limit errors during execution.
102+
auto choice = ACCUMULATED_DATA_MUTATION_CONFIGURATION.select(rng);
103+
switch (choice) {
104+
case AccumulatedDataMutationOptions::NoteHashes:
105+
mutate_vec<FF>(input.note_hashes, rng, mutate_note_hash, generate_note_hash, BASIC_VEC_MUTATION_CONFIGURATION);
106+
break;
107+
case AccumulatedDataMutationOptions::NoteHashesLimit: {
108+
size_t original_size = input.note_hashes.size();
109+
input.note_hashes.resize(MAX_NOTE_HASHES_PER_TX);
110+
for (size_t i = original_size; i < MAX_NOTE_HASHES_PER_TX; i++) {
111+
input.note_hashes[i] = generate_note_hash(rng);
112+
}
113+
break;
114+
}
115+
case AccumulatedDataMutationOptions::Nullifiers:
116+
mutate_vec<FF>(input.nullifiers, rng, mutate_nullifier, generate_nullifier, BASIC_VEC_MUTATION_CONFIGURATION);
117+
break;
118+
case AccumulatedDataMutationOptions::NullifiersLimit: {
119+
size_t original_size = input.nullifiers.size();
120+
input.nullifiers.resize(MAX_NULLIFIERS_PER_TX);
121+
for (size_t i = original_size; i < MAX_NULLIFIERS_PER_TX; i++) {
122+
input.nullifiers[i] = generate_nullifier(rng);
123+
}
124+
break;
125+
}
126+
case AccumulatedDataMutationOptions::L2ToL1Messages:
127+
mutate_vec<ScopedL2ToL1Message>(input.l2_to_l1_messages,
128+
rng,
129+
mutate_l2_to_l1_msg,
130+
generate_l2_to_l1_message,
131+
BASIC_VEC_MUTATION_CONFIGURATION);
132+
break;
133+
case AccumulatedDataMutationOptions::L2ToL1MessagesLimit: {
134+
size_t original_size = input.l2_to_l1_messages.size();
135+
input.l2_to_l1_messages.resize(MAX_L2_TO_L1_MSGS_PER_TX);
136+
for (size_t i = original_size; i < MAX_L2_TO_L1_MSGS_PER_TX; i++) {
137+
input.l2_to_l1_messages[i] = generate_l2_to_l1_message(rng);
138+
}
139+
break;
140+
}
141+
}
142+
}
143+
144+
} // namespace
145+
146+
namespace bb::avm2::fuzzer {
147+
148+
AccumulatedData generate_non_revertible_accumulated_data(std::mt19937_64& rng)
149+
{
150+
AccumulatedData data = generate_accumulated_data(rng);
151+
if (data.nullifiers.empty()) {
152+
// Need to ensure the "tx nullifier" exists
153+
data.nullifiers.push_back(generate_nullifier(rng));
154+
}
155+
return data;
156+
}
157+
void mutate_non_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng)
158+
{
159+
mutate_accumulated_data(data, rng);
160+
if (data.nullifiers.empty()) {
161+
// Need to ensure the "tx nullifier" exists
162+
data.nullifiers.push_back(generate_nullifier(rng));
163+
}
164+
}
165+
166+
AccumulatedData generate_revertible_accumulated_data(std::mt19937_64& rng)
167+
{
168+
return generate_accumulated_data(rng);
169+
}
170+
171+
void mutate_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng)
172+
{
173+
mutate_accumulated_data(data, rng);
174+
};
175+
176+
} // namespace bb::avm2::fuzzer
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
#include <random>
4+
5+
#include "barretenberg/avm_fuzzer/common/weighted_selection.hpp"
6+
#include "barretenberg/vm2/common/avm_io.hpp"
7+
8+
namespace bb::avm2::fuzzer {
9+
10+
enum class AccumulatedDataMutationOptions : uint8_t {
11+
NoteHashes,
12+
NoteHashesLimit,
13+
Nullifiers,
14+
NullifiersLimit,
15+
L2ToL1Messages,
16+
L2ToL1MessagesLimit,
17+
};
18+
19+
using AccumulatedDataMutationConfig = WeightedSelectionConfig<AccumulatedDataMutationOptions, 6>;
20+
21+
constexpr AccumulatedDataMutationConfig ACCUMULATED_DATA_MUTATION_CONFIGURATION = AccumulatedDataMutationConfig({
22+
{ AccumulatedDataMutationOptions::NoteHashes, 20 },
23+
{ AccumulatedDataMutationOptions::NoteHashesLimit, 1 },
24+
{ AccumulatedDataMutationOptions::Nullifiers, 20 },
25+
{ AccumulatedDataMutationOptions::NullifiersLimit, 1 },
26+
{ AccumulatedDataMutationOptions::L2ToL1Messages, 20 },
27+
{ AccumulatedDataMutationOptions::L2ToL1MessagesLimit, 1 },
28+
});
29+
30+
AccumulatedData generate_non_revertible_accumulated_data(std::mt19937_64& rng);
31+
void mutate_non_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng);
32+
33+
AccumulatedData generate_revertible_accumulated_data(std::mt19937_64& rng);
34+
void mutate_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng);
35+
36+
} // namespace bb::avm2::fuzzer

0 commit comments

Comments
 (0)