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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "barretenberg/vm2/simulation/events/event_emitter.hpp"
#include "barretenberg/vm2/simulation/gadgets/calldata_hashing.hpp"
#include "barretenberg/vm2/simulation/interfaces/calldata_hashing.hpp"
#include "barretenberg/vm2/simulation/lib/contract_crypto.hpp"
#include "barretenberg/vm2/tooling/debugger.hpp"
#include "barretenberg/vm2/tracegen/calldata_trace.hpp"
#include "barretenberg/vm2/tracegen/execution_trace.hpp"
Expand Down Expand Up @@ -363,7 +364,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
try {
for (size_t i = 0; i < num_events; i++) {
auto calldata_interface = calldata_hashing_provider.make_calldata_hasher(context_id++);
calldata_interface->compute_calldata_hash(calldata_fields[i]);
FF cd_hash = compute_calldata_hash(calldata_fields[i]);
calldata_interface->assert_calldata_hash(cd_hash, calldata_fields[i]);
}
} catch (const std::exception& e) {
// If any exception occurs, we cannot proceed further.
Expand Down
182 changes: 56 additions & 126 deletions barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,60 @@
#include "barretenberg/avm_fuzzer/mutations/tx_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/fuzzer_data.hpp"
#include "barretenberg/avm_fuzzer/mutations/instructions/instruction_block.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"
#include "barretenberg/vm2/common/aztec_types.hpp"
#include "barretenberg/vm2/common/tagged_value.hpp"
#include "barretenberg/vm2/simulation/lib/contract_crypto.hpp"

#include <optional>
#include <random>

namespace {

void mutate_enqueued_calls(std::vector<PublicCallRequestWithCalldata>& enqueued_calls,
std::vector<AztecAddress>& contract_addresses,
std::mt19937_64& rng)
{
auto mutate_fn = [&](PublicCallRequestWithCalldata& call, std::mt19937_64& rng) {
bb::avm2::fuzzer::mutate_public_call_request(call, contract_addresses, rng);
};

auto gen_fn = [&](std::mt19937_64& rng) {
return bb::avm2::fuzzer::generate_public_call_request(contract_addresses, rng);
};

mutate_vec<PublicCallRequestWithCalldata>(enqueued_calls, rng, mutate_fn, gen_fn, BASIC_VEC_MUTATION_CONFIGURATION);
};

void mutate_teardown(std::optional<PublicCallRequestWithCalldata>& teardown_call,
std::vector<AztecAddress>& contract_addresses,
std::mt19937_64& rng)
{
if (!teardown_call.has_value()) {
// Nothing to mutate, generate a new one
teardown_call = bb::avm2::fuzzer::generate_public_call_request(contract_addresses, rng);
return;
}

// If we already have a teardown call, there's a 1 in 10 chance we discard it
bool discard = std::uniform_int_distribution<int>(0, 9)(rng) == 0;
if (discard) {
fuzz_info("Discarding teardown enqueued call");
teardown_call = std::nullopt;
} else {
// Mutate existing teardown call
bb::avm2::fuzzer::mutate_public_call_request(teardown_call.value(), contract_addresses, rng);
}
}

} // namespace

namespace bb::avm2::fuzzer {

// Gas bounds for mutation
Expand All @@ -29,32 +73,25 @@ constexpr uint32_t AVM_MAX_PROCESSABLE_DA_GAS = (MAX_NOTE_HASHES_PER_TX * AVM_EM

void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt19937_64& rng)
{
auto choice = std::uniform_int_distribution<uint8_t>(0, 1)(rng);
auto choice = TX_MUTATION_CONFIGURATION.select(rng);

switch (choice) {
case 0:
case TxMutationOptions::SetupEnqueuedCalls:
// Mutate setup enqueued calls
fuzz_info("Mutating setup enqueued calls: ", tx.setup_enqueued_calls.size());
mutate_vec<PublicCallRequestWithCalldata>(
tx.setup_enqueued_calls,
rng,
[&](PublicCallRequestWithCalldata& call, std::mt19937_64& rng) {
mutate_public_call_request(call, contract_addresses, rng);
},
[&](std::mt19937_64& rng) { return generate_public_call_request(contract_addresses, rng); },
BASIC_VEC_MUTATION_CONFIGURATION);
mutate_enqueued_calls(tx.setup_enqueued_calls, contract_addresses, rng);
break;
case 1:
case TxMutationOptions::AppLogicEnqueuedCalls:
// Mutate app logic enqueued calls
fuzz_info("Mutating app logic enqueued calls: ", tx.app_logic_enqueued_calls.size());
mutate_vec<PublicCallRequestWithCalldata>(
tx.app_logic_enqueued_calls,
rng,
[&](PublicCallRequestWithCalldata& call, std::mt19937_64& rng) {
mutate_public_call_request(call, contract_addresses, rng);
},
[&](std::mt19937_64& rng) { return generate_public_call_request(contract_addresses, rng); },
BASIC_VEC_MUTATION_CONFIGURATION);
mutate_enqueued_calls(tx.app_logic_enqueued_calls, contract_addresses, rng);
break;
case TxMutationOptions::TearDownEnqueuedCall:
// Mutate teardown enqueued call
fuzz_info("Mutating teardown enqueued call");
mutate_teardown(tx.teardown_enqueued_call, contract_addresses, rng);
break;

// case 2:
// // Mutate gas_settings
// mutate_gas_settings(tx.gas_settings, rng);
Expand Down Expand Up @@ -92,10 +129,6 @@ void mutate_tx(Tx& tx, std::vector<AztecAddress>& contract_addresses, std::mt199
// BASIC_VEC_MUTATION_CONFIGURATION);
// break;
// break;
// case 7:
// // Mutate teardown enqueued call
//
// break;
// case 8:
// // Mutate gas_used_by_private
// break;
Expand Down Expand Up @@ -180,20 +213,6 @@ void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng)
}
}

void mutate_ff_vec(std::vector<FF>& vec, std::mt19937_64& rng, size_t max_size)
{
mutate_vec<FF>(
vec,
rng,
[](bb::avm2::FF& value, std::mt19937_64& rng) { mutate_field(value, rng, BASIC_FIELD_MUTATION_CONFIGURATION); },
generate_random_field,
BASIC_VEC_MUTATION_CONFIGURATION);

if (vec.size() > max_size) {
vec.resize(max_size);
}
}

void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
{
auto choice = std::uniform_int_distribution<uint8_t>(0, 2)(rng);
Expand Down Expand Up @@ -222,26 +241,6 @@ ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng)
};
}

void mutate_bool_vec(std::vector<bool>& vec, size_t target_size, std::mt19937_64& rng)
{
// Resize to match target size
while (vec.size() < target_size) {
vec.push_back(std::uniform_int_distribution<uint8_t>(0, 1)(rng) == 1);
}
while (vec.size() > target_size) {
vec.pop_back();
}

// Flip a random bool with some probability
if (!vec.empty()) {
auto flip_prob = std::uniform_int_distribution<uint8_t>(0, 4)(rng);
if (flip_prob == 0) {
auto idx = std::uniform_int_distribution<size_t>(0, vec.size() - 1)(rng);
vec[idx] = !vec[idx];
}
}
}

void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt19937_64& rng, size_t max_size)
{
auto choice = std::uniform_int_distribution<uint8_t>(0, 1)(rng);
Expand Down Expand Up @@ -278,73 +277,4 @@ void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt1993
}
}

void mutate_public_call_request([[maybe_unused]] PublicCallRequestWithCalldata& request,
[[maybe_unused]] std::vector<AztecAddress>& contract_addresses,
[[maybe_unused]] std::mt19937_64& rng)
{
if (contract_addresses.empty()) {
return; // Nothing to mutate to
}
// fixme(ilyas): this should be weighted since stuff like mutate calldata hash is fail-early
auto choice = std::uniform_int_distribution<uint8_t>(0, 0)(rng);
//
switch (choice) {
case 0:
// Mutate contract_address
// This is likely to cause immediate failure, needs to be weighted appropriately
auto contract_address_choice = std::uniform_int_distribution<size_t>(0, contract_addresses.size() - 1)(rng);
auto contract_address = contract_addresses[contract_address_choice];
request.request.contract_address = contract_address;
break;
// case 1:
// // Mutate msg_sender
// request.request.msg_sender = generate_random_field(rng);
// break;
// case 2: {
// // Mutate is_static_call
// request.request.is_static_call = !request.request.is_static_call;
// break;
// }
// case 3:
// // Mutate calldata_hash - the intention here is to fail the hash check
// request.request.calldata_hash = generate_random_field(rng);
// break;
// case 4:
// // Mutate calldata
// mutate_ff_vec(request.calldata, rng, 256);
// // fixme: recompute calldata_hash when we start doing tracegen versions
// // request.calldata_hash = compute_calldata_hash(request.calldata);
// break;
}
}

PublicCallRequestWithCalldata generate_public_call_request(std::vector<AztecAddress>& contract_addresses,
std::mt19937_64& rng)
{
fuzz_info("Generating new public call request");
// Generate random calldata
size_t calldata_size = std::uniform_int_distribution<size_t>(0, 256)(rng);
std::vector<FF> calldata{};
for (size_t i = 0; i < calldata_size; ++i) {
calldata.push_back(generate_random_field(rng));
}

auto contract_address =
contract_addresses.empty()
? generate_random_field(rng)
: contract_addresses[std::uniform_int_distribution<size_t>(0, contract_addresses.size() - 1)(rng)];
fuzz_info("Using contract address: ", contract_address);
FF calldata_hash = simulation::compute_calldata_hash(calldata);
return PublicCallRequestWithCalldata{
.request =
PublicCallRequest{
.msg_sender = generate_random_field(rng),
.contract_address = contract_address,
.is_static_call = (std::uniform_int_distribution<uint8_t>(0, 1)(rng) == 1),
.calldata_hash = calldata_hash,
},
.calldata = calldata,
};
}

} // namespace bb::avm2::fuzzer
30 changes: 15 additions & 15 deletions barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
#pragma once

#include <functional>
#include <optional>
#include <random>
#include <vector>

#include "barretenberg/avm_fuzzer/common/weighted_selection.hpp"
#include "barretenberg/avm_fuzzer/fuzz_lib/fuzzer_data.hpp"
#include "barretenberg/vm2/common/avm_io.hpp"
#include "barretenberg/vm2/common/aztec_types.hpp"
#include "barretenberg/vm2/common/field.hpp"

enum class TxMutationOptions {
SetupEnqueuedCalls,
AppLogicEnqueuedCalls,
TearDownEnqueuedCall,
};

using TxMutationConfig = WeightedSelectionConfig<TxMutationOptions, 3>;

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

namespace bb::avm2::fuzzer {

Expand All @@ -23,22 +35,10 @@ void mutate_gas(Gas& gas, std::mt19937_64& rng);
// GasFees mutation
void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng);

// Field vector mutation
void mutate_ff_vec(std::vector<FF>& vec, std::mt19937_64& rng, size_t max_size = 10);

// 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);

// Boolean vector mutation
void mutate_bool_vec(std::vector<bool>& vec, size_t target_size, std::mt19937_64& rng);

void mutate_fuzzer_data_vec(std::vector<FuzzerData>& enqueued_calls, std::mt19937_64& rng, size_t max_size = 10);

void mutate_public_call_request(PublicCallRequestWithCalldata& request,
std::vector<AztecAddress>& contract_addreses,
std::mt19937_64& rng);
PublicCallRequestWithCalldata generate_public_call_request(std::vector<AztecAddress>& contract_addresses,
std::mt19937_64& rng);

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