15#include <gmock/gmock.h>
16#include <gtest/gtest.h>
22class HintingDBsTest :
public ::testing::Test {
24 HintingDBsTest(
const AvmProvingInputs& inputs)
30 template <
typename H
int>
33 for (
const Hint& input_hint : input_hints) {
34 EXPECT_FALSE(std::ranges::find(collected_hints.begin(), collected_hints.end(), input_hint) ==
35 collected_hints.end());
38 for (
const Hint& collected_hint : collected_hints) {
39 EXPECT_FALSE(std::ranges::find(input_hints.begin(), input_hints.end(), collected_hint) ==
52class HintingDBsMinimalTest :
public HintingDBsTest {
54 HintingDBsMinimalTest()
55 : HintingDBsTest(AvmProvingInputs::from(
read_file(
"../src/barretenberg/vm2/testing/minimal_tx.testdata.bin")))
60AvmProvingInputs fix_hint_keys(AvmProvingInputs
inputs)
62 auto reset_action_counters = [&]<
typename H>(
std::vector<H>& hints) {
63 for (
auto& hint : hints) {
68 for (
auto& hint : hints) {
82class HintingDBsTestInputTest :
public HintingDBsTest {
84 HintingDBsTestInputTest()
85 : HintingDBsTest(fix_hint_keys(
86 AvmProvingInputs::from(
read_file(
"../src/barretenberg/vm2/testing/avm_inputs.testdata.bin"))))
90TEST_F(HintingDBsTestInputTest, GetContractInstance)
92 for (
const auto& instance_hint :
inputs.hints.contract_instances) {
98 ExecutionHints collected_hints;
103TEST_F(HintingDBsTestInputTest, GetContractClass)
105 for (
const auto& class_hint :
inputs.hints.contract_classes) {
107 EXPECT_TRUE(klass.has_value());
111 ExecutionHints collected_hints;
116TEST_F(HintingDBsTestInputTest, GetBytecodeCommitment)
118 for (
const auto& hint :
inputs.hints.bytecode_commitments) {
120 EXPECT_TRUE(commitment.has_value());
124 ExecutionHints collected_hints;
129TEST_F(HintingDBsTestInputTest, GetDebugFunctionName)
131 for (
const auto& hint :
inputs.hints.debug_function_names) {
133 EXPECT_TRUE(name.has_value());
137 ExecutionHints collected_hints;
142TEST_F(HintingDBsMinimalTest, ContractDBCheckpoints)
154 ExecutionHints collected_hints;
157 collected_hints.contract_db_create_checkpoint_hints);
159 collected_hints.contract_db_commit_checkpoint_hints);
162TEST_F(HintingDBsTestInputTest, GetSiblingPath)
164 for (
const auto& hint :
inputs.hints.get_sibling_path_hints) {
169 ExecutionHints collected_hints;
174TEST_F(HintingDBsMinimalTest, MerkleDBCheckpoints)
186 ExecutionHints collected_hints;
192class MockedHintingDBsTest :
public ::testing::Test {
194 MockedHintingDBsTest() { ON_CALL(base_merkle_db, get_tree_roots).WillByDefault(testing::Return(mock_tree_info)); }
208TEST_F(MockedHintingDBsTest, GetLowLeaf)
211 std::vector<FF> update_preimage_slots = { 1, 2, 4 };
213 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(update_preimage_slots.size()));
216 for (
size_t i = 0; i < update_preimage_slots.size(); ++i) {
217 if (leaf_slot == update_preimage_slots[i]) {
221 throw std::runtime_error(
"Leaf not found");
225 for (
const auto& update_preimage_slot : update_preimage_slots) {
228 ExecutionHints collected_hints;
232 EXPECT_EQ(collected_hints.get_previous_value_index_hints.size(), update_preimage_slots.size());
234 collected_hints.get_previous_value_index_hints,
235 testing::ElementsAreArray({ GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
236 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
237 .value = update_preimage_slots[0],
239 .already_present = true },
240 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
241 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
242 .value = update_preimage_slots[1],
244 .already_present = true },
245 GetPreviousValueIndexHint{ .hint_key = mock_tree_info.public_data_tree,
246 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
247 .value = update_preimage_slots[2],
249 .already_present = true } }));
252TEST_F(MockedHintingDBsTest, GetLeafValue)
255 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
257 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(note_hash_leaf_values.size()));
260 if (
index < note_hash_leaf_values.size()) {
261 return note_hash_leaf_values[index];
263 throw std::runtime_error(
"Leaf not found");
267 for (
index_t i = 0; i < note_hash_leaf_values.size(); i++) {
270 ExecutionHints collected_hints;
274 EXPECT_EQ(collected_hints.get_leaf_value_hints.size(), note_hash_leaf_values.size());
275 EXPECT_THAT(collected_hints.get_leaf_value_hints,
276 testing::ElementsAreArray({
277 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
278 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
280 .value = note_hash_leaf_values[0] },
281 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
282 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
284 .value = note_hash_leaf_values[1] },
285 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
286 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
288 .value = note_hash_leaf_values[2] },
289 GetLeafValueHint{ .hint_key = mock_tree_info.note_hash_tree,
290 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
292 .value = note_hash_leaf_values[3] },
296TEST_F(MockedHintingDBsTest, GetLeafPreimagePublicDataTree)
301 { public_leaf_values[1], 2, 4 },
302 { public_leaf_values[2], 0, 3 } };
304 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(public_leaf_preimages.size()));
306 if (
index < public_leaf_preimages.size()) {
307 return public_leaf_preimages[index];
309 throw std::runtime_error(
"Leaf preimage not found");
313 for (
index_t i = 0; i < public_leaf_preimages.size(); i++) {
316 ExecutionHints collected_hints;
320 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_public_data_tree.size(), public_leaf_preimages.size());
322 collected_hints.get_leaf_preimage_hints_public_data_tree,
323 testing::ElementsAreArray(
324 { GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
325 .hint_key = mock_tree_info.public_data_tree, .index = 0, .leaf_preimage = public_leaf_preimages[0] },
326 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{
327 .hint_key = mock_tree_info.public_data_tree, .index = 1, .leaf_preimage = public_leaf_preimages[1] },
328 GetLeafPreimageHint<PublicDataTreeLeafPreimage>{ .hint_key = mock_tree_info.public_data_tree,
330 .leaf_preimage = public_leaf_preimages[2] } }));
333TEST_F(MockedHintingDBsTest, GetLeafPreimageNullifierTree)
338 { nullifier_leaf_values[1], 2, 4 },
339 { nullifier_leaf_values[2], 0, 3 } };
341 EXPECT_CALL(
base_merkle_db, get_tree_roots).Times(
static_cast<int>(nullifier_leaf_preimages.size()));
343 if (
index < nullifier_leaf_preimages.size()) {
344 return nullifier_leaf_preimages[index];
346 throw std::runtime_error(
"Leaf preimage not found");
350 for (
index_t i = 0; i < nullifier_leaf_preimages.size(); i++) {
353 ExecutionHints collected_hints;
357 EXPECT_EQ(collected_hints.get_leaf_preimage_hints_nullifier_tree.size(), nullifier_leaf_preimages.size());
359 collected_hints.get_leaf_preimage_hints_nullifier_tree,
360 testing::ElementsAreArray(
361 { GetLeafPreimageHint<NullifierTreeLeafPreimage>{
362 .hint_key = mock_tree_info.nullifier_tree, .index = 0, .leaf_preimage = nullifier_leaf_preimages[0] },
363 GetLeafPreimageHint<NullifierTreeLeafPreimage>{
364 .hint_key = mock_tree_info.nullifier_tree, .index = 1, .leaf_preimage = nullifier_leaf_preimages[1] },
365 GetLeafPreimageHint<NullifierTreeLeafPreimage>{ .hint_key = mock_tree_info.nullifier_tree,
367 .leaf_preimage = nullifier_leaf_preimages[2] } }));
370TEST_F(MockedHintingDBsTest, InsertIndexedLeavesPublicDataTree)
372 AppendOnlyTreeSnapshot state_before =
mock_tree_info.public_data_tree;
377 AppendOnlyTreeSnapshot mock_state_after = {
mock_tree_info.public_data_tree.root++,
384 EXPECT_CALL(
base_merkle_db, insert_indexed_leaves_public_data_tree(testing::_))
386 SequentialInsertionResult<PublicDataLeafValue> result = {
387 .low_leaf_witness_data = { mock_low_witness_data },
388 .insertion_witness_data = { { {
value, 1, 6 }, 1, mock_path } }
396 ExecutionHints collected_hints;
400 EXPECT_EQ(collected_hints.sequential_insert_hints_public_data_tree.size(), 1);
401 EXPECT_THAT(collected_hints.sequential_insert_hints_public_data_tree,
402 testing::ElementsAre(SequentialInsertHint<PublicDataLeafValue>{
403 .hint_key = state_before,
404 .tree_id = world_state::MerkleTreeId::PUBLIC_DATA_TREE,
405 .leaf = public_leaf_value,
406 .low_leaves_witness_data = mock_low_witness_data,
407 .insertion_witness_data = { { public_leaf_value, 1, 6 }, 1, mock_path },
411TEST_F(MockedHintingDBsTest, InsertIndexedLeavesNullifierTree)
413 AppendOnlyTreeSnapshot state_before =
mock_tree_info.nullifier_tree;
418 AppendOnlyTreeSnapshot mock_state_after = {
mock_tree_info.nullifier_tree.root++,
425 EXPECT_CALL(
base_merkle_db, insert_indexed_leaves_nullifier_tree(testing::_))
427 SequentialInsertionResult<NullifierLeafValue> result = { .low_leaf_witness_data = { mock_low_witness_data },
428 .insertion_witness_data = {
429 { {
value, 1, 6 }, 1, mock_path } } };
436 ExecutionHints collected_hints;
440 EXPECT_EQ(collected_hints.sequential_insert_hints_nullifier_tree.size(), 1);
441 EXPECT_THAT(collected_hints.sequential_insert_hints_nullifier_tree,
442 testing::ElementsAre(SequentialInsertHint<NullifierLeafValue>{
443 .hint_key = state_before,
444 .tree_id = world_state::MerkleTreeId::NULLIFIER_TREE,
446 .low_leaves_witness_data = mock_low_witness_data,
447 .insertion_witness_data = { { nullifier, 1, 6 }, 1, mock_path },
451TEST_F(MockedHintingDBsTest, AppendLeaves)
454 AppendOnlyTreeSnapshot initial_state = { 0, 0 };
457 std::vector<FF> note_hash_leaf_values = { 11, 22, 44, 88 };
458 AppendOnlyTreeSnapshot expected_end_state = { 8, 4 };
460 expected_tree_info_after.note_hash_tree = expected_end_state;
464 .WillOnce(testing::Return(expected_tree_info_after));
465 EXPECT_CALL(
base_merkle_db, append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, testing::_)).Times(1);
468 hinting_merkle_db.append_leaves(world_state::MerkleTreeId::NOTE_HASH_TREE, note_hash_leaf_values);
469 ExecutionHints collected_hints;
473 EXPECT_EQ(collected_hints.append_leaves_hints.size(), 1);
474 EXPECT_THAT(collected_hints.append_leaves_hints,
475 testing::ElementsAre(AppendLeavesHint{ .hint_key = initial_state,
476 .state_after = expected_end_state,
477 .tree_id = world_state::MerkleTreeId::NOTE_HASH_TREE,
478 .leaves = note_hash_leaf_values }));
481TEST_F(MockedHintingDBsTest, MerkleDBCheckpoints)
483 uint32_t mock_checkpoint_id = 0;
485 .WillOnce(testing::Return(mock_checkpoint_id))
486 .WillOnce(testing::Return(++mock_checkpoint_id))
487 .WillOnce(testing::Return(mock_checkpoint_id))
488 .WillOnce(testing::Return(++mock_checkpoint_id));
496 .WillOnce(testing::Return(mock_checkpoint_id))
497 .WillOnce(testing::Return(--mock_checkpoint_id));
505 .WillOnce(testing::Return(mock_checkpoint_id))
506 .WillOnce(testing::Return(--mock_checkpoint_id));
509 ExecutionHints collected_hints;
513 EXPECT_EQ(collected_hints.create_checkpoint_hints.size(), 2);
514 EXPECT_EQ(collected_hints.commit_checkpoint_hints.size(), 1);
515 EXPECT_EQ(collected_hints.revert_checkpoint_hints.size(), 1);
516 mock_checkpoint_id = 0;
517 uint32_t mock_action_counter = 0;
518 EXPECT_THAT(collected_hints.create_checkpoint_hints,
519 testing::ElementsAreArray({ CreateCheckpointHint{
520 .action_counter = mock_action_counter++,
521 .old_checkpoint_id = mock_checkpoint_id,
522 .new_checkpoint_id = ++mock_checkpoint_id,
524 CreateCheckpointHint{
525 .action_counter = mock_action_counter++,
526 .old_checkpoint_id = mock_checkpoint_id,
527 .new_checkpoint_id = ++mock_checkpoint_id,
529 EXPECT_THAT(collected_hints.commit_checkpoint_hints,
530 testing::ElementsAre(CommitCheckpointHint{
531 .action_counter = mock_action_counter++,
532 .old_checkpoint_id = mock_checkpoint_id,
533 .new_checkpoint_id = --mock_checkpoint_id,
535 EXPECT_THAT(collected_hints.revert_checkpoint_hints,
536 testing::ElementsAre(RevertCheckpointHint{
537 .action_counter = mock_action_counter++,
538 .old_checkpoint_id = mock_checkpoint_id,
539 .new_checkpoint_id = --mock_checkpoint_id,
540 .state_before = mock_tree_info,
541 .state_after = mock_tree_info,
std::shared_ptr< Napi::ThreadSafeFunction > instance
std::shared_ptr< Napi::ThreadSafeFunction > revert_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > commit_checkpoint
std::shared_ptr< Napi::ThreadSafeFunction > create_checkpoint
#define NULLIFIER_TREE_HEIGHT
#define PUBLIC_DATA_TREE_HEIGHT
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)
HintingContractsDB hinting_contract_db
TreeSnapshots mock_tree_info
HintedRawMerkleDB base_merkle_db
HintingRawDB hinting_merkle_db
HintedRawContractDB base_contract_db
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
::bb::world_state::MerkleTreeId MerkleTreeId
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