Skip to content

Commit 331ad6c

Browse files
authored
fix!: misc avm - fixes constraints, ts sim, cpp sim, tracegen (#16664)
Fixes to alu, context, execution, tx pil. Fixes to tx execution and tx tracegen. Trace side-effect operations before they fail in TS state manager. Always perform nullifier non-membership check on non-existence in AVM TS. Side-effects rollbacks in tx execution. 1. ALU PIL should disable C's tag check on `sel_err` (any error) rather than `sel_tag_err`. It at least needs to be disabled on div-by-0 as well. 2. `sel_instruction_fetching_success` should be forced to 0 on bytecode retrieval faliure. 3. TX's dispatch "end" interaction to execution's should use execution's `sel_failure` to capture "error or revert opcode". 4. Bytecode retrieval failures should emit an event that includes tree roots so that non-membership can be performed. 5. When bytecode is not found for a contract call, the execution trace's empty row should have opcode 0. 6. TX trace should snapshot and restore end-setup's side effect states. 7. Execution tracegen should handle "exit call scenarios" in a separate if-statement to individual opcodes, because if an opcode errors, we need to set all of the selectors for "exit", but also need to tracegen the failing opcode. 8. In the TS avm simulator, contract instance retrieval should perform the nullifier [non]membership check even if the instance does not exist.
2 parents 4229886 + 953f475 commit 331ad6c

File tree

15 files changed

+58
-31
lines changed

15 files changed

+58
-31
lines changed

barretenberg/cpp/pil/vm2/alu.pil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pol EXPECTED_C_TAG = (sel_op_add + sel_op_sub + sel_op_mul + sel_op_div + sel_op
119119
// Gating with (1 - sel_tag_err) is necessary because when an error occurs, we have to set the tag to 0,
120120
// which might not be equal to EXPECTED_C_TAG.
121121
#[C_TAG_CHECK]
122-
(1 - sel_tag_err) * (EXPECTED_C_TAG - ic_tag) = 0;
122+
(1 - sel_err) * (EXPECTED_C_TAG - ic_tag) = 0;
123123

124124
pol commit sel_tag_err;
125125
sel_tag_err * (1 - sel_tag_err) = 0;

barretenberg/cpp/pil/vm2/context.pil

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ namespace execution;
1212
#[skippable_if]
1313
sel = 0;
1414

15+
// TODO: make sure that all uses of `sel_error` here really should be "error" only
16+
// since `sel_error` will not be ` for the REVERT opcode. If we need "error or REVERT",
17+
// use `sel_failure`.
18+
1519
// Guaranteed to be boolean because sel_execute_call & sel_execute_static_call are mutually exclusive
1620
pol commit sel_enter_call;
1721
// The following selectors will be 0 if there is an error during execution (before the opcode execution step).

barretenberg/cpp/pil/vm2/execution.pil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ sel_bytecode_retrieval_success {
147147

148148
pol commit sel_instruction_fetching_success;
149149
// If sel = 0, we want sel_instruction_fetching_success = 0. We shouldn't be using it.
150-
sel_instruction_fetching_success = sel * (1 - sel_instruction_fetching_failure);
150+
sel_instruction_fetching_success = sel_bytecode_retrieval_success * (1 - sel_instruction_fetching_failure);
151151

152152
#[INSTRUCTION_FETCHING_BODY]
153153
sel_instruction_fetching_success {

barretenberg/cpp/pil/vm2/tx.pil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ namespace tx;
306306
execution.enqueued_call_end {
307307
execution.context_id,
308308
execution.next_context_id,
309-
execution.sel_error,
309+
execution.sel_failure,
310310
execution.discard,
311311
// Tree State
312312
execution.note_hash_tree_root,

barretenberg/cpp/src/barretenberg/vm2/generated/relations/alu_impl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void aluImpl<FF_>::accumulate(ContainerOverSubrelations& evals,
138138
}
139139
{ // C_TAG_CHECK
140140
using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>;
141-
auto tmp = (FF(1) - in.get(C::alu_sel_tag_err)) * (alu_EXPECTED_C_TAG - in.get(C::alu_ic_tag));
141+
auto tmp = (FF(1) - in.get(C::alu_sel_err)) * (alu_EXPECTED_C_TAG - in.get(C::alu_ic_tag));
142142
tmp *= scaling_factor;
143143
std::get<8>(evals) += typename Accumulator::View(tmp);
144144
}

barretenberg/cpp/src/barretenberg/vm2/generated/relations/execution_impl.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ void executionImpl<FF_>::accumulate(ContainerOverSubrelations& evals,
120120
{
121121
using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>;
122122
auto tmp = (in.get(C::execution_sel_instruction_fetching_success) -
123-
in.get(C::execution_sel) * (FF(1) - in.get(C::execution_sel_instruction_fetching_failure)));
123+
in.get(C::execution_sel_bytecode_retrieval_success) *
124+
(FF(1) - in.get(C::execution_sel_instruction_fetching_failure)));
124125
tmp *= scaling_factor;
125126
std::get<8>(evals) += typename Accumulator::View(tmp);
126127
}

barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_tx.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ struct lookup_tx_dispatch_exec_end_settings_ {
243243
static constexpr std::array<ColumnAndShifts, LOOKUP_TUPLE_SIZE> DST_COLUMNS = {
244244
ColumnAndShifts::execution_context_id,
245245
ColumnAndShifts::execution_next_context_id,
246-
ColumnAndShifts::execution_sel_error,
246+
ColumnAndShifts::execution_sel_failure,
247247
ColumnAndShifts::execution_discard,
248248
ColumnAndShifts::execution_note_hash_tree_root,
249249
ColumnAndShifts::execution_note_hash_tree_size,

barretenberg/cpp/src/barretenberg/vm2/simulation/bytecode_manager.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ BytecodeId TxBytecodeManager::get_bytecode(const AztecAddress& address)
1818
// This handles nullifier checks, address derivation, and update validation
1919
auto maybe_instance = contract_instance_manager.get_contract_instance(address);
2020

21+
auto tree_states = merkle_db.get_tree_state();
2122
if (!maybe_instance.has_value()) {
2223
// Contract instance not found - emit error event and throw
2324
retrieval_events.emit({
2425
.bytecode_id = FF(0), // Use default ID for error case
2526
.address = address,
27+
.nullifier_root = tree_states.nullifierTree.tree.root,
28+
.public_data_tree_root = tree_states.publicDataTree.tree.root,
2629
.error = true,
2730
});
2831
vinfo("Contract ", field_to_string(address), " is not deployed!");
@@ -45,7 +48,6 @@ BytecodeId TxBytecodeManager::get_bytecode(const AztecAddress& address)
4548
// Check if we've already processed this bytecode. If so, don't do hashing and decomposition again!
4649
if (bytecodes.contains(bytecode_id)) {
4750
// Already processed this bytecode - just emit retrieval event and return
48-
auto tree_states = merkle_db.get_tree_state();
4951
retrieval_events.emit({
5052
.bytecode_id = bytecode_id,
5153
.address = address,
@@ -69,8 +71,6 @@ BytecodeId TxBytecodeManager::get_bytecode(const AztecAddress& address)
6971
// We now save the bytecode so that we don't repeat this process.
7072
bytecodes.emplace(bytecode_id, std::move(shared_bytecode));
7173

72-
auto tree_states = merkle_db.get_tree_state();
73-
7474
retrieval_events.emit({
7575
.bytecode_id = bytecode_id,
7676
.address = address,

barretenberg/cpp/src/barretenberg/vm2/simulation/tx_execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ void TxExecution::simulate(const Tx& tx)
114114
format("[SETUP] UNRECOVERABLE ERROR! Enqueued call to ", call.request.contractAddress, " failed"));
115115
}
116116
}
117+
SideEffectStates end_setup_side_effect_states = tx_context.side_effect_states;
117118

118119
// The checkpoint we should go back to if anything from now on reverts.
119120
merkle_db.create_checkpoint();
@@ -159,6 +160,7 @@ void TxExecution::simulate(const Tx& tx)
159160
info("Revertible failure while simulating tx ", tx.hash, ": ", e.what());
160161
// We revert to the post-setup state.
161162
merkle_db.revert_checkpoint();
163+
tx_context.side_effect_states = end_setup_side_effect_states;
162164
// But we also create a new fork so that the teardown phase can transparently
163165
// commit or rollback to the end of teardown.
164166
merkle_db.create_checkpoint();

barretenberg/cpp/src/barretenberg/vm2/simulation/written_public_data_slots_tree_check.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ void WrittenPublicDataSlotsTreeCheck::create_checkpoint()
139139

140140
void WrittenPublicDataSlotsTreeCheck::commit_checkpoint()
141141
{
142+
// Commit the current top of the stack down one level.
142143
WrittenPublicDataSlotsTree current_tree = std::move(written_public_data_slots_tree_stack.top());
143144
written_public_data_slots_tree_stack.pop();
144145
written_public_data_slots_tree_stack.top() = std::move(current_tree);

0 commit comments

Comments
 (0)