From 998b6c7e773034b3199fae85f3a48639b828e354 Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Sun, 4 Jan 2026 20:39:52 +0000 Subject: [PATCH 1/2] feat(avm): mutate enqueued calls --- .../avm_fuzzer/mutations/tx_data.cpp | 182 ++++++------------ .../avm_fuzzer/mutations/tx_data.hpp | 30 +-- .../tx_types/public_call_request.cpp | 105 ++++++++++ .../tx_types/public_call_request.hpp | 36 ++++ .../barretenberg/avm_fuzzer/prover.fuzzer.cpp | 1 - .../vm2/simulation/gadgets/tx_execution.cpp | 3 +- 6 files changed, 214 insertions(+), 143 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp create mode 100644 barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp index 2ded216ba3e0..71ec8b4dea49 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.cpp @@ -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 #include +namespace { + +void mutate_enqueued_calls(std::vector& enqueued_calls, + std::vector& 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(enqueued_calls, rng, mutate_fn, gen_fn, BASIC_VEC_MUTATION_CONFIGURATION); +}; + +void mutate_teardown(std::optional& teardown_call, + std::vector& 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(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 @@ -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& contract_addresses, std::mt19937_64& rng) { - auto choice = std::uniform_int_distribution(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( - 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( - 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); @@ -92,10 +129,6 @@ void mutate_tx(Tx& tx, std::vector& 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; @@ -180,20 +213,6 @@ void mutate_gas_fees(GasFees& fees, std::mt19937_64& rng) } } -void mutate_ff_vec(std::vector& vec, std::mt19937_64& rng, size_t max_size) -{ - mutate_vec( - 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(0, 2)(rng); @@ -222,26 +241,6 @@ ScopedL2ToL1Message generate_l2_to_l1_msg(std::mt19937_64& rng) }; } -void mutate_bool_vec(std::vector& 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(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(0, 4)(rng); - if (flip_prob == 0) { - auto idx = std::uniform_int_distribution(0, vec.size() - 1)(rng); - vec[idx] = !vec[idx]; - } - } -} - void mutate_fuzzer_data_vec(std::vector& enqueued_calls, std::mt19937_64& rng, size_t max_size) { auto choice = std::uniform_int_distribution(0, 1)(rng); @@ -278,73 +277,4 @@ void mutate_fuzzer_data_vec(std::vector& enqueued_calls, std::mt1993 } } -void mutate_public_call_request([[maybe_unused]] PublicCallRequestWithCalldata& request, - [[maybe_unused]] std::vector& 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(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(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& contract_addresses, - std::mt19937_64& rng) -{ - fuzz_info("Generating new public call request"); - // Generate random calldata - size_t calldata_size = std::uniform_int_distribution(0, 256)(rng); - std::vector 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(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(0, 1)(rng) == 1), - .calldata_hash = calldata_hash, - }, - .calldata = calldata, - }; -} - } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp index 958b336a1bce..ab7f6f37bf30 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_data.hpp @@ -1,14 +1,26 @@ #pragma once -#include -#include #include #include +#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; + +constexpr TxMutationConfig TX_MUTATION_CONFIGURATION = TxMutationConfig({ + { TxMutationOptions::SetupEnqueuedCalls, 30 }, + { TxMutationOptions::AppLogicEnqueuedCalls, 30 }, + { TxMutationOptions::TearDownEnqueuedCall, 10 }, +}); namespace bb::avm2::fuzzer { @@ -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& 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& vec, size_t target_size, std::mt19937_64& rng); - void mutate_fuzzer_data_vec(std::vector& enqueued_calls, std::mt19937_64& rng, size_t max_size = 10); -void mutate_public_call_request(PublicCallRequestWithCalldata& request, - std::vector& contract_addreses, - std::mt19937_64& rng); -PublicCallRequestWithCalldata generate_public_call_request(std::vector& contract_addresses, - std::mt19937_64& rng); - } // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp new file mode 100644 index 000000000000..f88b7062b126 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.cpp @@ -0,0 +1,105 @@ +#include "barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.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/calldata/calldata_vec.hpp" +#include "barretenberg/avm_fuzzer/mutations/configuration.hpp" +#include "barretenberg/vm2/common/avm_io.hpp" +#include "barretenberg/vm2/simulation/lib/contract_crypto.hpp" + +using bb::avm2::AztecAddress; +using bb::avm2::FF; + +namespace { + +void mutate_contract_address(AztecAddress& address, std::vector& contract_addresses, std::mt19937_64& rng) +{ + if (contract_addresses.empty()) { + address = generate_random_field(rng); + } + // Most of the time we want to pick from the existing contract addresses, since a random address will fail early + auto contract_address_choice = std::uniform_int_distribution(0, contract_addresses.size() - 1)(rng); + address = contract_addresses[contract_address_choice]; + + // 1 in 1000 chance for the contract address to be random + bool random_address = std::uniform_int_distribution(0, 999)(rng) == 0; + if (random_address) { + fuzz_info("Mutating contract address to a random address"); + mutate_field(address, rng, BASIC_FIELD_MUTATION_CONFIGURATION); + } +} + +void mutate_calldata(PublicCallRequestWithCalldata& request, std::mt19937_64& rng) +{ + mutate_calldata_vec(request.calldata, rng); + if (request.calldata.size() > fuzzer::MAX_CALLDATA_SIZE) { + request.calldata.resize(fuzzer::MAX_CALLDATA_SIZE); + } + + request.request.calldata_hash = simulation::compute_calldata_hash(request.calldata); +} + +} // namespace + +namespace bb::avm2::fuzzer { + +void mutate_public_call_request(PublicCallRequestWithCalldata& request, + std::vector& contract_addresses, + std::mt19937_64& rng) +{ + fuzz_info("Mutating public call request"); + auto choice = PUB_REQUEST_MUTATION_CONFIGURATION.select(rng); + + switch (choice) { + case PublicCallRequestMutationOptions::ContractAddress: + // Mutate contract_address + mutate_contract_address(request.request.contract_address, contract_addresses, rng); + break; + case PublicCallRequestMutationOptions::MsgSender: + // Mutate msg_sender + mutate_field(request.request.msg_sender, rng, BASIC_FIELD_MUTATION_CONFIGURATION); + break; + case PublicCallRequestMutationOptions::IsStaticCall: + // Mutate is_static_call + request.request.is_static_call = !request.request.is_static_call; + break; + case PublicCallRequestMutationOptions::Calldata: + // Mutate calldata, this also updates the calldata_hash + mutate_calldata(request, rng); + break; + } +} + +PublicCallRequestWithCalldata generate_public_call_request(std::vector& contract_addresses, + std::mt19937_64& rng) +{ + fuzz_info("Generating new public call request"); + // Generate random calldata + size_t calldata_size = std::uniform_int_distribution(0, MAX_CALLDATA_SIZE)(rng); + std::vector calldata; + calldata.reserve(calldata_size); + 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(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(0, 1)(rng) == 1), + .calldata_hash = calldata_hash, + }, + .calldata = calldata, + }; +} + +} // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp new file mode 100644 index 000000000000..e97c1659eed6 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/public_call_request.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "barretenberg/avm_fuzzer/common/weighted_selection.hpp" +#include "barretenberg/vm2/common/avm_io.hpp" +#include "barretenberg/vm2/common/aztec_types.hpp" + +namespace bb::avm2::fuzzer { + +constexpr uint16_t MAX_CALLDATA_SIZE = 256; + +enum class PublicCallRequestMutationOptions : uint8_t { + ContractAddress, + MsgSender, + IsStaticCall, + Calldata, +}; + +using PublicCallRequestMutationConfig = WeightedSelectionConfig; + +constexpr PublicCallRequestMutationConfig PUB_REQUEST_MUTATION_CONFIGURATION = PublicCallRequestMutationConfig({ + { PublicCallRequestMutationOptions::ContractAddress, 3 }, + { PublicCallRequestMutationOptions::MsgSender, 1 }, + { PublicCallRequestMutationOptions::IsStaticCall, 3 }, + { PublicCallRequestMutationOptions::Calldata, 5 }, +}); + +PublicCallRequestWithCalldata generate_public_call_request(std::vector& contract_addresses, + std::mt19937_64& rng); + +void mutate_public_call_request(PublicCallRequestWithCalldata& request, + std::vector& contract_addresses, + std::mt19937_64& rng); +} // namespace bb::avm2::fuzzer diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp index cf41dd525b76..56a01bda9ec0 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/prover.fuzzer.cpp @@ -14,7 +14,6 @@ using namespace bb::avm2::fuzzer; extern "C" int LLVMFuzzerInitialize(int*, char***) { FuzzerWorldStateManager::initialize(); - std::filesystem::create_directories("proving_inputs"); return 0; } diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp index 33b8190a5c1f..1b5ef768ef46 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp @@ -255,7 +255,8 @@ TxExecutionResult TxExecution::simulate(const Tx& tx) merkle_db.commit_checkpoint(); contract_db.commit_checkpoint(); } catch (const TxExecutionException& e) { - important("Teardown failure while simulating tx ", tx.hash, ": ", e.what()); + // TODO(fcarreiro): move these back to important log once/if we have log levels properly set up. + vinfo("Teardown failure while simulating tx ", tx.hash, ": ", e.what()); tx_context.revert_code = tx_context.revert_code == RevertCode::APP_LOGIC_REVERTED ? RevertCode::BOTH_REVERTED : RevertCode::TEARDOWN_REVERTED; From 0ffaa16009506689f90ed171aeff49af31fa431e Mon Sep 17 00:00:00 2001 From: IlyasRidhuan Date: Sun, 4 Jan 2026 21:13:17 +0000 Subject: [PATCH 2/2] feat(avm): defensively assert cd hashes --- .../barretenberg/avm_fuzzer/harness/calldata.fuzzer.cpp | 4 +++- .../vm2/simulation/gadgets/calldata_hashing.cpp | 6 +++--- .../vm2/simulation/gadgets/calldata_hashing.hpp | 2 +- .../vm2/simulation/gadgets/calldata_hashing.test.cpp | 7 +++---- .../vm2/simulation/gadgets/context_provider.cpp | 3 ++- .../vm2/simulation/gadgets/context_provider.hpp | 1 + .../barretenberg/vm2/simulation/gadgets/tx_execution.cpp | 3 +++ .../vm2/simulation/interfaces/calldata_hashing.hpp | 2 +- .../vm2/simulation/interfaces/context_provider.hpp | 1 + .../barretenberg/vm2/simulation/testing/mock_cd_hasher.hpp | 2 +- .../vm2/simulation/testing/mock_context_provider.hpp | 1 + 11 files changed, 20 insertions(+), 12 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/calldata.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/calldata.fuzzer.cpp index ae912887852f..ab0b2ad3f3da 100644 --- a/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/calldata.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/avm_fuzzer/harness/calldata.fuzzer.cpp @@ -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" @@ -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. diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.cpp index d5d9d0dfe2e5..27df179d99f0 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.cpp @@ -6,7 +6,7 @@ namespace bb::avm2::simulation { -FF CalldataHasher::compute_calldata_hash(std::span calldata) +void CalldataHasher::assert_calldata_hash(const FF& cd_hash, std::span calldata) { // todo(ilyas): this probably simulates faster at the cost of re-work in tracegen std::vector calldata_with_sep = { DOM_SEP__PUBLIC_CALLDATA }; @@ -14,13 +14,13 @@ FF CalldataHasher::compute_calldata_hash(std::span calldata) // Note: Using `insert` breaks GCC. calldata_with_sep.push_back(value); } - FF output_hash = hasher.hash(calldata_with_sep); + FF computed_hash = hasher.hash(calldata_with_sep); + BB_ASSERT_EQ(computed_hash, cd_hash); events.emit({ .context_id = context_id, .calldata = { calldata.begin(), calldata.end() }, }); - return output_hash; } } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.hpp index c736c65f82ab..b2d6600d218d 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.hpp @@ -18,7 +18,7 @@ class CalldataHasher : public CalldataHashingInterface { , hasher(hasher) {} - FF compute_calldata_hash(std::span calldata) override; + void assert_calldata_hash(const FF& cd_hash, std::span calldata) override; private: uint32_t context_id; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.test.cpp index 085735096685..1a8eabbfc7d4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/calldata_hashing.test.cpp @@ -59,9 +59,8 @@ TEST_F(CalldataHashingTest, SimpleHash) EXPECT_CALL(poseidon2, hash(prepended_calldata_fields)).WillOnce(Return(hash)); - auto output_hash = calldata_hasher.compute_calldata_hash(calldata_fields); + calldata_hasher.assert_calldata_hash(hash, calldata_fields); - EXPECT_EQ(output_hash, hash); EXPECT_THAT( calldata_events.dump_events(), AllOf(SizeIs(1), @@ -77,7 +76,7 @@ TEST_F(CalldataHashingTest, Hash) auto hash = RawPoseidon2::hash(prepended_calldata_fields); EXPECT_CALL(poseidon2, hash(prepended_calldata_fields)).WillOnce(Return(hash)); - calldata_hasher.compute_calldata_hash(calldata); + calldata_hasher.assert_calldata_hash(hash, calldata); EXPECT_THAT( calldata_events.dump_events(), AllOf(SizeIs(1), @@ -93,7 +92,7 @@ TEST_F(CalldataHashingTest, Empty) auto hash = RawPoseidon2::hash(prepended_calldata_fields); EXPECT_CALL(poseidon2, hash(prepended_calldata_fields)).WillOnce(Return(hash)); - calldata_hasher.compute_calldata_hash(calldata); + calldata_hasher.assert_calldata_hash(hash, calldata); EXPECT_THAT( calldata_events.dump_events(), AllOf(SizeIs(1), diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.cpp index b85afae231b7..184e7a1391b1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.cpp @@ -45,6 +45,7 @@ std::unique_ptr ContextProvider::make_enqueued_context(AztecAd AztecAddress msg_sender, FF transaction_fee, std::span calldata, + const FF& calldata_hash, bool is_static, Gas gas_limit, Gas gas_used, @@ -56,7 +57,7 @@ std::unique_ptr ContextProvider::make_enqueued_context(AztecAd assert(context_id <= std::numeric_limits::max()); uint16_t space_id = static_cast(context_id); - cd_hash_provider.make_calldata_hasher(context_id)->compute_calldata_hash(calldata); + cd_hash_provider.make_calldata_hasher(context_id)->assert_calldata_hash(calldata_hash, calldata); return std::make_unique( context_id, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.hpp index b581d53c508d..d471322c1a38 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/context_provider.hpp @@ -48,6 +48,7 @@ class ContextProvider : public ContextProviderInterface { AztecAddress msg_sender, FF transaction_fee, std::span calldata, + const FF& calldata_hash, bool is_static, Gas gas_limit, Gas gas_used, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp index 1b5ef768ef46..12a5883dfd37 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/tx_execution.cpp @@ -107,6 +107,7 @@ TxExecutionResult TxExecution::simulate(const Tx& tx) call.request.msg_sender, /*transaction_fee=*/FF(0), call.calldata, + call.request.calldata_hash, call.request.is_static_call, gas_limit, start_gas, @@ -166,6 +167,7 @@ TxExecutionResult TxExecution::simulate(const Tx& tx) call.request.msg_sender, /*transaction_fee=*/FF(0), call.calldata, + call.request.calldata_hash, call.request.is_static_call, gas_limit, start_gas, @@ -229,6 +231,7 @@ TxExecutionResult TxExecution::simulate(const Tx& tx) teardown_enqueued_call.request.msg_sender, fee, teardown_enqueued_call.calldata, + teardown_enqueued_call.request.calldata_hash, teardown_enqueued_call.request.is_static_call, teardown_gas_limit, start_gas, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/calldata_hashing.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/calldata_hashing.hpp index ca67b85ef4a2..b5487e2cf39f 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/calldata_hashing.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/calldata_hashing.hpp @@ -11,7 +11,7 @@ namespace bb::avm2::simulation { class CalldataHashingInterface { public: virtual ~CalldataHashingInterface() = default; - virtual FF compute_calldata_hash(std::span calldata) = 0; + virtual void assert_calldata_hash(const FF& cd_hash, std::span calldata) = 0; }; class CalldataHashingProviderInterface { diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context_provider.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context_provider.hpp index 0d0729015c71..0464425f4567 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context_provider.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/interfaces/context_provider.hpp @@ -30,6 +30,7 @@ class ContextProviderInterface { AztecAddress msg_sender, FF transaction_fee, std::span calldata, + const FF& calldata_hash, bool is_static, Gas gas_limit, Gas gas_used, diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_cd_hasher.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_cd_hasher.hpp index 5e4dd1a917df..3e7fb739f2c1 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_cd_hasher.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_cd_hasher.hpp @@ -11,6 +11,6 @@ class MockCalldataHasher : public CalldataHashingInterface { MockCalldataHasher(); ~MockCalldataHasher() override; - MOCK_METHOD(FF, compute_calldata_hash, (const std::span calldata), (override)); + MOCK_METHOD(void, assert_calldata_hash, (const FF& cd_hash, std::span calldata), (override)); }; } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_context_provider.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_context_provider.hpp index e35f949d7afa..31b4204ec1d9 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_context_provider.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_context_provider.hpp @@ -37,6 +37,7 @@ class MockContextProvider : public ContextProviderInterface { AztecAddress msg_sender, FF transaction_fee, std::span calldata, + const FF& calldata_hash, bool is_static, Gas gas_limit, Gas gas_used,