feat!: constrain discarding of side-effects for tx-level operations in AVM#16258
feat!: constrain discarding of side-effects for tx-level operations in AVM#16258
Conversation
32b01b3 to
7ff82e3
Compare
4d11b7a to
51cb9bc
Compare
There was a problem hiding this comment.
Could live in tx.pil. I opted to throw it in a virtual file as I did with execution discard.
| WrittenPublicDataSlotsTreeCheckInterface& written_public_data_slots_tree, | ||
| SideEffectStates side_effect_states) | ||
| SideEffectStates side_effect_states, | ||
| TransactionPhase phase) | ||
| : merkle_db(merkle_db) |
There was a problem hiding this comment.
I opted to add phase to the context like this. There are probably other ways. Phase is (and already was) needed for execution tracegen of discard, but we were just hardcoding it to APP LOGIC before.
b7ed13d to
f18cfa8
Compare
| bool res = avm.verify(proof, inputs.publicInputs, vk); | ||
| info("verification: ", res ? "success" : "failure"); | ||
| if (!res) { | ||
| throw std::runtime_error("Generated proof is invalid!1!!1"); |
| bool discard = false; | ||
| if (is_revertible(tx_phase_event->phase)) { | ||
| if (tx_phase_event->phase == TransactionPhase::TEARDOWN) { | ||
| discard = teardown_failure; | ||
| } else { | ||
| // Even if we don't fail until later in teardown, all revertible phases discard. | ||
| discard = teardown_failure || r_insertion_or_app_logic_failure; | ||
| } | ||
| } | ||
| if (tx_phase_event->reverted) { | ||
| // If we are in a revertible phase, we set the discard column to 1 | ||
| // If we are in a non-revertible phase, we set the discard column to 0 | ||
| discard = is_revertible(tx_phase_event->phase); | ||
| } else if (r_insertion_or_app_logic_failure && is_revertible(tx_phase_event->phase)) { | ||
| // If we have a revertible failure in a previous phase, we set the discard column to 1 | ||
| discard = true; | ||
| } else if (teardown_failure && tx_phase_event->phase == TransactionPhase::TEARDOWN) { | ||
| // If we have a teardown failure, we set the discard column to 1 | ||
| discard = true; | ||
| } |
There was a problem hiding this comment.
This looks like the mix of two strategies to set discard? or am i missing something?
There was a problem hiding this comment.
Also we can probably compute discard outside of the for, since discard only needs to be computed once per phase I think
There was a problem hiding this comment.
hmm i think you're right on both accounts. I'll clean up.
There was a problem hiding this comment.
cleaned it up to only use the first approach, and moved that to the start of the outer "buckets" loop so it only happens once per-phase.
3dcc73f to
248fa75
Compare
248fa75 to
7611091
Compare
✅ Deploy Preview for barretenberg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
18ca663 to
f2a192b
Compare
f2a192b to
e59c72f
Compare

Link to DD.
Relevant sections from the
discardDDTX trace columns
phase: the phase of the current rowis_revertible: is this row in a revertible phase (revertible insertions, app logic or teardown)is_padded: boolean representing whether this row is an empty row as a placeholder for a skipped phase.failure/reverted: this TX row fails in some way (enqueued call fails or insertion fails due to limit reached or nullifier collision.revertedin the TX trace which is probably fine because there is no distinction betweenerrorandrevertin TX.discard: this context or one of its ancestors fails. All side effects should be discarded.TX trace constraints
discardis a booleanfailureanddiscardmust remain 0. These phases cannot fail at the top level.if failure == 1, thendiscard == 1must hold true.discardis propagated to the next row.discardto the next row is lifted if any one of the following conditions are met:is_revertible == 0 && is_revertible’ == 1).reverted == 1).discard == 1is propagated past teardown because it was 1 and teardown does not fail, the constraint will fail (item 2 above) that disallows discarding during non-revertible phases. Together, these constraints enforce that ifdiscardis set for teardown, teardown must fail, in which case propagation is lifted anddiscardcan be reset to 0 for the following non-revertible phases.context_idis used as the key for a lookup to the execution trace to retrievefailure.is_revertibleis constrained to be correct even for padding rows (so app-logic padding should haveis_revertible == 1.TX tracegen
For TX tracegen, we need a preprocessing phase similar to execution because in order to populate
discard, we need to figure out whether a failure occurs later in the current phase (or phase grouping), or in some later phase.The preprocessing phase should figure out:
r_insertion_or_app_logic_failure: (boolean) did revertible insertions or app logic failteardown_failure: (boolean) did teardown failThen we populate
discardfor each phase as follows:discard = r_insertion_or_app_logic_failure || teardown_failurediscard = teardown_failure