Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
emit_unencrypted_log.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
14
15namespace bb::avm2::simulation {
16namespace {
17
18using ::testing::_;
19using ::testing::ElementsAre;
20using ::testing::Return;
21using ::testing::ReturnRef;
22using ::testing::StrictMock;
23
24std::vector<MemoryValue> to_memory_values(const std::vector<FF>& fields)
25{
26 std::vector<MemoryValue> memory_values;
27 memory_values.reserve(fields.size());
28 for (const FF& field : fields) {
29 memory_values.push_back(MemoryValue::from<FF>(field));
30 }
31 return memory_values;
32}
33
34TEST(EmitUnencryptedLogTest, Basic)
35{
36 StrictMock<MockMemory> memory;
37 StrictMock<MockContext> context;
38 StrictMock<MockGreaterThan> greater_than;
39 StrictMock<MockExecutionIdManager> execution_id_manager;
40 StrictMock<MockSideEffectTracker> side_effect_tracker;
41 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
42
43 AztecAddress address = 0xdeadbeef;
44 MemoryAddress log_offset = 27;
45 const std::vector<FF> log_fields = { log_offset, log_offset + 1 };
46 uint32_t log_size = static_cast<uint32_t>(log_fields.size());
47 uint64_t end_log_address = 28;
48 TrackedSideEffects side_effect_states = { .public_logs = {} };
49 TrackedSideEffects side_effect_states_after = { .public_logs = PublicLogs{ { { log_fields, address } } } };
50
51 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
52
53 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(1));
54 EXPECT_CALL(greater_than,
55 gt(side_effect_states_after.get_num_unencrypted_log_fields(), FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH))
56 .WillOnce(Return(false));
57 EXPECT_CALL(greater_than, gt(end_log_address, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
58
59 EXPECT_CALL(context, get_side_effect_tracker()).WillRepeatedly(ReturnRef(side_effect_tracker));
60 EXPECT_CALL(side_effect_tracker, get_side_effects())
61 .WillOnce(ReturnRef(side_effect_states))
62 .WillOnce(ReturnRef(side_effect_states_after));
63 EXPECT_CALL(side_effect_tracker, add_public_log(address, std::vector<FF>{ log_offset, log_offset + 1 }));
64
65 EXPECT_CALL(memory, get(_)).WillRepeatedly([](MemoryAddress address) -> const MemoryValue& {
66 static thread_local MemoryValue value;
67 value = MemoryValue::from<FF>(FF(address));
68 return value;
69 });
70
71 EXPECT_CALL(memory, get_space_id()).WillOnce(Return(57));
72 EXPECT_CALL(context, get_is_static()).WillOnce(Return(false));
73
74 emit_unencrypted_log.emit_unencrypted_log(memory, context, address, log_offset, log_size);
75
76 EmitUnencryptedLogWriteEvent expect_event = {
77 .execution_clk = 1,
78 .contract_address = address,
79 .space_id = 57,
80 .log_address = log_offset,
81 .log_size = log_size,
82 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
83 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
84 .is_static = false,
85 .values = to_memory_values(log_fields),
86 .error_memory_out_of_bounds = false,
87 .error_too_many_log_fields = false,
88 .error_tag_mismatch = false,
89 };
90
91 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
92}
93
94TEST(EmitUnencryptedLogTest, NegativeMemoryOutOfBounds)
95{
96 StrictMock<MockMemory> memory;
97 StrictMock<MockContext> context;
98 StrictMock<MockGreaterThan> greater_than;
99 StrictMock<MockExecutionIdManager> execution_id_manager;
100 StrictMock<MockSideEffectTracker> side_effect_tracker;
101 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
102
103 AztecAddress address = 0xdeadbeef;
105 const std::vector<FF> log_fields = { log_offset, log_offset + 1 };
106 uint32_t log_size = static_cast<uint32_t>(log_fields.size());
107 uint64_t end_log_address = static_cast<uint64_t>(log_offset) + log_size - 1;
108 TrackedSideEffects side_effect_states = { .public_logs = {} };
109 // No change to side effect states due to failure.
110 const TrackedSideEffects& side_effect_states_after = side_effect_states;
111
112 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
113
114 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(1));
115 EXPECT_CALL(greater_than,
116 gt(side_effect_states.get_num_unencrypted_log_fields() + PUBLIC_LOG_HEADER_LENGTH + log_size,
118 .WillOnce(Return(false));
119 EXPECT_CALL(greater_than, gt(end_log_address, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(true));
120
121 EXPECT_CALL(context, get_side_effect_tracker()).WillRepeatedly(ReturnRef(side_effect_tracker));
122 EXPECT_CALL(side_effect_tracker, get_side_effects())
123 .WillOnce(ReturnRef(side_effect_states))
124 .WillOnce(ReturnRef(side_effect_states_after));
125
126 EXPECT_CALL(memory, get_space_id()).WillOnce(Return(57));
127 EXPECT_CALL(context, get_is_static()).WillOnce(Return(false));
128
129 EXPECT_THROW(emit_unencrypted_log.emit_unencrypted_log(memory, context, address, log_offset, log_size),
130 EmitUnencryptedLogException);
131
132 EmitUnencryptedLogWriteEvent expect_event = {
133 .execution_clk = 1,
134 .contract_address = address,
135 .space_id = 57,
136 .log_address = log_offset,
137 .log_size = log_size,
138 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
139 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
140 .is_static = false,
141 .values = {},
142 .error_memory_out_of_bounds = true,
143 .error_too_many_log_fields = false,
144 .error_tag_mismatch = false,
145 };
146
147 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
148}
149
150TEST(EmitUnencryptedLogTest, NegativeTooManyLogs)
151{
152 StrictMock<MockMemory> memory;
153 StrictMock<MockContext> context;
154 StrictMock<MockGreaterThan> greater_than;
155 StrictMock<MockExecutionIdManager> execution_id_manager;
156 StrictMock<MockSideEffectTracker> side_effect_tracker;
157 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
158
159 AztecAddress address = 0xdeadbeef;
160 MemoryAddress log_offset = 27;
161 const std::vector<FF> log_fields = { log_offset, log_offset + 1 };
162 uint32_t log_size = static_cast<uint32_t>(log_fields.size());
163 uint64_t end_log_address = 28;
164 // Minus three so header = 2 + log_size = 2 doesn't fit
165 TrackedSideEffects side_effect_states = {
166 .public_logs = PublicLogs{ { { .fields = testing::random_fields(FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH -
168 .contract_address = 0xdeadbeef } } }
169 };
170 // No change to side effect states due to failure.
171 const TrackedSideEffects& side_effect_states_after = side_effect_states;
172
173 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
174
175 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(1));
176 EXPECT_CALL(greater_than,
177 gt(side_effect_states.get_num_unencrypted_log_fields() + PUBLIC_LOG_HEADER_LENGTH + log_size,
179 .WillOnce(Return(true));
180 EXPECT_CALL(greater_than, gt(end_log_address, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
181
182 EXPECT_CALL(context, get_side_effect_tracker()).WillOnce(ReturnRef(side_effect_tracker));
183 EXPECT_CALL(side_effect_tracker, get_side_effects())
184 .WillOnce(ReturnRef(side_effect_states))
185 .WillOnce(ReturnRef(side_effect_states_after));
186
187 EXPECT_CALL(memory, get(_)).WillRepeatedly([](MemoryAddress address) -> const MemoryValue& {
188 static thread_local MemoryValue value;
189 value = MemoryValue::from<FF>(FF(address));
190 return value;
191 });
192
193 EXPECT_CALL(memory, get_space_id()).WillOnce(Return(57));
194 EXPECT_CALL(context, get_is_static()).WillOnce(Return(false));
195
196 EXPECT_THROW(emit_unencrypted_log.emit_unencrypted_log(memory, context, address, log_offset, log_size),
197 EmitUnencryptedLogException);
198
199 EmitUnencryptedLogWriteEvent expect_event = {
200 .execution_clk = 1,
201 .contract_address = address,
202 .space_id = 57,
203 .log_address = log_offset,
204 .log_size = log_size,
205 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
206 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
207 .is_static = false,
208 .values = to_memory_values(log_fields),
209 .error_memory_out_of_bounds = false,
210 .error_too_many_log_fields = true,
211 .error_tag_mismatch = false,
212 };
213
214 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
215}
216
217TEST(EmitUnencryptedLogTest, NegativeTagMismatch)
218{
219 StrictMock<MockMemory> memory;
220 StrictMock<MockContext> context;
221 StrictMock<MockGreaterThan> greater_than;
222 StrictMock<MockExecutionIdManager> execution_id_manager;
223 StrictMock<MockSideEffectTracker> side_effect_tracker;
224 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
225
226 AztecAddress address = 0xdeadbeef;
227 MemoryAddress log_offset = 27;
228 uint32_t log_size = 2;
229 uint64_t end_log_address = 28;
230 TrackedSideEffects side_effect_states = { .public_logs = {} };
231 // No change to side effect states due to failure.
232 const TrackedSideEffects& side_effect_states_after = side_effect_states;
233
234 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
235
236 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(1));
237 EXPECT_CALL(greater_than,
238 gt(side_effect_states.get_num_unencrypted_log_fields() + PUBLIC_LOG_HEADER_LENGTH + log_size,
240 .WillOnce(Return(false));
241 EXPECT_CALL(greater_than, gt(end_log_address, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
242
243 EXPECT_CALL(context, get_side_effect_tracker()).WillOnce(ReturnRef(side_effect_tracker));
244 EXPECT_CALL(side_effect_tracker, get_side_effects())
245 .WillOnce(ReturnRef(side_effect_states))
246 .WillOnce(ReturnRef(side_effect_states_after));
247
248 EXPECT_CALL(memory, get(_)).WillRepeatedly([](MemoryAddress address) -> const MemoryValue& {
249 static thread_local MemoryValue value;
250 value = MemoryValue::from<uint32_t>(address);
251 return value;
252 });
253
254 EXPECT_CALL(memory, get_space_id()).WillOnce(Return(57));
255 EXPECT_CALL(context, get_is_static()).WillOnce(Return(false));
256
257 EXPECT_THROW(emit_unencrypted_log.emit_unencrypted_log(memory, context, address, log_offset, log_size),
258 EmitUnencryptedLogException);
259
260 EmitUnencryptedLogWriteEvent expect_event = {
261 .execution_clk = 1,
262 .contract_address = address,
263 .space_id = 57,
264 .log_address = log_offset,
265 .log_size = log_size,
266 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
267 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
268 .is_static = false,
269 .values = { MemoryValue::from<uint32_t>(log_offset), MemoryValue::from<uint32_t>(log_offset + 1) },
270 .error_memory_out_of_bounds = false,
271 .error_too_many_log_fields = false,
272 .error_tag_mismatch = true,
273 };
274
275 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
276}
277
278TEST(EmitUnencryptedLogTest, NegativeStatic)
279{
280 StrictMock<MockMemory> memory;
281 StrictMock<MockContext> context;
282 StrictMock<MockGreaterThan> greater_than;
283 StrictMock<MockExecutionIdManager> execution_id_manager;
284 StrictMock<MockSideEffectTracker> side_effect_tracker;
285 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
286
287 AztecAddress address = 0xdeadbeef;
288 MemoryAddress log_offset = 27;
289 const std::vector<FF> log_fields = { log_offset, log_offset + 1 };
290 uint32_t log_size = static_cast<uint32_t>(log_fields.size());
291 uint64_t end_log_address = 28;
292 TrackedSideEffects side_effect_states = { .public_logs = {} };
293 // No change to side effect states due to failure.
294 const TrackedSideEffects& side_effect_states_after = side_effect_states;
295
296 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
297
298 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(1));
299 EXPECT_CALL(greater_than,
300 gt(side_effect_states.get_num_unencrypted_log_fields() + PUBLIC_LOG_HEADER_LENGTH + log_size,
302 .WillOnce(Return(false));
303 EXPECT_CALL(greater_than, gt(end_log_address, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
304
305 EXPECT_CALL(context, get_side_effect_tracker()).WillOnce(ReturnRef(side_effect_tracker));
306 EXPECT_CALL(side_effect_tracker, get_side_effects())
307 .WillOnce(ReturnRef(side_effect_states))
308 .WillOnce(ReturnRef(side_effect_states_after));
309
310 EXPECT_CALL(memory, get(_)).WillRepeatedly([](MemoryAddress address) -> const MemoryValue& {
311 static thread_local MemoryValue value;
312 value = MemoryValue::from<FF>(FF(address));
313 return value;
314 });
315
316 EXPECT_CALL(memory, get_space_id()).WillOnce(Return(57));
317 EXPECT_CALL(context, get_is_static()).WillOnce(Return(true));
318
319 EXPECT_THROW(emit_unencrypted_log.emit_unencrypted_log(memory, context, address, log_offset, log_size),
320 EmitUnencryptedLogException);
321
322 EmitUnencryptedLogWriteEvent expect_event = {
323 .execution_clk = 1,
324 .contract_address = address,
325 .space_id = 57,
326 .log_address = log_offset,
327 .log_size = log_size,
328 .prev_num_unencrypted_log_fields = side_effect_states.get_num_unencrypted_log_fields(),
329 .next_num_unencrypted_log_fields = side_effect_states_after.get_num_unencrypted_log_fields(),
330 .is_static = true,
331 .values = to_memory_values(log_fields),
332 .error_memory_out_of_bounds = false,
333 .error_too_many_log_fields = false,
334 .error_tag_mismatch = false,
335 };
336
337 EXPECT_THAT(event_emitter.dump_events(), ElementsAre(expect_event));
338}
339
340TEST(EmitUnencryptedLogTest, CheckpointListener)
341{
342 StrictMock<MockMemory> memory;
343 StrictMock<MockContext> context;
344 StrictMock<MockGreaterThan> greater_than;
345 StrictMock<MockExecutionIdManager> execution_id_manager;
346 EventEmitter<EmitUnencryptedLogEvent> event_emitter;
347 EmitUnencryptedLog emit_unencrypted_log(execution_id_manager, greater_than, event_emitter);
348
349 emit_unencrypted_log.on_checkpoint_created();
350 emit_unencrypted_log.on_checkpoint_committed();
351 emit_unencrypted_log.on_checkpoint_reverted();
352 EXPECT_THAT(event_emitter.get_events().size(), 3);
353 EXPECT_THAT(event_emitter.dump_events(),
357}
358
359} // namespace
360} // namespace bb::avm2::simulation
GreaterThan greater_than
#define FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH
#define FLAT_PUBLIC_LOGS_HEADER_LENGTH
#define PUBLIC_LOG_HEADER_LENGTH
#define AVM_HIGHEST_MEM_ADDRESS
ExecutionIdManager execution_id_manager
EventEmitter< DataCopyEvent > event_emitter
GreaterThan gt
StrictMock< MockContext > context
std::vector< FF > random_fields(size_t n)
Definition fixtures.cpp:23
TaggedValue MemoryValue
uint32_t MemoryAddress
AvmFlavorSettings::FF FF
Definition field.hpp:10
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
MemoryStore memory
SideEffectTracker side_effect_tracker