1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
35using ::testing::NiceMock;
36using ::testing::TestWithParam;
38using testing::TestMemoryTree;
41using simulation::DeduplicatingEventEmitter;
42using simulation::EventEmitter;
43using simulation::FieldGreaterThan;
44using simulation::FieldGreaterThanEvent;
45using simulation::MerkleCheck;
46using simulation::MerkleCheckEvent;
47using simulation::MockExecutionIdManager;
48using simulation::MockGreaterThan;
49using simulation::MockRangeCheck;
50using simulation::NoopEventEmitter;
51using simulation::Poseidon2;
52using simulation::Poseidon2HashEvent;
53using simulation::Poseidon2PermutationEvent;
54using simulation::Poseidon2PermutationMemoryEvent;
57using simulation::WrittenPublicDataSlotLeafValue;
59using simulation::WrittenPublicDataSlotsTreeCheck;
60using simulation::WrittenPublicDataSlotsTreeCheckEvent;
63using tracegen::FieldGreaterThanTraceBuilder;
64using tracegen::MerkleCheckTraceBuilder;
65using tracegen::Poseidon2TraceBuilder;
66using tracegen::TestTraceContainer;
67using tracegen::WrittenPublicDataSlotsTreeCheckTraceBuilder;
74class WrittenPublicDataSlotsTreeCheckConstrainingTest :
public ::testing::Test {
76 WrittenPublicDataSlotsTreeCheckConstrainingTest() =
default;
87 Poseidon2(mock_execution_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
90TEST_F(WrittenPublicDataSlotsTreeCheckConstrainingTest, EmptyRow)
106 .contract_address = 27,
110 TestParams{ .slot = 42,
111 .contract_address = 27,
117 TestParams{ .slot = 42, .contract_address = 27, .exists =
false, .pre_existing_leaves = { {} } },
121 .contract_address = 27,
126class WrittenPublicDataSlotsReadPositiveTests :
public WrittenPublicDataSlotsTreeCheckConstrainingTest,
127 public ::testing::WithParamInterface<TestParams> {};
129TEST_P(WrittenPublicDataSlotsReadPositiveTests, Positive)
131 const auto& param = GetParam();
133 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
134 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
141 EventEmitter<WrittenPublicDataSlotsTreeCheckEvent> written_public_data_slots_tree_check_event_emitter;
143 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
146 MerkleCheckTraceBuilder merkle_check_builder;
148 WrittenPublicDataSlotsTreeCheckTraceBuilder written_public_data_slots_tree_check_builder;
151 initial_state.insert_indexed_leaves(param.pre_existing_leaves);
153 WrittenPublicDataSlotsTreeCheck written_public_data_slots_tree_check_simulator(
154 poseidon2, merkle_check,
field_gt, initial_state, written_public_data_slots_tree_check_event_emitter);
156 written_public_data_slots_tree_check_simulator.contains(param.contract_address, param.slot);
158 written_public_data_slots_tree_check_builder.process(
159 written_public_data_slots_tree_check_event_emitter.dump_events(), trace);
163 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
166 check_relation<written_public_data_slots_tree_check>(trace);
167 check_all_interactions<WrittenPublicDataSlotsTreeCheckTraceBuilder>(trace);
171 WrittenPublicDataSlotsReadPositiveTests,
172 ::testing::ValuesIn(positive_read_tests));
174TEST_F(WrittenPublicDataSlotsTreeCheckConstrainingTest, PositiveWriteAppend)
176 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
177 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
184 EventEmitter<WrittenPublicDataSlotsTreeCheckEvent> written_public_data_slots_tree_check_event_emitter;
186 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
189 MerkleCheckTraceBuilder merkle_check_builder;
191 WrittenPublicDataSlotsTreeCheckTraceBuilder written_public_data_slots_tree_check_builder;
198 WrittenPublicDataSlotsTreeCheck written_public_data_slots_tree_check_simulator(
199 poseidon2, merkle_check,
field_gt, initial_state, written_public_data_slots_tree_check_event_emitter);
203 written_public_data_slots_tree_check_builder.process(
204 written_public_data_slots_tree_check_event_emitter.dump_events(), trace);
209 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
212 check_relation<written_public_data_slots_tree_check>(trace);
213 check_all_interactions<WrittenPublicDataSlotsTreeCheckTraceBuilder>(trace);
216TEST_F(WrittenPublicDataSlotsTreeCheckConstrainingTest, PositiveWriteMembership)
223 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
224 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
231 EventEmitter<WrittenPublicDataSlotsTreeCheckEvent> written_public_data_slots_tree_check_event_emitter;
233 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
236 MerkleCheckTraceBuilder merkle_check_builder;
238 WrittenPublicDataSlotsTreeCheckTraceBuilder written_public_data_slots_tree_check_builder;
241 initial_state.insert_indexed_leaves({ { WrittenPublicDataSlotLeafValue(leaf_slot) } });
243 WrittenPublicDataSlotsTreeCheck written_public_data_slots_tree_check_simulator(
244 poseidon2, merkle_check,
field_gt, initial_state, written_public_data_slots_tree_check_event_emitter);
248 written_public_data_slots_tree_check_builder.process(
249 written_public_data_slots_tree_check_event_emitter.dump_events(), trace);
254 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
257 check_relation<written_public_data_slots_tree_check>(trace);
258 check_all_interactions<WrittenPublicDataSlotsTreeCheckTraceBuilder>(trace);
261TEST_F(WrittenPublicDataSlotsTreeCheckConstrainingTest, NegativeExistsFlagCheck)
265 TestTraceContainer
trace({
266 { { C::written_public_data_slots_tree_check_sel, 1 },
267 { C::written_public_data_slots_tree_check_leaf_slot, 27 },
268 { C::written_public_data_slots_tree_check_low_leaf_slot, 27 },
269 { C::written_public_data_slots_tree_check_slot_low_leaf_slot_diff_inv, 0 },
270 { C::written_public_data_slots_tree_check_leaf_not_exists, 0 } },
271 { { C::written_public_data_slots_tree_check_sel, 1 },
272 { C::written_public_data_slots_tree_check_leaf_slot, 28 },
273 { C::written_public_data_slots_tree_check_low_leaf_slot, 27 },
274 { C::written_public_data_slots_tree_check_slot_low_leaf_slot_diff_inv,
FF(1).invert() },
275 { C::written_public_data_slots_tree_check_leaf_not_exists, 1 } },
279 trace.
set(C::written_public_data_slots_tree_check_leaf_not_exists, 0, 1);
284 trace.
set(C::written_public_data_slots_tree_check_leaf_not_exists, 0, 0);
285 trace.
set(C::written_public_data_slots_tree_check_leaf_not_exists, 1, 0);
292TEST_F(WrittenPublicDataSlotsTreeCheckConstrainingTest, NegativeNextSlotIsZero)
296 TestTraceContainer
trace({
298 { C::written_public_data_slots_tree_check_leaf_not_exists, 1 },
299 { C::written_public_data_slots_tree_check_low_leaf_next_slot, 0 },
300 { C::written_public_data_slots_tree_check_next_slot_inv, 0 },
301 { C::written_public_data_slots_tree_check_next_slot_is_nonzero, 0 },
304 { C::written_public_data_slots_tree_check_leaf_not_exists, 1 },
305 { C::written_public_data_slots_tree_check_low_leaf_next_slot, 1 },
306 { C::written_public_data_slots_tree_check_next_slot_inv,
FF(1).invert() },
307 { C::written_public_data_slots_tree_check_next_slot_is_nonzero, 1 },
311 check_relation<written_public_data_slots_tree_check>(
314 trace.
set(C::written_public_data_slots_tree_check_next_slot_is_nonzero, 0, 1);
318 "NEXT_SLOT_IS_ZERO_CHECK");
320 trace.
set(C::written_public_data_slots_tree_check_next_slot_is_nonzero, 0, 0);
321 trace.
set(C::written_public_data_slots_tree_check_next_slot_is_nonzero, 1, 0);
325 "NEXT_SLOT_IS_ZERO_CHECK");
FieldGreaterThan field_gt
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
StrictMock< MockGreaterThan > mock_gt
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
Poseidon2TraceBuilder poseidon2_builder
StrictMock< MockExecutionIdManager > mock_execution_id_manager
void process(const simulation::EventEmitterInterface< simulation::FieldGreaterThanEvent >::Container &events, TraceContainer &trace)
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
static constexpr size_t SR_NEXT_SLOT_IS_ZERO_CHECK
static constexpr size_t SR_EXISTS_CHECK
FieldGreaterThanTraceBuilder field_gt_builder
NullifierTreeLeafPreimage low_leaf
std::vector< ClassIdLeafValue > pre_existing_leaves
AztecAddress contract_address
INSTANTIATE_TEST_SUITE_P(PaddingVariants, AvmRecursiveTestsParameterized, ::testing::Values(false, true), [](const auto &info) { return info.param ? "Padded" :"Unpadded";})
TEST_F(AvmRecursiveTests, GoblinRecursionFailsWithWrongPIs)
TEST_P(AvmRecursiveTestsParameterized, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
IndexedLeaf< WrittenPublicDataSlotLeafValue > WrittenPublicDataSlotsTreeLeafPreimage
FF unconstrained_root_from_path(const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
WrittenPublicDataSlotsTree build_public_data_slots_tree()
FF unconstrained_compute_leaf_slot(const AztecAddress &contract_address, const FF &slot)
IndexedMemoryTree< WrittenPublicDataSlotLeafValue, Poseidon2HashPolicy > WrittenPublicDataSlotsTree
TestTraceContainer empty_trace()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter
NiceMock< MockWrittenPublicDataSlotsTreeCheck > written_public_data_slots_tree_check