Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion barretenberg/cpp/pil/vm2/execution.pil
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ sel_gas_sstore * (written_slots_tree_siloing_separator - constants.DOM_SEP__PUBL
#[CHECK_WRITTEN_STORAGE_SLOT]
sel_gas_sstore {
dynamic_da_gas_factor,
register[1], // value
register[1], // slot
prev_written_public_data_slots_tree_root,
written_slots_tree_height,
sel_gas_sstore, // sel_silo = 1
Expand Down
40 changes: 37 additions & 3 deletions barretenberg/cpp/pil/vm2/opcodes/emit_notehash.pil
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
include "../constants_gen.pil";
include "../range_check.pil";
include "../trees/note_hash_tree_check.pil";

namespace execution; // this is a virtual gadget that shares rows with the execution trace
/**
* This virtual gadget implements the EmitNoteHash opcode, which writes a new note hash
* to the note hash tree. The note hash is siloed and made unique by the note_hash_tree_check
* gadget before being inserted as a leaf. It also increments the note hash tree size
* and the number of note hashes emitted.
*
* The opcode is gated by the `sel_execute_emit_notehash` selector, which is set to 1 if the
* EmitNoteHash opcode has reached opcode dispatch (there are no earlier errors).
*
* This opcode also uses:
* - register[0]: the note hash input register (FF) (from execution.pil)
* - is_static: whether the current context is static (from context.pil)
* - contract_address: address of the current contract (from context.pil)
* - prev_note_hash_tree_root: root before the write (from context.pil)
* - prev_note_hash_tree_size: leaf index for the new note hash (from context.pil)
* - prev_num_note_hashes_emitted: count before this emission (from context.pil)
* - note_hash_tree_root: root after the write (from context.pil)
* - note_hash_tree_size: tree size after the write (from context.pil)
* - num_note_hashes_emitted: count after this emission (from context.pil)
* - sel_opcode_error: whether an opcode error was raised (from execution.pil)
* - discard: whether the transaction will be discarded (reverted) (from discard.pil)
*
* Interactions:
* - The gadget performs a lookup into the note_hash_tree_check gadget to write the note hash.
* - The lookup passes sel_silo=1 and sel_unique=1 so the tree check gadget silos the
* note hash with the contract address and makes it unique with the note hash index.
* - This lookup is only performed if no error occurs (sel_write_note_hash = 1).
*
* Errors:
* - If the max note hash writes limit has been reached, the operation raises an opcode error.
* - If the current context is static, the operation raises an opcode error.
*
* If there are errors in earlier temporality groups (i.e. the opcode is not dispatched),
* all columns in this trace should be 0 (gated by sel_execute_emit_notehash).
*/
namespace execution;

#[skippable_if]
sel_execute_emit_notehash = 0; // from execution.pil.
Expand All @@ -15,7 +49,7 @@ namespace execution; // this is a virtual gadget that shares rows with the execu
pol commit sel_reached_max_note_hashes; // @boolean
sel_reached_max_note_hashes * (1 - sel_reached_max_note_hashes) = 0;

pol commit remaining_note_hashes_inv;
pol commit remaining_note_hashes_inv; // @zero-check
// We reached the max note hashes if REMAINING_NOTE_HASH_WRITES is 0
#[MAX_NOTE_HASHES_REACHED]
sel_execute_emit_notehash * (REMAINING_NOTE_HASH_WRITES * (sel_reached_max_note_hashes * (1 - remaining_note_hashes_inv) + remaining_note_hashes_inv) - 1 + sel_reached_max_note_hashes) = 0;
Expand Down
35 changes: 25 additions & 10 deletions barretenberg/cpp/pil/vm2/opcodes/emit_nullifier.pil
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
include "../constants_gen.pil";

/**
* This virtual gadget implements the EmitNullifier opcode, which attempts to write a new nullifier
* to the nullifier tree for the current contract address. It also increments the nullifier tree size
* This virtual gadget implements the EmitNullifier opcode, which writes a new nullifier
* to the nullifier tree. The nullifier is siloed with the contract address by the
* indexed_tree_check gadget before being inserted. It also increments the nullifier tree size
* and the number of nullifiers emitted.
*
* The opcode is gated by the `sel_execute_emit_nullifier` selector, which is set to 1 if the
* EmitNullifier opcode has reached dispatch (there are no earlier errors).
* EmitNullifier opcode has reached opcode dispatch (there are no earlier errors).
*
* This opcode uses:
* - register[0] as the nullifier input register (FF)
* This opcode also uses:
* - register[0]: the nullifier input register (FF) (from execution.pil)
* - is_static: whether the current context is static (from context.pil)
* - contract_address: address of the current contract (from context.pil)
* - prev_nullifier_tree_root: root before the write (from context.pil)
* - prev_nullifier_tree_size: leaf index for the new nullifier (from context.pil)
* - prev_num_nullifiers_emitted: count before this emission (from context.pil)
* - nullifier_tree_root: root after the write (from context.pil)
* - nullifier_tree_size: tree size after the write (from context.pil)
* - num_nullifiers_emitted: count after this emission (from context.pil)
* - nullifier_tree_height: height of the nullifier tree (from execution.pil)
* - sel_opcode_error: whether an opcode error was raised (from execution.pil)
* - discard: whether the transaction will be discarded (reverted) (from discard.pil)
*
* Interactions:
* - The gadget performs a lookup into the indexed_tree_check gadget to attempt to write the nullifier.
* - This lookup is only performed if no limit error occurs.
* - The gadget performs a lookup into the indexed_tree_check gadget to write the nullifier.
* - The lookup passes sel_silo=1 so the tree check gadget silos the nullifier
* with the contract address.
* - This lookup is only performed if no error occurs (sel_write_nullifier = 1).
*
* Errors:
* - If the max nullifier writes limit has been reached, the operation raises an opcode error.
* - If the current context is static, the operation raises an opcode error.
* - If the nullifier already exists (collision), the operation raises an opcode error.
*
* If there are errors in earlier temporality groups (i.e. the opcode is not dispatched),
* all selectors should be 0 and intermediate values should be 0.
* all columns in this trace should be 0 (gated by sel_execute_emit_nullifier).
*/
namespace execution; // this is a virtual gadget that shares rows with the execution trace
namespace execution;

// No relations will be checked if this identity is satisfied.
#[skippable_if]
Expand All @@ -36,7 +51,7 @@ namespace execution; // this is a virtual gadget that shares rows with the execu
pol commit sel_reached_max_nullifiers; // @boolean
sel_reached_max_nullifiers * (1 - sel_reached_max_nullifiers) = 0;

pol commit remaining_nullifiers_inv;
pol commit remaining_nullifiers_inv; // @zero-check
// Limit error if REMAINING_NULLIFIER_WRITES is 0
#[MAX_NULLIFIER_WRITES_REACHED]
sel_execute_emit_nullifier * (REMAINING_NULLIFIER_WRITES * (sel_reached_max_nullifiers * (1 - remaining_nullifiers_inv) + remaining_nullifiers_inv) - 1 + sel_reached_max_nullifiers) = 0;
Expand Down
Loading
Loading