3#include "barretenberg/aztec/aztec_constants.hpp"
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
23class HintingDBsTest :
public ::testing::Test {
25 HintingDBsTest(
const AvmProvingInputs& inputs)
31 template <
typename H
int>
34 for (
const Hint& input_hint : input_hints) {
35 EXPECT_FALSE(std::ranges::find(collected_hints.begin(), collected_hints.end(), input_hint) ==
36 collected_hints.end());
39 for (
const Hint& collected_hint : collected_hints) {
40 EXPECT_FALSE(std::ranges::find(input_hints.begin(), input_hints.end(), collected_hint) ==
53class HintingDBsMinimalTest :
public HintingDBsTest {
55 HintingDBsMinimalTest()
61AvmProvingInputs fix_hint_keys(AvmProvingInputs
inputs)
63 auto reset_action_counters = [&]<
typename H>(
std::vector<H>& hints) {
64 for (
auto& hint : hints) {
69 for (
auto& hint : hints) {
83class HintingDBsTestInputTest :
public HintingDBsTest {
85 HintingDBsTestInputTest()
86 : HintingDBsTest(fix_hint_keys(
87 AvmProvingInputs::from(
read_file(
"../src/barretenberg/vm2/testing/avm_inputs.testdata.bin"))))
91TEST_F(HintingDBsTestInputTest, GetContractInstance)
93 for (
const auto& instance_hint :
inputs.hints.contract_instances) {
95 EXPECT_TRUE(instance.has_value());
99 ExecutionHints collected_hints;
104TEST_F(HintingDBsTestInputTest, GetContractClass)
106 for (
const auto& class_hint :
inputs.hints.contract_classes) {
108 EXPECT_TRUE(klass.has_value());
112 ExecutionHints collected_hints;
117TEST_F(HintingDBsTestInputTest, GetBytecodeCommitment)
119 for (
const auto& hint :
inputs.hints.bytecode_commitments) {
121 EXPECT_TRUE(commitment.has_value());
125 ExecutionHints collected_hints;
130TEST_F(HintingDBsTestInputTest, GetDebugFunctionName)
132 for (
const auto& hint :
inputs.hints.debug_function_names) {
134 EXPECT_TRUE(
name.has_value());
138 ExecutionHints collected_hints;
143TEST_F(HintingDBsMinimalTest, ContractDBCheckpoints)
155 ExecutionHints collected_hints;
158 collected_hints.contract_db_create_checkpoint_hints);
160 collected_hints.contract_db_commit_checkpoint_hints);
163TEST_F(HintingDBsTestInputTest, GetSiblingPath)
165 for (
const auto& hint :
inputs.hints.get_sibling_path_hints) {
170 ExecutionHints collected_hints;
175TEST_F(HintingDBsMinimalTest, MerkleDBCheckpoints)
187 ExecutionHints collected_hints;
193class MockedHintingDBsTest :
public ::testing::Test {
195 MockedHintingDBsTest() { ON_CALL(base_merkle_db, get_tree_roots).WillByDefault(::testing::Return(mock_tree_info)); }
209TEST_F(MockedHintingDBsTest, GetLowLeaf)
212 std::vector<FF> update_preimage_slots = { 1, 2, 4 };
214 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(update_preimage_slots.size()));
217 for (
size_t i = 0; i < update_preimage_slots.size(); ++i) {
218 if (leaf_slot == update_preimage_slots[i]) {
222 throw std::runtime_error(
"Leaf not found");
226 for (
const auto& update_preimage_slot : update_preimage_slots) {
229 ExecutionHints collected_hints;
233 EXPECT_EQ(collected_hints.get_previous_value_index_hints.size(), update_preimage_slots.size());
235 collected_hints.get_previous_value_index_hints,
236 ::testing::ElementsAreArray({ GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
237 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
238 .value = update_preimage_slots[0],
240 .already_present = true },
241 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
242 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
243 .value = update_preimage_slots[1],
245 .already_present = true },
246 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
247 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
248 .value = update_preimage_slots[2],
250 .already_present = true } }));
253TEST_F(MockedHintingDBsTest, GetLeafValue)
256 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
258 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(note_hash_leaf_values.size()));
261 if (
index < note_hash_leaf_values.size()) {
262 return note_hash_leaf_values[index];
264 throw std::runtime_error(
"Leaf not found");
268 for (
index_t i = 0; i < note_hash_leaf_values.size(); i++) {
271 ExecutionHints collected_hints;
275 EXPECT_EQ(collected_hints.get_leaf_value_hints.size(), note_hash_leaf_values.size());
276 EXPECT_THAT(collected_hints.get_leaf_value_hints,
277 ::testing::ElementsAreArray({
278 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
279 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
281 .value = note_hash_leaf_values[0] },
282 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
283 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
285 .value = note_hash_leaf_values[1] },
286 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
287 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
289 .value = note_hash_leaf_values[2] },
290 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
291 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
293 .value = note_hash_leaf_values[3] },
297TEST_F(MockedHintingDBsTest, GetLeafPreimagePublicDataTree)
302 { public_leaf_values[1], 2, 4 },
303 { public_leaf_values[2], 0, 3 } };
305 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(public_leaf_preimages.size()));
307 if (
index < public_leaf_preimages.size()) {
308 return public_leaf_preimages[index];
310 throw std::runtime_error(
"Leaf preimage not found");
314 for (
index_t i = 0; i < public_leaf_preimages.size(); i++) {
317 ExecutionHints collected_hints;
321 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_public_data_tree.size(), public_leaf_preimages.size());
323 collected_hints.get_leaf_preimage_hints_public_data_tree,
324 ::testing::ElementsAreArray(
325 { GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
326 .hint_key = mock_tree_info.public_data_tree, .index = 0, .leaf_preimage = public_leaf_preimages[0] },
327 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
328 .hint_key = mock_tree_info.public_data_tree, .index = 1, .leaf_preimage = public_leaf_preimages[1] },
329 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{ .hint_key = mock_tree_info.public_data_tree,
331 .leaf_preimage = public_leaf_preimages[2] } }));
334TEST_F(MockedHintingDBsTest, GetLeafPreimageNullifierTree)
339 { nullifier_leaf_values[1], 2, 4 },
340 { nullifier_leaf_values[2], 0, 3 } };
342 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(nullifier_leaf_preimages.size()));
344 if (
index < nullifier_leaf_preimages.size()) {
345 return nullifier_leaf_preimages[index];
347 throw std::runtime_error(
"Leaf preimage not found");
351 for (
index_t i = 0; i < nullifier_leaf_preimages.size(); i++) {
354 ExecutionHints collected_hints;
358 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_nullifier_tree.size(), nullifier_leaf_preimages.size());
360 collected_hints.get_leaf_preimage_hints_nullifier_tree,
361 ::testing::ElementsAreArray(
362 { GetLeafPreimageHint<NullifierTreeLeafPreimage>{
363 .hint_key = mock_tree_info.nullifier_tree, .index = 0, .leaf_preimage = nullifier_leaf_preimages[0] },
364 GetLeafPreimageHint<NullifierTreeLeafPreimage>{
365 .hint_key = mock_tree_info.nullifier_tree, .index = 1, .leaf_preimage = nullifier_leaf_preimages[1] },
366 GetLeafPreimageHint<NullifierTreeLeafPreimage>{ .hint_key = mock_tree_info.nullifier_tree,
368 .leaf_preimage = nullifier_leaf_preimages[2] } }));
371TEST_F(MockedHintingDBsTest, InsertIndexedLeavesPublicDataTree)
373 AppendOnlyTreeSnapshot state_before =
mock_tree_info.public_data_tree;
378 AppendOnlyTreeSnapshot mock_state_after = {
mock_tree_info.public_data_tree.root++,
385 EXPECT_CALL(
base_merkle_db, insert_indexed_leaves_public_data_tree(::testing::_))
387 SequentialInsertionResult<PublicDataLeafValue>
result = {
388 .low_leaf_witness_data = { mock_low_witness_data },
389 .insertion_witness_data = { { {
value, 1, 6 }, 1, mock_path } }
397 ExecutionHints collected_hints;
401 EXPECT_EQ(collected_hints.sequential_insert_hints_public_data_tree.size(), 1);
402 EXPECT_THAT(collected_hints.sequential_insert_hints_public_data_tree,
403 ::testing::ElementsAre(SequentialInsertHint<PublicDataLeafValue>{
404 .hint_key = state_before,
405 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
406 .leaf = public_leaf_value,
407 .low_leaves_witness_data = mock_low_witness_data,
408 .insertion_witness_data = { { public_leaf_value, 1, 6 }, 1, mock_path },
412TEST_F(MockedHintingDBsTest, InsertIndexedLeavesNullifierTree)
414 AppendOnlyTreeSnapshot state_before =
mock_tree_info.nullifier_tree;
419 AppendOnlyTreeSnapshot mock_state_after = {
mock_tree_info.nullifier_tree.root++,
426 EXPECT_CALL(
base_merkle_db, insert_indexed_leaves_nullifier_tree(::testing::_))
428 SequentialInsertionResult<NullifierLeafValue>
result = { .low_leaf_witness_data = { mock_low_witness_data },
429 .insertion_witness_data = {
430 { {
value, 1, 6 }, 1, mock_path } } };
437 ExecutionHints collected_hints;
441 EXPECT_EQ(collected_hints.sequential_insert_hints_nullifier_tree.size(), 1);
442 EXPECT_THAT(collected_hints.sequential_insert_hints_nullifier_tree,
443 ::testing::ElementsAre(SequentialInsertHint<NullifierLeafValue>{
444 .hint_key = state_before,
445 .tree_id = world_state::MerkleTreeId::NULLIFIER_TREE,
447 .low_leaves_witness_data = mock_low_witness_data,
448 .insertion_witness_data = { { nullifier, 1, 6 }, 1, mock_path },
452TEST_F(MockedHintingDBsTest, AppendLeaves)
455 AppendOnlyTreeSnapshot initial_state = { 0, 0 };
458 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
459 AppendOnlyTreeSnapshot expected_end_state = { 8, 4 };
461 expected_tree_info_after.note_hash_tree = expected_end_state;
465 .WillOnce(::testing::Return(expected_tree_info_after));
466 EXPECT_CALL(
base_merkle_db, append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, ::testing::_)).Times(1);
469 hinting_merkle_db.append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, note_hash_leaf_values);
470 ExecutionHints collected_hints;
474 EXPECT_EQ(collected_hints.append_leaves_hints.size(), 1);
475 EXPECT_THAT(collected_hints.append_leaves_hints,
476 ::testing::ElementsAre(AppendLeavesHint{ .hint_key = initial_state,
477 .state_after = expected_end_state,
478 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
479 .leaves = note_hash_leaf_values }));
482TEST_F(MockedHintingDBsTest, MerkleDBCheckpoints)
484 uint32_t mock_checkpoint_id = 0;
486 .WillOnce(::testing::Invoke([&]() {
return mock_checkpoint_id; }))
487 .WillOnce(::testing::Invoke([&]() {
return ++mock_checkpoint_id; }))
488 .WillOnce(::testing::Invoke([&]() {
return mock_checkpoint_id; }))
489 .WillOnce(::testing::Invoke([&]() {
return ++mock_checkpoint_id; }));
497 .WillOnce(::testing::Invoke([&]() {
return mock_checkpoint_id; }))
498 .WillOnce(::testing::Invoke([&]() {
return --mock_checkpoint_id; }));
506 .WillOnce(::testing::Invoke([&]() {
return mock_checkpoint_id; }))
507 .WillOnce(::testing::Invoke([&]() {
return --mock_checkpoint_id; }));
510 ExecutionHints collected_hints;
514 EXPECT_EQ(collected_hints.create_checkpoint_hints.size(), 2);
515 EXPECT_EQ(collected_hints.commit_checkpoint_hints.size(), 1);
516 EXPECT_EQ(collected_hints.revert_checkpoint_hints.size(), 1);
517 mock_checkpoint_id = 0;
518 uint32_t mock_action_counter = 0;
519 EXPECT_THAT(collected_hints.create_checkpoint_hints,
520 ::testing::ElementsAreArray({ CreateCheckpointHint{
521 .action_counter = mock_action_counter++,
522 .old_checkpoint_id = mock_checkpoint_id,
523 .new_checkpoint_id = ++mock_checkpoint_id,
525 CreateCheckpointHint{
526 .action_counter = mock_action_counter++,
527 .old_checkpoint_id = mock_checkpoint_id,
528 .new_checkpoint_id = ++mock_checkpoint_id,
530 EXPECT_THAT(collected_hints.commit_checkpoint_hints,
531 ::testing::ElementsAre(CommitCheckpointHint{
532 .action_counter = mock_action_counter++,
533 .old_checkpoint_id = mock_checkpoint_id,
534 .new_checkpoint_id = --mock_checkpoint_id,
536 EXPECT_THAT(collected_hints.revert_checkpoint_hints,
537 ::testing::ElementsAre(RevertCheckpointHint{
538 .action_counter = mock_action_counter++,
539 .old_checkpoint_id = mock_checkpoint_id,
540 .new_checkpoint_id = --mock_checkpoint_id,
541 .state_before = mock_tree_info,
542 .state_after = mock_tree_info,
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
std::optional< std::string > get_debug_function_name(const AztecAddress &address, const FunctionSelector &selector) const override
std::optional< FF > get_bytecode_commitment(const ContractClassId &class_id) const override
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
std::optional< std::string > get_debug_function_name(const AztecAddress &address, const FunctionSelector &selector) const override
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
void commit_checkpoint() override
std::optional< FF > get_bytecode_commitment(const ContractClassId &class_id) const override
void create_checkpoint() override
void dump_hints(ExecutionHints &hints)
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
void create_checkpoint() override
void dump_hints(ExecutionHints &hints)
SiblingPath get_sibling_path(MerkleTreeId tree_id, index_t leaf_index) const override
GetLowIndexedLeafResponse get_low_indexed_leaf(MerkleTreeId tree_id, const FF &value) const override
void commit_checkpoint() override
FF get_leaf_value(MerkleTreeId tree_id, index_t leaf_index) const override
auto & get_tree_info_helper(world_state::MerkleTreeId tree_id, auto &tree_roots)
HintedRawMerkleDB base_merkle_db
HintingContractsDB hinting_contract_db
TreeSnapshots mock_tree_info
HintedRawContractDB base_contract_db
HintingRawDB hinting_merkle_db
AVM range check gadget for witness generation.
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
::bb::world_state::MerkleTreeId MerkleTreeId
AvmProvingInputs get_minimal_proving_inputs()
TEST_F(IPATest, ChallengesAreZero)
std::vector< uint8_t > read_file(const std::string &filename, size_t bytes=0)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
TreeSnapshots starting_tree_roots
std::vector< GetSiblingPathHint > get_sibling_path_hints
std::vector< DebugFunctionNameHint > debug_function_names
std::vector< ContractDBCreateCheckpointHint > contract_db_create_checkpoint_hints
std::vector< ContractDBCommitCheckpointHint > contract_db_commit_checkpoint_hints
std::vector< CommitCheckpointHint > commit_checkpoint_hints
std::vector< CreateCheckpointHint > create_checkpoint_hints
std::vector< ContractInstanceHint > contract_instances
std::vector< ContractClassHint > contract_classes
std::vector< BytecodeCommitmentHint > bytecode_commitments