Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
tx_trace.test.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
6
16
17namespace bb::avm2::tracegen {
18namespace {
19
20using enum ::bb::avm2::WireOpCode;
21
22using ::testing::AllOf;
23
24TEST(TxTraceGenTest, EnqueuedCallEvent)
25{
26 TestTraceContainer trace;
27 TxTraceBuilder builder;
28
29 auto msg_sender = FF::random_element();
30 auto contract_address = FF::random_element();
31 auto calldata_hash = FF::random_element();
32
33 simulation::TxStartupEvent startup_event = {
34 .state = { .gas_used = { 500, 1000 }, .tree_states = {}, .written_public_data_slots_tree_snapshot = {} },
35 .gas_limit = { 1000, 2000 },
36 .teardown_gas_limit = { 0, 0 },
37 };
38
39 simulation::TxPhaseEvent tx_event = {
41 .state_before = {},
42 .state_after = {},
43 .reverted = false,
44 .event =
45 simulation::EnqueuedCallEvent{
46 .msg_sender = msg_sender,
47 .contract_address = contract_address,
48 .is_static = false,
49 .calldata_hash = calldata_hash,
50 .success = true,
51 },
52 };
53
54 builder.process({ startup_event, tx_event }, trace);
55 auto rows = trace.as_rows();
56 ASSERT_EQ(rows.size(), 13); // 12 tx trace rows + 1 precomputed row
57 EXPECT_THAT(rows[static_cast<uint8_t>(TransactionPhase::NR_NOTE_INSERTION)],
58 AllOf(ROW_FIELD_EQ(tx_sel, 1),
59 ROW_FIELD_EQ(tx_phase_value, static_cast<uint8_t>(TransactionPhase::NR_NOTE_INSERTION)),
60 ROW_FIELD_EQ(tx_is_padded, 1),
61 ROW_FIELD_EQ(tx_is_tree_insert_phase, 1),
62 ROW_FIELD_EQ(tx_sel_non_revertible_append_note_hash, 1),
64 tx_read_pi_length_offset,
66 ROW_FIELD_EQ(tx_read_pi_offset,
68 ROW_FIELD_EQ(tx_start_phase, 1),
69 ROW_FIELD_EQ(tx_end_phase, 1),
70 ROW_FIELD_EQ(tx_is_static, false)));
71
72 // Setup
73 EXPECT_THAT(rows[static_cast<uint8_t>(TransactionPhase::SETUP)],
74 AllOf(ROW_FIELD_EQ(tx_sel, 1),
75 ROW_FIELD_EQ(tx_phase_value, static_cast<uint8_t>(TransactionPhase::SETUP)),
76 ROW_FIELD_EQ(tx_start_phase, 1),
77 ROW_FIELD_EQ(tx_is_public_call_request, 1),
78 ROW_FIELD_EQ(tx_read_pi_length_offset,
81 ROW_FIELD_EQ(tx_remaining_phase_counter, 1),
82 ROW_FIELD_EQ(tx_remaining_phase_inv, 1),
83 ROW_FIELD_EQ(tx_msg_sender, msg_sender),
84 ROW_FIELD_EQ(tx_contract_addr, contract_address),
85 ROW_FIELD_EQ(tx_calldata_hash, calldata_hash),
86 ROW_FIELD_EQ(tx_end_phase, 1)));
87};
88
89TEST(TxTraceGenTest, CollectFeeEvent)
90{
91 TestTraceContainer trace;
92 TxTraceBuilder builder;
93
94 auto fee_payer = FF::random_element();
95 auto fee_payer_balance = FF::neg_one();
96 auto effective_fee_per_da_gas = 100;
97 auto effective_fee_per_l2_gas = 200;
98 auto prev_da_gas_used = 1000;
99 auto prev_l2_gas_used = 500;
100 auto fee = effective_fee_per_da_gas * prev_da_gas_used + effective_fee_per_l2_gas * prev_l2_gas_used;
101
102 simulation::TxStartupEvent startup_event = {
103 .state = { .gas_used = { 500, 1000 }, .tree_states = {}, .written_public_data_slots_tree_snapshot = {} },
104 .gas_limit = { 1000, 2000 },
105 .teardown_gas_limit = { 0, 0 },
106 };
107
108 simulation::TxPhaseEvent tx_event = { .phase = TransactionPhase::COLLECT_GAS_FEES,
109 .state_before = {},
110 .state_after = {},
111 .reverted = false,
112 .event = simulation::CollectGasFeeEvent{
113 .effective_fee_per_da_gas =
114 static_cast<uint128_t>(effective_fee_per_da_gas),
115 .effective_fee_per_l2_gas =
116 static_cast<uint128_t>(effective_fee_per_l2_gas),
117 .fee_payer = fee_payer,
118 .fee_payer_balance = fee_payer_balance,
119 .fee = fee,
120 } };
121
122 builder.process({ startup_event, tx_event }, trace);
123 auto rows = trace.as_rows();
124 ASSERT_EQ(rows.size(), 13); // 12 tx trace rows + 1 precomputed row
125
126 EXPECT_THAT(rows[static_cast<uint8_t>(TransactionPhase::COLLECT_GAS_FEES)],
127 AllOf(ROW_FIELD_EQ(tx_sel, 1),
128 ROW_FIELD_EQ(tx_phase_value, static_cast<uint8_t>(TransactionPhase::COLLECT_GAS_FEES)),
129 ROW_FIELD_EQ(tx_is_padded, 0),
130 ROW_FIELD_EQ(tx_start_phase, 1),
131 ROW_FIELD_EQ(tx_sel_read_phase_length, 0),
132 ROW_FIELD_EQ(tx_end_phase, 1),
133 ROW_FIELD_EQ(tx_prev_da_gas_used, prev_da_gas_used),
134 ROW_FIELD_EQ(tx_prev_l2_gas_used, prev_l2_gas_used),
136 ROW_FIELD_EQ(tx_read_pi_length_offset, 0),
138 ROW_FIELD_EQ(tx_remaining_phase_counter, 1),
139 ROW_FIELD_EQ(tx_remaining_phase_inv, FF(1).invert()),
140 ROW_FIELD_EQ(tx_remaining_phase_minus_one_inv, 0),
141 ROW_FIELD_EQ(tx_is_collect_fee, 1),
142 ROW_FIELD_EQ(tx_effective_fee_per_da_gas, FF(effective_fee_per_da_gas)),
143 ROW_FIELD_EQ(tx_effective_fee_per_l2_gas, FF(effective_fee_per_l2_gas)),
144 ROW_FIELD_EQ(tx_fee_payer, fee_payer),
145 ROW_FIELD_EQ(tx_fee_payer_pi_offset, AVM_PUBLIC_INPUTS_FEE_PAYER_ROW_IDX),
146 ROW_FIELD_EQ(tx_fee, fee),
147 ROW_FIELD_EQ(tx_fee_payer_balance, fee_payer_balance),
148 ROW_FIELD_EQ(tx_next_da_gas_used, prev_da_gas_used),
149 ROW_FIELD_EQ(tx_next_l2_gas_used, prev_l2_gas_used),
150 ROW_FIELD_EQ(tx_uint32_max, 0xffffffff)));
151};
152
153TEST(TxTraceGenTest, PadTreesEvent)
154{
155 TestTraceContainer trace;
156 TxTraceBuilder builder;
157
158 simulation::TxStartupEvent startup_event = {
159 .state = { .gas_used = { 500, 1000 }, .tree_states = {}, .written_public_data_slots_tree_snapshot = {} },
160 .gas_limit = { 1000, 2000 },
161 .teardown_gas_limit = { 0, 0 },
162 };
163
164 simulation::TxPhaseEvent tx_event = { .phase = TransactionPhase::TREE_PADDING,
165 .state_before = {
166 .tree_states = {
167 .noteHashTree = {
168 .tree = {
169 .root = 27,
170 .nextAvailableLeafIndex = 65,
171 },
172 .counter = 1
173 },
174 .nullifierTree = {
175 .tree = {
176 .root = 28,
177 .nextAvailableLeafIndex = 127,
178 },
179 .counter = 63
180 },
181 },
182 },
183 .state_after = {
184 .tree_states = {
185 .noteHashTree = {
186 .tree = {
187 .root = 27,
188 .nextAvailableLeafIndex = 128,
189 },
190 .counter = 1
191 },
192 .nullifierTree = {
193 .tree = {
194 .root = 28,
195 .nextAvailableLeafIndex = 128,
196 },
197 .counter = 63
198 },
199 },
200 },
201 .reverted = false,
202 .event = simulation::PadTreesEvent{} };
203
204 builder.process({ startup_event, tx_event }, trace);
205 auto rows = trace.as_rows();
206 ASSERT_EQ(rows.size(), 13); // 12 tx trace rows + 1 precomputed row
207
208 EXPECT_THAT(rows[static_cast<uint8_t>(TransactionPhase::TREE_PADDING)],
209 AllOf(ROW_FIELD_EQ(tx_sel, 1),
210 ROW_FIELD_EQ(tx_phase_value, static_cast<uint8_t>(TransactionPhase::TREE_PADDING)),
211 ROW_FIELD_EQ(tx_start_phase, 1),
212 ROW_FIELD_EQ(tx_end_phase, 1),
213 ROW_FIELD_EQ(tx_is_tree_padding, 1),
214 ROW_FIELD_EQ(tx_remaining_phase_counter, 1),
215 ROW_FIELD_EQ(tx_remaining_phase_inv, 1),
216 ROW_FIELD_EQ(tx_sel_can_emit_note_hash, 1),
217 ROW_FIELD_EQ(tx_sel_can_emit_nullifier, 1),
218 ROW_FIELD_EQ(tx_prev_note_hash_tree_root, 27),
219 ROW_FIELD_EQ(tx_prev_note_hash_tree_size, 65),
220 ROW_FIELD_EQ(tx_prev_num_note_hashes_emitted, 1),
221 ROW_FIELD_EQ(tx_next_note_hash_tree_root, 27),
222 ROW_FIELD_EQ(tx_next_note_hash_tree_size, 128),
223 ROW_FIELD_EQ(tx_prev_nullifier_tree_root, 28),
224 ROW_FIELD_EQ(tx_prev_nullifier_tree_size, 127),
225 ROW_FIELD_EQ(tx_prev_num_nullifiers_emitted, 63),
226 ROW_FIELD_EQ(tx_next_nullifier_tree_root, 28),
227 ROW_FIELD_EQ(tx_next_nullifier_tree_size, 128)));
228}
229
230TEST(TxTraceGenTest, CleanupEvent)
231{
232 TestTraceContainer trace;
233 TxTraceBuilder builder;
234
235 simulation::TxStartupEvent startup_event = {
236 .state = { .gas_used = { 500, 1000 }, .tree_states = {}, .written_public_data_slots_tree_snapshot = {} },
237 .gas_limit = { 1000, 2000 },
238 .teardown_gas_limit = { 0, 0 },
239 };
240
241 simulation::TxPhaseEvent tx_event = { .phase = TransactionPhase::CLEANUP,
242 .state_before = {},
243 .state_after = {},
244 .reverted = false,
245 .event = simulation::CleanupEvent{} };
246
247 builder.process({ startup_event, tx_event }, trace);
248 auto rows = trace.as_rows();
249 ASSERT_EQ(rows.size(), 13); // 12 tx trace rows + 1 precomputed row
250
251 EXPECT_THAT(
252 rows[static_cast<uint8_t>(TransactionPhase::CLEANUP)],
253 AllOf(ROW_FIELD_EQ(tx_sel, 1),
254 ROW_FIELD_EQ(tx_phase_value, static_cast<uint8_t>(TransactionPhase::CLEANUP)),
255 ROW_FIELD_EQ(tx_start_phase, 1),
256 ROW_FIELD_EQ(tx_end_phase, 1),
257 ROW_FIELD_EQ(tx_is_cleanup, 1),
258 ROW_FIELD_EQ(tx_remaining_phase_counter, 1),
259 ROW_FIELD_EQ(tx_remaining_phase_inv, 1),
261 ROW_FIELD_EQ(tx_should_read_note_hash_tree, 1),
263 ROW_FIELD_EQ(tx_should_read_nullifier_tree, 1),
265 ROW_FIELD_EQ(tx_should_read_public_data_tree, 1),
267 ROW_FIELD_EQ(tx_should_read_l1_l2_tree, 1),
269 ROW_FIELD_EQ(tx_should_read_gas_used, 1)));
270}
271
272} // namespace
273} // namespace bb::avm2::tracegen
#define AVM_PUBLIC_INPUTS_END_TREE_SNAPSHOTS_L1_TO_L2_MESSAGE_TREE_ROW_IDX
#define AVM_PUBLIC_INPUTS_EFFECTIVE_GAS_FEES_ROW_IDX
#define AVM_PUBLIC_INPUTS_FEE_PAYER_ROW_IDX
#define AVM_PUBLIC_INPUTS_TRANSACTION_FEE_ROW_IDX
#define AVM_PUBLIC_INPUTS_END_GAS_USED_ROW_IDX
#define AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_NOTE_HASHES_ROW_IDX
#define AVM_PUBLIC_INPUTS_PUBLIC_SETUP_CALL_REQUESTS_ROW_IDX
#define AVM_PUBLIC_INPUTS_END_TREE_SNAPSHOTS_NULLIFIER_TREE_ROW_IDX
#define AVM_PUBLIC_INPUTS_END_TREE_SNAPSHOTS_NOTE_HASH_TREE_ROW_IDX
#define AVM_PUBLIC_INPUTS_PUBLIC_CALL_REQUEST_ARRAY_LENGTHS_SETUP_CALLS_ROW_IDX
#define AVM_PUBLIC_INPUTS_PREVIOUS_NON_REVERTIBLE_ACCUMULATED_DATA_ARRAY_LENGTHS_NOTE_HASHES_ROW_IDX
#define AVM_PUBLIC_INPUTS_END_TREE_SNAPSHOTS_PUBLIC_DATA_TREE_ROW_IDX
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
std::vector< AvmFullRowConstRef > as_rows() const
AluTraceBuilder builder
Definition alu.test.cpp:123
TestTraceContainer trace
#define ROW_FIELD_EQ(field_name, expression)
Definition macros.hpp:15
TEST(EmitUnencryptedLogTest, Basic)
@ NR_NOTE_INSERTION
AvmFlavorSettings::FF FF
Definition field.hpp:10
unsigned __int128 uint128_t
Definition serialize.hpp:44