3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
18using ::testing::ElementsAre;
19using ::testing::Return;
20using ::testing::StrictMock;
26TEST(AvmSimulationNullifierTree, ReadExists)
29 StrictMock<MockMerkleCheck> merkle_check;
30 StrictMock<MockFieldGreaterThan>
field_gt;
37 uint64_t low_leaf_index = 30;
38 std::vector<FF> sibling_path = { 1, 2, 3, 4, 5 };
39 AppendOnlyTreeSnapshot snapshot = AppendOnlyTreeSnapshot{ .root = 123456, .nextAvailableLeafIndex = 128 };
44 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
45 .WillRepeatedly(Return());
47 nullifier_tree_check.assert_read(
50 NullifierTreeReadWriteEvent expect_event = {
52 .prev_snapshot = snapshot,
53 .next_snapshot = snapshot,
55 .low_leaf_hash = low_leaf_hash,
56 .low_leaf_index = low_leaf_index,
58 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(expect_event));
62 nullifier_tree_check.assert_read(
64 "Nullifier non-membership check failed");
67TEST(AvmSimulationNullifierTree, ReadNotExistsLowPointsToInfinity)
70 StrictMock<MockMerkleCheck> merkle_check;
71 StrictMock<MockFieldGreaterThan>
field_gt;
78 uint64_t low_leaf_index = 30;
79 std::vector<FF> sibling_path = { 1, 2, 3, 4, 5 };
80 AppendOnlyTreeSnapshot snapshot = AppendOnlyTreeSnapshot{ .root = 123456, .nextAvailableLeafIndex = 128 };
84 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
85 .WillRepeatedly(Return());
88 nullifier_tree_check.assert_read(
90 NullifierTreeReadWriteEvent expect_event = {
92 .prev_snapshot = snapshot,
93 .next_snapshot = snapshot,
95 .low_leaf_hash = low_leaf_hash,
96 .low_leaf_index = low_leaf_index,
98 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(expect_event));
102 nullifier_tree_check.assert_read(
104 "Nullifier membership check failed");
109 nullifier_tree_check.assert_read(
111 "Low leaf value is GTE leaf value");
114TEST(AvmSimulationNullifierTree, ReadNotExistsLowPointsToAnotherLeaf)
117 StrictMock<MockMerkleCheck> merkle_check;
118 StrictMock<MockFieldGreaterThan>
field_gt;
125 uint64_t low_leaf_index = 30;
126 std::vector<FF> sibling_path = { 1, 2, 3, 4, 5 };
127 AppendOnlyTreeSnapshot snapshot = AppendOnlyTreeSnapshot{ .root = 123456, .nextAvailableLeafIndex = 128 };
131 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
132 .WillRepeatedly(Return());
136 nullifier_tree_check.assert_read(
138 NullifierTreeReadWriteEvent expect_event = {
140 .prev_snapshot = snapshot,
141 .next_snapshot = snapshot,
143 .low_leaf_hash = low_leaf_hash,
144 .low_leaf_index = low_leaf_index,
146 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(expect_event));
150 nullifier_tree_check.assert_read(
152 "Nullifier membership check failed");
157 nullifier_tree_check.assert_read(
159 "Leaf value is GTE low leaf next value");
162TEST(AvmSimulationNullifierTree, WriteExists)
165 StrictMock<MockMerkleCheck> merkle_check;
166 StrictMock<MockFieldGreaterThan>
field_gt;
173 uint64_t low_leaf_index = 30;
174 std::vector<FF> sibling_path = { 1, 2, 3, 4, 5 };
175 AppendOnlyTreeSnapshot snapshot = AppendOnlyTreeSnapshot{ .root = 123456, .nextAvailableLeafIndex = 128 };
180 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
181 .WillRepeatedly(Return());
183 AppendOnlyTreeSnapshot result_snapshot = nullifier_tree_check.write(
nullifier,
192 EXPECT_EQ(result_snapshot, snapshot);
194 NullifierTreeReadWriteEvent expect_event = {
196 .prev_snapshot = snapshot,
197 .next_snapshot = snapshot,
199 .low_leaf_hash = low_leaf_hash,
200 .low_leaf_index = low_leaf_index,
202 .nullifier_counter = 10,
204 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(expect_event));
207TEST(AvmSimulationNullifierTree, Siloing)
210 StrictMock<MockMerkleCheck> merkle_check;
211 StrictMock<MockFieldGreaterThan>
field_gt;
223 uint64_t low_leaf_index = 30;
224 std::vector<FF> sibling_path = { 1, 2, 3, 4, 5 };
225 AppendOnlyTreeSnapshot snapshot = AppendOnlyTreeSnapshot{ .root = 123456, .nextAvailableLeafIndex = 128 };
227 EXPECT_CALL(
poseidon2,
hash(siloed_nullifier_hash_inputs)).WillRepeatedly(Return(
FF(siloed_nullifier)));
229 EXPECT_CALL(merkle_check, assert_membership(low_leaf_hash, low_leaf_index, _, snapshot.root))
230 .WillRepeatedly(Return());
234 NullifierTreeReadWriteEvent read_event = {
236 .prev_snapshot = snapshot,
237 .next_snapshot = snapshot,
239 .low_leaf_hash = low_leaf_hash,
240 .low_leaf_index = low_leaf_index,
241 .siloing_data = NullifierSiloingData{ .siloed_nullifier = siloed_nullifier, .address =
contract_address },
252 NullifierTreeReadWriteEvent write_event = {
254 .prev_snapshot = snapshot,
255 .next_snapshot = snapshot,
257 .low_leaf_hash = low_leaf_hash,
258 .low_leaf_index = low_leaf_index,
260 .siloing_data = NullifierSiloingData{ .siloed_nullifier = siloed_nullifier, .address =
contract_address },
261 .nullifier_counter = 10,
263 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(read_event, write_event));
266TEST(AvmSimulationNullifierTree, WriteAppend)
269 StrictMock<MockMerkleCheck> merkle_check;
270 StrictMock<MockFieldGreaterThan>
field_gt;
276 FF low_nullifier = 40;
283 uint64_t low_leaf_index = 0;
284 nullifier_tree.update_element(low_leaf_index, low_leaf_hash);
286 AppendOnlyTreeSnapshot prev_snapshot =
287 AppendOnlyTreeSnapshot{ .root = nullifier_tree.root(), .nextAvailableLeafIndex = 128 };
288 std::vector<FF> low_leaf_sibling_path = nullifier_tree.get_sibling_path(low_leaf_index);
291 updated_low_leaf.
nextIndex = prev_snapshot.nextAvailableLeafIndex;
294 nullifier_tree.update_element(low_leaf_index, updated_low_leaf_hash);
296 FF intermediate_root = nullifier_tree.root();
297 std::vector<FF> insertion_sibling_path = nullifier_tree.get_sibling_path(prev_snapshot.nextAvailableLeafIndex);
302 nullifier_tree.update_element(prev_snapshot.nextAvailableLeafIndex, new_leaf_hash);
304 AppendOnlyTreeSnapshot next_snapshot =
305 AppendOnlyTreeSnapshot{ .root = nullifier_tree.root(),
306 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex + 1 };
308 EXPECT_CALL(
poseidon2,
hash(_)).WillRepeatedly([](
const std::vector<FF>& input) {
311 EXPECT_CALL(merkle_check,
write(low_leaf_hash, updated_low_leaf_hash, low_leaf_index, _, prev_snapshot.root))
312 .WillRepeatedly(Return(intermediate_root));
315 EXPECT_CALL(merkle_check,
write(
FF(0), new_leaf_hash, prev_snapshot.nextAvailableLeafIndex, _, intermediate_root))
316 .WillRepeatedly(Return(next_snapshot.root));
318 AppendOnlyTreeSnapshot result_snapshot = nullifier_tree_check.write(
nullifier,
323 low_leaf_sibling_path,
325 insertion_sibling_path);
327 EXPECT_EQ(next_snapshot, result_snapshot);
329 NullifierTreeReadWriteEvent expect_event = { .nullifier =
nullifier,
330 .prev_snapshot = prev_snapshot,
331 .next_snapshot = next_snapshot,
333 .low_leaf_hash = low_leaf_hash,
334 .low_leaf_index = low_leaf_index,
336 .append_data = NullifierAppendData{
337 .updated_low_leaf_hash = updated_low_leaf_hash,
338 .new_leaf_hash = new_leaf_hash,
339 .intermediate_root = intermediate_root,
342 EXPECT_THAT(
event_emitter.dump_events(), ElementsAre(expect_event));
351 low_leaf_sibling_path,
353 insertion_sibling_path),
354 "Nullifier non-membership check failed");
364 low_leaf_sibling_path,
366 insertion_sibling_path),
367 "Low leaf value is GTE leaf value");
377 low_leaf_sibling_path,
379 insertion_sibling_path),
380 "Leaf value is GTE low leaf next value");
#define GENERATOR_INDEX__OUTER_NULLIFIER
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
EventEmitter< DataCopyEvent > event_emitter
NullifierTreeLeafPreimage low_leaf
AztecAddress contract_address
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
void hash(State &state) noexcept
crypto::Poseidon2< crypto::Poseidon2Bn254ScalarFieldParams > poseidon2
TEST(EmitUnencryptedLogTest, Basic)
::bb::crypto::merkle_tree::NullifierLeafValue NullifierLeafValue
IndexedLeaf< NullifierLeafValue > NullifierTreeLeafPreimage
void write(B &buf, field2< base_field, Params > const &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::vector< fr > get_hash_inputs() const
NiceMock< MockFieldGreaterThan > field_gt