Skip to content

Commit 2effaa2

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/barretenberg
2 parents c7c476f + 41d60d0 commit 2effaa2

File tree

101 files changed

+4354
-422
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+4354
-422
lines changed

.test_patterns.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,3 @@ tests:
291291
flake_group_id: e2e-p2p-epoch-flakes
292292
owners:
293293
- *palla
294-
295-
- regex: "bb-prover/src/avm_proving_tests/avm_bulk.test.ts"
296-
error_regex: "Exceeded timeout"
297-
owners:
298-
- *alex

barretenberg/cpp/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ if(FUZZING)
8787
if(DISABLE_CUSTOM_MUTATORS)
8888
add_definitions(-DDISABLE_CUSTOM_MUTATORS=1)
8989
endif()
90-
91-
set(MULTITHREADING OFF)
9290
endif()
9391

9492
if(CMAKE_SYSTEM_PROCESSOR MATCHES "wasm32")

barretenberg/cpp/CMakePresets.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,20 @@
273273
"CXXFLAGS": "-fprofile-instr-generate -fcoverage-mapping"
274274
}
275275
},
276+
{
277+
"name": "fuzzing-avm",
278+
"displayName": "Build with fuzzing and AVM",
279+
"description": "Build default preset but with fuzzing and AVM enabled",
280+
"inherits": "clang20",
281+
"binaryDir": "build-fuzzing-avm",
282+
"cacheVariables": {
283+
"FUZZING": "ON",
284+
"DISABLE_ASM": "OFF",
285+
"AVM_TRANSPILER_LIB": "",
286+
"CMAKE_BUILD_TYPE": "RelWithAssert",
287+
"MULTITHREADING": "ON"
288+
}
289+
},
276290
{
277291
"name": "smt-verification",
278292
"displayName": "Build with smt verification",
@@ -580,6 +594,11 @@
580594
"inherits": "clang20",
581595
"configurePreset": "fuzzing-coverage"
582596
},
597+
{
598+
"name": "fuzzing-avm",
599+
"inherits": "clang20",
600+
"configurePreset": "fuzzing-avm"
601+
},
583602
{
584603
"name": "gperftools",
585604
"inherits": "clang20",

barretenberg/cpp/src/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,19 @@ add_subdirectory(barretenberg/translator_vm)
110110
add_subdirectory(barretenberg/ultra_honk)
111111
add_subdirectory(barretenberg/vm2_stub)
112112
add_subdirectory(barretenberg/wasi)
113+
add_subdirectory(barretenberg/world_state)
114+
add_subdirectory(barretenberg/lmdblib)
115+
116+
if(AVM)
117+
add_subdirectory(barretenberg/vm2)
118+
if(FUZZING)
119+
add_subdirectory(barretenberg/avm_fuzzer)
120+
endif()
121+
endif()
113122

114123
if(NOT FUZZING AND NOT WASM)
115124
add_subdirectory(barretenberg/ipc)
116-
add_subdirectory(barretenberg/lmdblib)
117125
add_subdirectory(barretenberg/nodejs_module)
118-
add_subdirectory(barretenberg/world_state)
119-
add_subdirectory(barretenberg/vm2)
120126
endif()
121127

122128
if(SMT)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
if(AVM AND FUZZING)
2+
barretenberg_module(avm_fuzzer vm2 nlohmann_json::nlohmann_json)
3+
endif()
4+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include <iomanip>
2+
#include <iostream>
3+
#include <random>
4+
#include <string>
5+
#include <vector>
6+
7+
#include "barretenberg/avm_fuzzer/fuzz_lib/control_flow.hpp"
8+
#include "barretenberg/avm_fuzzer/fuzz_lib/fuzz.hpp"
9+
#include "barretenberg/avm_fuzzer/fuzz_lib/fuzzer_data.hpp"
10+
#include "barretenberg/avm_fuzzer/fuzz_lib/simulator.hpp"
11+
#include "barretenberg/avm_fuzzer/mutations/fuzzer_data.hpp"
12+
#include "barretenberg/serialize/msgpack_impl.hpp"
13+
14+
using FuzzInstruction = ::FuzzInstruction;
15+
16+
/// Initializes the typescript simulator process
17+
/// See yarn-project/simulator/scripts/fuzzing/
18+
extern "C" int LLVMFuzzerInitialize(int*, char***)
19+
{
20+
21+
const char* simulator_path = std::getenv("AVM_SIMULATOR_BIN");
22+
if (simulator_path == nullptr) {
23+
throw std::runtime_error("AVM_SIMULATOR_BIN is not set");
24+
}
25+
std::string simulator_path_str(simulator_path);
26+
JsSimulator::initialize(simulator_path_str);
27+
return 0;
28+
}
29+
30+
SimulatorResult fuzz(const uint8_t* buffer, size_t size)
31+
{
32+
FuzzerData deserialized_data;
33+
try {
34+
msgpack::unpack((reinterpret_cast<const char*>(buffer)), size).get().convert(deserialized_data);
35+
} catch (const std::exception& e) {
36+
deserialized_data = FuzzerData();
37+
}
38+
auto res = fuzz(deserialized_data);
39+
40+
return res;
41+
}
42+
43+
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* serialized_fuzzer_data,
44+
size_t serialized_fuzzer_data_size,
45+
size_t max_size,
46+
unsigned int seed)
47+
{
48+
auto rng = std::mt19937_64(seed);
49+
FuzzerData deserialized_data;
50+
try {
51+
msgpack::unpack((reinterpret_cast<const char*>(serialized_fuzzer_data)), serialized_fuzzer_data_size)
52+
.get()
53+
.convert(deserialized_data);
54+
} catch (const std::exception& e) {
55+
deserialized_data = FuzzerData();
56+
}
57+
mutate_fuzzer_data(deserialized_data, rng);
58+
auto [mutated_serialized_fuzzer_data, mutated_serialized_fuzzer_data_size] =
59+
msgpack_encode_buffer(deserialized_data);
60+
if (mutated_serialized_fuzzer_data_size > max_size) {
61+
delete[] mutated_serialized_fuzzer_data;
62+
return 0;
63+
}
64+
65+
memcpy(serialized_fuzzer_data, mutated_serialized_fuzzer_data, mutated_serialized_fuzzer_data_size);
66+
delete[] mutated_serialized_fuzzer_data;
67+
68+
return mutated_serialized_fuzzer_data_size;
69+
}
70+
71+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
72+
{
73+
fuzz(data, size);
74+
return 0;
75+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "process.hpp"
2+
3+
Process::Process(const std::string& command)
4+
{
5+
int stdin_pipe[2]; // NOLINT
6+
int stdout_pipe[2]; // NOLINT
7+
pid_t pid = 0;
8+
9+
if (pipe(stdin_pipe) < 0 || pipe(stdout_pipe) < 0) {
10+
throw std::runtime_error("pipe() failed");
11+
}
12+
13+
pid = fork();
14+
if (pid < 0) {
15+
throw std::runtime_error("fork() failed");
16+
}
17+
18+
if (pid == 0) { // Child process
19+
close(stdin_pipe[1]);
20+
close(stdout_pipe[0]);
21+
22+
dup2(stdin_pipe[0], STDIN_FILENO);
23+
dup2(stdout_pipe[1], STDOUT_FILENO);
24+
25+
close(stdin_pipe[0]);
26+
close(stdout_pipe[1]);
27+
28+
execl("/bin/sh", "sh", "-c", command.c_str(), nullptr); // NOLINT
29+
exit(1);
30+
}
31+
32+
// Parent process
33+
close(stdin_pipe[0]);
34+
close(stdout_pipe[1]);
35+
36+
this->pid = pid;
37+
this->stdin_fd = stdin_pipe[1];
38+
this->stdout_fd = stdout_pipe[0];
39+
}
40+
41+
Process::~Process()
42+
{
43+
close(stdin_fd);
44+
close(stdout_fd);
45+
waitpid(pid, nullptr, 0);
46+
}
47+
48+
void Process::write_line(const std::string& line) const
49+
{
50+
std::string command = line + "\n";
51+
write(stdin_fd, command.c_str(), command.size());
52+
}
53+
54+
std::string Process::read_line() const
55+
{
56+
char buffer[4096]; // NOLINT
57+
std::string response;
58+
ssize_t bytes_read = 0;
59+
while ((bytes_read = read(stdout_fd, buffer, sizeof(buffer))) > 0) {
60+
response.append(buffer, static_cast<size_t>(bytes_read));
61+
if (response.find('\n') != std::string::npos) {
62+
break;
63+
}
64+
}
65+
return response;
66+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <array>
2+
#include <iostream>
3+
#include <memory>
4+
#include <string>
5+
#include <sys/wait.h>
6+
#include <unistd.h>
7+
8+
class Process {
9+
private:
10+
pid_t pid;
11+
int stdin_fd = 0;
12+
int stdout_fd = 0;
13+
14+
public:
15+
Process(const std::string& command);
16+
~Process();
17+
Process(const Process&) = delete;
18+
Process& operator=(const Process&) = delete;
19+
Process(Process&&) = default;
20+
Process& operator=(Process&&) = default;
21+
22+
/// Ends line with a newline character, sends to the process.
23+
void write_line(const std::string& line) const;
24+
25+
/// Reads a line from the process.
26+
std::string read_line() const;
27+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <array>
4+
#include <random>
5+
#include <stdexcept>
6+
#include <vector>
7+
8+
template <typename T, size_t N> class WeightedSelectionConfig {
9+
private:
10+
std::array<std::pair<T, size_t>, N> options_with_weights;
11+
size_t total_weight = 0;
12+
13+
public:
14+
constexpr WeightedSelectionConfig(const std::array<std::pair<T, size_t>, N>& options_with_weights)
15+
: options_with_weights(options_with_weights)
16+
{
17+
for (const auto& [option, weight] : options_with_weights) {
18+
total_weight += weight;
19+
}
20+
}
21+
22+
constexpr WeightedSelectionConfig(std::initializer_list<std::pair<T, size_t>> options_with_weights)
23+
: options_with_weights()
24+
{
25+
size_t i = 0;
26+
for (const auto& [option, weight] : options_with_weights) {
27+
this->options_with_weights[i] = { option, weight };
28+
total_weight += weight;
29+
++i;
30+
}
31+
}
32+
33+
T select(std::mt19937_64& rng) const
34+
{
35+
std::uniform_int_distribution<size_t> dist(0, total_weight - 1);
36+
size_t selector = dist(rng);
37+
38+
for (const auto& [option, weight] : options_with_weights) {
39+
if (selector < weight) {
40+
return option;
41+
}
42+
selector -= weight;
43+
}
44+
45+
throw std::runtime_error("Should have returned by now");
46+
}
47+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "barretenberg/avm_fuzzer/fuzz_lib/control_flow.hpp"
2+
3+
void ControlFlow::process_insert_simple_instruction_block(InsertSimpleInstructionBlock instruction)
4+
{
5+
if (instruction_blocks->size() == 0) {
6+
return;
7+
}
8+
auto instruction_block = instruction_blocks->at(instruction.instruction_block_idx % instruction_blocks->size());
9+
for (const auto& instr : instruction_block) {
10+
current_block.process_instruction(instr);
11+
}
12+
}
13+
14+
void ControlFlow::process_cfg_instruction(CFGInstruction instruction)
15+
{
16+
std::visit(overloaded_cfg_instruction{ [&](InsertSimpleInstructionBlock arg) {
17+
process_insert_simple_instruction_block(arg);
18+
} },
19+
instruction);
20+
}
21+
22+
// Helper function to create bytecode from a vector of instructions
23+
std::vector<uint8_t> create_bytecode(const std::vector<bb::avm2::simulation::Instruction>& instructions)
24+
{
25+
std::vector<uint8_t> bytecode;
26+
for (const auto& instruction : instructions) {
27+
auto serialized_instruction = instruction.serialize();
28+
bytecode.insert(bytecode.end(),
29+
std::make_move_iterator(serialized_instruction.begin()),
30+
std::make_move_iterator(serialized_instruction.end()));
31+
}
32+
return bytecode;
33+
}
34+
35+
std::vector<uint8_t> ControlFlow::build_bytecode(const ReturnOptions& return_options)
36+
{
37+
current_block.finalize_with_return(
38+
/*TODO(defkit) fix return size */ 1, return_options.return_value_tag, return_options.return_value_offset_index);
39+
return create_bytecode(current_block.get_instructions());
40+
}

0 commit comments

Comments
 (0)