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
65 changes: 11 additions & 54 deletions barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "barretenberg/avm_fuzzer/mutations/basic_types/vector.hpp"
#include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp"
#include "barretenberg/avm_fuzzer/mutations/instructions/instruction_block.hpp"
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp"
#include "barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp"
#include "barretenberg/vm2/common/avm_io.hpp"
#include "barretenberg/vm2/common/aztec_constants.hpp"
Expand Down Expand Up @@ -91,6 +92,16 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
fuzz_info("Mutating teardown enqueued call");
mutate_teardown(tx.teardown_enqueued_call, contract_addresses, rng);
break;
case TxMutationOptions::NonRevertibleData:
// Mutate non-revertible accumulated data
fuzz_info("Mutating non-revertible accumulated data");
mutate_non_revertible_accumulated_data(tx.non_revertible_accumulated_data, rng);
break;
case TxMutationOptions::RevertibleData:
// Mutate revertible accumulated data
fuzz_info("Mutating revertible accumulated data");
mutate_revertible_accumulated_data(tx.revertible_accumulated_data, rng);
break;

// case 2:
// // Mutate gas_settings
Expand All @@ -103,32 +114,6 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
// case 4:
// // Mutate Deployment data
// break;
// case 5:
// // Mutate non-revertible accumulated data
// // fixme: maybe don't change all stuff
// mutate_ff_vec(tx.non_revertible_accumulated_data.note_hashes, rng, MAX_NOTE_HASHES_PER_TX);
// mutate_ff_vec(tx.non_revertible_accumulated_data.nullifiers, rng, MAX_NULLIFIERS_PER_TX);
// mutate_vec<ScopedL2ToL1Message>(tx.non_revertible_accumulated_data.l2_to_l1_messages,
// rng,
// mutate_l2_to_l1_msg,
// generate_l2_to_l1_msg,
// BASIC_VEC_MUTATION_CONFIGURATION);
// if (tx.non_revertible_accumulated_data.nullifiers.empty()) {
// // Need to ensure the "tx nullifier" exists
// tx.non_revertible_accumulated_data.nullifiers.push_back(generate_random_field(rng));
// }
// break;
// case 6:
// // Mutate revertible accumulated data
// mutate_ff_vec(tx.revertible_accumulated_data.note_hashes, rng, MAX_NOTE_HASHES_PER_TX);
// mutate_ff_vec(tx.revertible_accumulated_data.nullifiers, rng, MAX_NULLIFIERS_PER_TX);
// mutate_vec<ScopedL2ToL1Message>(tx.revertible_accumulated_data.l2_to_l1_messages,
// rng,
// mutate_l2_to_l1_msg,
// generate_l2_to_l1_msg,
// BASIC_VEC_MUTATION_CONFIGURATION);
// break;
// break;
// case 8:
// // Mutate gas_used_by_private
// break;
Expand Down Expand Up @@ -213,34 +198,6 @@ void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng)
}
}

void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
{
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);

switch (choice) {
case 0:
// Mutate recipient
msg.message.recipient = generate_random_field(rng);
break;
case 1:
// Mutate content
msg.message.content = generate_random_field(rng);
break;
case 2:
// Mutate contract_address
msg.contract_address = generate_random_field(rng);
break;
}
}

ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng)
{
return ScopedL2ToL1Message{
.message = L2ToL1Message{ .recipient = generate_random_field(rng), .content = generate_random_field(rng) },
.contract_address = generate_random_field(rng),
};
}

void mutate_fuzzer_data_vec(const FuzzerContext& context,
std::vector<FuzzerData>& enqueued_calls,
std::mt19937_64& rng,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ enum class TxMutationOptions {
SetupEnqueuedCalls,
AppLogicEnqueuedCalls,
TearDownEnqueuedCall,
NonRevertibleData,
RevertibleData,
};

using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 3>;
using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 5>;

constexpr TxMutationConfig TX_MUTATION_CONFIGURATION = TxMutationConfig({
{ TxMutationOptions::SetupEnqueuedCalls, 30 },
{ TxMutationOptions::AppLogicEnqueuedCalls, 30 },
{ TxMutationOptions::TearDownEnqueuedCall, 10 },
{ TxMutationOptions::NonRevertibleData, 15 },
{ TxMutationOptions::RevertibleData, 15 },
});

namespace bb::avm2::fuzzer {
Expand All @@ -36,10 +40,6 @@ void mutate_gas(Gas& gas, std::mt19937_64& rng);
// GasFees mutation
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng);

// L2ToL1Msg vector mutation
void mutate_l2_to_l1_msg(ScopedL2ToL1Message& vec, std::mt19937_64& rng);
ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng);

void mutate_fuzzer_data_vec(const FuzzerContext& context,
std::vector<FuzzerData>& enqueued_calls,
std::mt19937_64& rng,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp"

#include "barretenberg/avm_fuzzer/fuzz_lib/constants.hpp"
#include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp"
#include "barretenberg/avm_fuzzer/mutations/basic_types/vector.hpp"
#include "barretenberg/avm_fuzzer/mutations/configuration.hpp"
#include "barretenberg/vm2/common/avm_io.hpp"

using bb::avm2::AztecAddress;
using bb::avm2::FF;

namespace {

// Generate a random note hash
FF generate_note_hash(std::mt19937_64& rng)
{
return generate_random_field(rng);
}

void mutate_note_hash(FF& note_hash, std::mt19937_64& rng)
{
mutate_field(note_hash, rng, BASIC_FIELD_MUTATION_CONFIGURATION);
}

// Generate a random nullifier
FF generate_nullifier(std::mt19937_64& rng)
{
return generate_random_field(rng);
}

void mutate_nullifier(FF& nullifier, std::mt19937_64& rng)
{
mutate_field(nullifier, rng, BASIC_FIELD_MUTATION_CONFIGURATION);
}

// Generate a random L2 to L1 message
ScopedL2ToL1Message generate_l2_to_l1_message(std::mt19937_64& rng)
{
return ScopedL2ToL1Message{
.message = L2ToL1Message{ .recipient = generate_random_field(rng), .content = generate_random_field(rng) },
.contract_address = generate_random_field(rng),
};
}

void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
{
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);

switch (choice) {
case 0:
// Mutate recipient
msg.message.recipient = generate_random_field(rng);
break;
case 1:
// Mutate content
msg.message.content = generate_random_field(rng);
break;
case 2:
// Mutate contract_address
msg.contract_address = generate_random_field(rng);
break;
default:
break;
}
}

AccumulatedData generate_accumulated_data(std::mt19937_64& rng)
{
// When we generate new accumulated data we can simply generate a small number of entries
// We test the limits during mutation
std::vector<FF> note_hashes;
size_t num_note_hashes = std::uniform_int_distribution<size_t>(0, 4)(rng);
note_hashes.reserve(num_note_hashes);
for (size_t i = 0; i < num_note_hashes; i++) {
note_hashes.push_back(generate_note_hash(rng));
}
std::vector<FF> nullifiers;
size_t num_nullifiers = std::uniform_int_distribution<size_t>(0, 4)(rng);
nullifiers.reserve(num_nullifiers);
for (size_t i = 0; i < num_nullifiers; i++) {
nullifiers.push_back(generate_nullifier(rng));
}
std::vector<ScopedL2ToL1Message> l2_to_l1_messages;
size_t num_messages = std::uniform_int_distribution<size_t>(0, 4)(rng);
l2_to_l1_messages.reserve(num_messages);
for (size_t i = 0; i < num_messages; i++) {
l2_to_l1_messages.push_back(generate_l2_to_l1_message(rng));
}

return AccumulatedData{
.note_hashes = note_hashes,
.nullifiers = nullifiers,
.l2_to_l1_messages = l2_to_l1_messages,
};
}

void mutate_accumulated_data(AccumulatedData& input, std::mt19937_64& rng)
{
using namespace bb::avm2::fuzzer;
// We only really care about the existence of note hashes, nullifiers, and L2 to L1 messages
// or if these values end up triggering limit errors during execution.
auto choice = ACCUMULATED_DATA_MUTATION_CONFIGURATION.select(rng);
switch (choice) {
case AccumulatedDataMutationOptions::NoteHashes:
mutate_vec_with_limit<FF>(input.note_hashes,
rng,
mutate_note_hash,
generate_note_hash,
BASIC_VEC_MUTATION_CONFIGURATION,
MAX_NOTE_HASHES_PER_TX);
break;
case AccumulatedDataMutationOptions::NoteHashesLimit: {
size_t original_size = input.note_hashes.size();
input.note_hashes.resize(MAX_NOTE_HASHES_PER_TX);
for (size_t i = original_size; i < MAX_NOTE_HASHES_PER_TX; i++) {
input.note_hashes[i] = generate_note_hash(rng);
}
break;
}
case AccumulatedDataMutationOptions::Nullifiers:
mutate_vec_with_limit<FF>(input.nullifiers,
rng,
mutate_nullifier,
generate_nullifier,
BASIC_VEC_MUTATION_CONFIGURATION,
MAX_NULLIFIERS_PER_TX);
break;
case AccumulatedDataMutationOptions::NullifiersLimit: {
size_t original_size = input.nullifiers.size();
input.nullifiers.resize(MAX_NULLIFIERS_PER_TX);
for (size_t i = original_size; i < MAX_NULLIFIERS_PER_TX; i++) {
input.nullifiers[i] = generate_nullifier(rng);
}
break;
}
case AccumulatedDataMutationOptions::L2ToL1Messages:
mutate_vec_with_limit<ScopedL2ToL1Message>(input.l2_to_l1_messages,
rng,
mutate_l2_to_l1_msg,
generate_l2_to_l1_message,
BASIC_VEC_MUTATION_CONFIGURATION,
MAX_L2_TO_L1_MSGS_PER_TX);
break;
case AccumulatedDataMutationOptions::L2ToL1MessagesLimit: {
size_t original_size = input.l2_to_l1_messages.size();
input.l2_to_l1_messages.resize(MAX_L2_TO_L1_MSGS_PER_TX);
for (size_t i = original_size; i < MAX_L2_TO_L1_MSGS_PER_TX; i++) {
input.l2_to_l1_messages[i] = generate_l2_to_l1_message(rng);
}
break;
}
}
}

} // namespace

namespace bb::avm2::fuzzer {

AccumulatedData generate_non_revertible_accumulated_data(std::mt19937_64& rng)
{
AccumulatedData data = generate_accumulated_data(rng);
if (data.nullifiers.empty()) {
// Need to ensure the "tx nullifier" exists
data.nullifiers.push_back(generate_nullifier(rng));
}
return data;
}
void mutate_non_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng)
{
mutate_accumulated_data(data, rng);
if (data.nullifiers.empty()) {
// Need to ensure the "tx nullifier" exists
data.nullifiers.push_back(generate_nullifier(rng));
}
}

AccumulatedData generate_revertible_accumulated_data(std::mt19937_64& rng)
{
return generate_accumulated_data(rng);
}

void mutate_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng)
{
mutate_accumulated_data(data, rng);
};

} // namespace bb::avm2::fuzzer
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include <random>

#include "barretenberg/avm_fuzzer/common/weighted_selection.hpp"
#include "barretenberg/avm_fuzzer/mutations/configuration.hpp"
#include "barretenberg/vm2/common/avm_io.hpp"

namespace bb::avm2::fuzzer {

enum class AccumulatedDataMutationOptions : uint8_t {
NoteHashes,
NoteHashesLimit,
Nullifiers,
NullifiersLimit,
L2ToL1Messages,
L2ToL1MessagesLimit,
};

using AccumulatedDataMutationConfig = WeightedSelectionConfig<AccumulatedDataMutationOptions, 6>;

constexpr AccumulatedDataMutationConfig ACCUMULATED_DATA_MUTATION_CONFIGURATION = AccumulatedDataMutationConfig({
{ AccumulatedDataMutationOptions::NoteHashes, 20 },
{ AccumulatedDataMutationOptions::NoteHashesLimit, 1 },
{ AccumulatedDataMutationOptions::Nullifiers, 20 },
{ AccumulatedDataMutationOptions::NullifiersLimit, 1 },
{ AccumulatedDataMutationOptions::L2ToL1Messages, 20 },
{ AccumulatedDataMutationOptions::L2ToL1MessagesLimit, 1 },
});

template <typename T>
void mutate_vec_with_limit(std::vector<T>& vec,
std::mt19937_64& rng,
std::function<void(T&, std::mt19937_64&)> mutate_element_function,
std::function<T(std::mt19937_64&)> generate_random_element_function,
const VecMutationConfig& config,
size_t vec_limit)
{
mutate_vec<T>(vec, rng, mutate_element_function, generate_random_element_function, config);
if (vec.size() > vec_limit) {
vec.resize(vec_limit);
}
}

AccumulatedData generate_non_revertible_accumulated_data(std::mt19937_64& rng);
void mutate_non_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng);

AccumulatedData generate_revertible_accumulated_data(std::mt19937_64& rng);
void mutate_revertible_accumulated_data(AccumulatedData& data, std::mt19937_64& rng);

} // namespace bb::avm2::fuzzer
Loading