-
Notifications
You must be signed in to change notification settings - Fork 145
feat(batch kernel): wire up INPUT_NOTES_COMMITMENT & note erasure
#2905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mmagician
wants to merge
35
commits into
next
Choose a base branch
from
mmagician-claude/batch-kernel-logic
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
01f5f62
feat: verify batch tx list, tx headers, and input-notes commitment
claude 79967d6
test: drive batch-kernel rejection tests through BatchExecutor advice…
claude feeb1cc
style: use the '# =>' stack-comment convention in the batch kernel masm
claude 622bee3
feat: compute the nullifier-sorted batch INPUT_NOTES_COMMITMENT
claude fc74536
feat: erase intra-batch created-and-consumed notes from the batch inp…
claude 8746a94
fix: reject same-transaction create+consume via the erasure ordering …
claude 0e9e806
test: assert concrete batch-kernel errors in the binding/erasure nega…
claude a4f8bf5
docs: describe final-state behavior in batch-kernel comments
claude 6304eef
feat: bound batch note/tx counts and codegen sentinel keys
claude 92502cf
test: harden batch verifier/output tests from review
claude f85ebac
docs: clarify batch verifier warning on self-reported BATCH_ID
claude e295049
refactor: address PR review comments
claude d62e9e7
refactor: simplify tampered-advice test parametrization
claude 623d1cf
docs: address MASM review comments on memory/prologue
claude 174ed7e
refactor: split batch kernel into prologue / note-tracking / epilogue
claude c1496dd
perf: fold per-input epilogue assertions into the commitment pass
claude 4ee8a17
refactor: derive batch note-list keys from a domain message
claude 0a80c7c
Merge branch 'next' into mmagician-claude/batch-kernel-logic
claude 08cd5ac
refactor: address PR review on batch kernel docs and note-list keys
claude 91a2e3b
refactor: derive note-list keys via MASM word(...) const
claude 4abe140
docs: clarify note-tracking binding in note_tracker.masm
claude af662e6
refactor: name note lists by sort key
claude 65158db
refactor: simplify epilogue hashing and trim key comments
claude 74a4b8b
refactor(batch-kernel): drop dead scratch bookkeeping, clarify docs
claude 9f4f2f8
perf(batch-kernel): absorb input entries in runs, drop unreachable as…
claude c6178b7
test(batch): cover capacity limits and duplicate note marking
claude d502cc6
Revert "perf(batch-kernel): absorb input entries in runs, drop unreac…
claude 5bde6bf
test(batch): drive forged-batch-id tests through BatchExecutor
claude bf4eedd
refactor(batch): keep testing overrides out of BatchExecutor::execute
claude 8d18cb2
refactor(batch): take caller advice as a parameter, mirroring the tx …
claude ef594bb
docs: strip self-evident and overly verbose comments
claude df9ee18
fix: address review comments
claude 5df0369
Merge branch 'next' into mmagician-claude/batch-kernel-logic
mmagician 273fdf0
Merge remote-tracking branch 'origin/next' into mmagician-claude/batc…
claude 941d204
feat(batch): surface unsupported batches early in BatchExecutor
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,9 @@ | |
| - [BREAKING] Replaced the `BurnNote` marker type and its `BurnNote::create` factory with a struct built via a `bon` typestate builder (`BurnNote::builder()`); a `BurnNote` converts into a `Note` via `Note::from` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). | ||
| - [BREAKING] Replaced the `P2ideNote` marker type and its `P2ideNote::create` factory with a `P2ideNote` struct built via a `bon` typestate builder (`P2ideNote::builder()`). P2IDE notes must now carry at least one asset; the optional `reclaim_height`/`timelock_height` are set via the builder, `P2ideNoteStorage::into_recipient` is now infallible, and a `P2ideNote` converts into a `Note` via `Note::from` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). | ||
| - Added a skeleton batch kernel ([#1122](https://github.com/0xMiden/protocol/issues/1122)) wired through `LocalBatchProver::prove` and attached to `ProvenBatch` as an `ExecutionProof`. It does not yet perform any verification. | ||
| - The batch kernel verifies the transaction list against `BATCH_ID` and computes the nullifier-sorted `INPUT_NOTES_COMMITMENT` matching `ProposedBatch::input_notes().commitment()` ([#2905](https://github.com/0xMiden/protocol/pull/2905)). | ||
|
|
||
| - [BREAKING] Renamed `AccountStorageDelta` to `AccountStoragePatch` ([#3002](https://github.com/0xMiden/protocol/pull/3002)). | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this line duplicates the next changelog entry. The next one also includes |
||
| - [BREAKING] Renamed `AccountStorageDelta` to `AccountStoragePatch` ([#3002](https://github.com/0xMiden/protocol/pull/3002), [#3154](https://github.com/0xMiden/protocol/pull/3154)). | ||
| - [BREAKING] Replaced the per-tree account and nullifier backend traits with shared `SmtBackend` and `SmtBackendReader` traits, split into read-only and read-write capabilities, enabling read-only `LargeSmt`-backed tree views via `reader()` ([#2755](https://github.com/0xMiden/protocol/pull/2755), [#3009](https://github.com/0xMiden/protocol/pull/3009)). | ||
| - [BREAKING] Block validator signatures are now verified against the validator key committed to by the parent block, enabling safe validator key rotation. `BlockHeader::validator_key` now denotes the signer of the *next* block, `ProvenBlock`/`SignedBlock` `new` no longer verify the signature (pass the parent header to `validate` to authenticate a block against its parent's validator key), and `ProposedBlock` serialization gained a trailing `next_validator_key` field ([#3030](https://github.com/0xMiden/protocol/pull/3030)). | ||
|
|
||
162 changes: 162 additions & 0 deletions
162
crates/miden-protocol/asm/kernels/batch/lib/epilogue.masm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| use miden::core::crypto::hashes::poseidon2 | ||
|
|
||
| use miden::batch_kernel::memory | ||
| use miden::batch_kernel::memory::NOTE_ENTRY_FELT_LEN | ||
| use miden::batch_kernel::memory::INPUT_NOTE_CONSUMPTION_OFFSET | ||
| use miden::batch_kernel::memory::OUTPUT_NOTE_IS_CREATED_OFFSET | ||
|
|
||
| # ERRORS | ||
| # ================================================================================================= | ||
|
|
||
| const ERR_BATCH_INPUT_NOTE_NOT_CONSUMED="an input-note list entry was not consumed by any transaction" | ||
|
|
||
| const ERR_BATCH_OUTPUT_NOTE_NOT_CREATED="an output-note list entry was not created by any transaction" | ||
|
|
||
| const ERR_BATCH_NOTE_CONSUMED_BEFORE_CREATED="an erased input note was consumed before the transaction that creates it" | ||
|
|
||
| # ASSERTIONS | ||
| # ================================================================================================= | ||
|
|
||
| #! Asserts every output-note list entry was created by exactly one transaction (with the per-tx | ||
| #! binding, this proves the list is exactly the union of the per-transaction output notes, so a host | ||
| #! cannot fabricate an erasure with a note no transaction creates). | ||
| #! | ||
| #! The matching input-note checks (every entry consumed exactly once, none left pending-erasure) are | ||
| #! folded into the single pass in [`compute_input_notes_commitment`]. | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [] | ||
| proc assert_all_output_notes_created | ||
| exec.memory::get_num_output_notes | ||
| push.0 | ||
| dup.1 dup.1 neq | ||
| while.true | ||
| dup exec.memory::output_note_flags_ptr add.OUTPUT_NOTE_IS_CREATED_OFFSET mem_load | ||
| assert.err=ERR_BATCH_OUTPUT_NOTE_NOT_CREATED | ||
| add.1 | ||
| dup.1 dup.1 neq | ||
| end | ||
| drop drop | ||
| end | ||
|
|
||
| # INPUT NOTES COMMITMENT | ||
| # ================================================================================================= | ||
|
|
||
| #! Absorbs input-note list entry `idx`'s 8-felt `(NULLIFIER, NOTE_ID_OR_EMPTY)` tuple into the batch | ||
| #! hasher state held in memory (overwrite-mode poseidon2, matching `Hasher::hash_elements`). | ||
| #! | ||
| #! Inputs: [idx] | ||
| #! Outputs: [] | ||
| proc absorb_input_entry | ||
| # The entry occupies one double word [entry_ptr, entry_ptr + NOTE_ENTRY_FELT_LEN). | ||
| exec.memory::input_note_entry_ptr | ||
| # => [entry_ptr] | ||
| dup add.NOTE_ENTRY_FELT_LEN swap | ||
| # => [entry_ptr, end_ptr] | ||
| exec.memory::load_batch_hasher_state | ||
| # => [RATE0, RATE1, CAPACITY, entry_ptr, end_ptr] | ||
| exec.poseidon2::absorb_double_words_from_memory | ||
| # => [RATE0', RATE1', CAPACITY', end_ptr, end_ptr] | ||
| exec.memory::save_batch_hasher_state | ||
| # => [end_ptr, end_ptr] | ||
| drop drop | ||
| end | ||
|
mmagician marked this conversation as resolved.
|
||
|
|
||
| #! Computes INPUT_NOTES_COMMITMENT as the sequential poseidon2 hash of the non-erased | ||
| #! `(NULLIFIER, NOTE_ID_OR_EMPTY)` entries of the nullifier-sorted input-note list (entries with | ||
| #! erasure flag == 2 are skipped). | ||
| #! | ||
| #! The single pass over the input entries also enforces the epilogue invariants on each entry: it | ||
| #! was consumed exactly once (consumption == 1) and is not left expected-to-be-erased (erasure != 1, | ||
| #! i.e. any created-and-consumed note had its creator processed). | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [INPUT_NOTES_COMMITMENT] | ||
| proc compute_input_notes_commitment | ||
| # Initialize the batch hasher state in memory. | ||
| exec.poseidon2::init_no_padding | ||
| exec.memory::save_batch_hasher_state | ||
|
|
||
| exec.memory::get_num_input_notes | ||
| push.0 push.0 | ||
| # => [idx, absorbed_count, num] | ||
| dup dup.3 neq | ||
| # => [should_loop, idx, absorbed_count, num] | ||
| while.true | ||
| # Assert this entry was consumed exactly once and is not left expected-to-be-erased. | ||
| dup exec.memory::input_note_flags_ptr | ||
| # => [flags_ptr, idx, absorbed_count, num] | ||
| dup add.INPUT_NOTE_CONSUMPTION_OFFSET mem_load | ||
| # => [consumption, flags_ptr, idx, absorbed_count, num] | ||
| assert.err=ERR_BATCH_INPUT_NOTE_NOT_CONSUMED | ||
| # => [flags_ptr, idx, absorbed_count, num] | ||
| mem_load | ||
| # => [erasure, idx, absorbed_count, num] | ||
| dup neq.1 assert.err=ERR_BATCH_NOTE_CONSUMED_BEFORE_CREATED | ||
| # => [erasure, idx, absorbed_count, num] | ||
|
|
||
| # Absorb the entry unless it was erased (created-and-consumed in this batch). | ||
| neq.2 | ||
| # => [not_erased, idx, absorbed_count, num] | ||
| if.true | ||
| dup exec.absorb_input_entry | ||
| swap add.1 swap | ||
| # => [idx, absorbed_count+1, num] | ||
| end | ||
| add.1 | ||
| dup dup.3 neq | ||
| # => [should_loop, idx, absorbed_count, num] | ||
| end | ||
| # => [idx, absorbed_count, num] | ||
| drop swap drop | ||
| # => [absorbed_count] | ||
|
|
||
| # With no non-erased entries the commitment is the empty word, matching the early return in | ||
| # `build_input_note_commitment` (this is not the hash of zero elements). Otherwise squeeze the | ||
| # accumulated state. | ||
| eq.0 | ||
| if.true | ||
| padw | ||
| # => [EMPTY_WORD] | ||
| else | ||
| exec.memory::load_batch_hasher_state | ||
| exec.poseidon2::squeeze_digest | ||
| # => [INPUT_NOTES_COMMITMENT] | ||
| end | ||
|
mmagician marked this conversation as resolved.
|
||
| end | ||
|
|
||
| # OUTPUT NOTES COMMITMENT | ||
| # ================================================================================================= | ||
|
|
||
| #! Computes the batch's output-notes commitment (the batch note tree root). | ||
| #! | ||
| #! Placeholder: returns the empty word until the batch note tree is wired up. | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [OUTPUT_NOTES_COMMITMENT] | ||
| #! | ||
| #! TODO: hash the batch's output notes into the batch note tree (SMT) root. | ||
| proc compute_output_notes_commitment | ||
| padw | ||
| end | ||
|
|
||
| # EPILOGUE | ||
| # ================================================================================================= | ||
|
|
||
| #! Verifies the note-tracking results and computes the batch's note commitments. | ||
| #! | ||
| #! Asserts every output-note list entry was created, then computes the input- and output-notes | ||
| #! commitments. The per-input-entry invariants (consumed exactly once, no pending erasure) are | ||
| #! enforced inside the input-commitment pass. | ||
| #! | ||
| #! Inputs: [] | ||
| #! Outputs: [INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT] | ||
| #! | ||
| #! TODO: authenticate unauthenticated, non-erased input notes against BLOCK_COMMITMENT's chain MMR. | ||
| pub proc finalize | ||
| exec.assert_all_output_notes_created | ||
| exec.compute_output_notes_commitment | ||
| # => [OUTPUT_NOTES_COMMITMENT] | ||
| exec.compute_input_notes_commitment | ||
| # => [INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT] | ||
| end | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entry may need to call out the
BatchExecutor::executesignature change too. It now requires callerAdviceInputs, so downstream code usingexecute(batch)will stop compiling.