feat(batch kernel): emit batch_expiration_block_num as the running-min over transactions#3019
Draft
mmagician wants to merge 32 commits into
Draft
Conversation
Establishes the public input/output contract for the batch kernel (#1122) plus the Rust plumbing that surrounds it, without any verification logic. - main.masm drops TRANSACTIONS_COMMITMENT + BLOCK_HASH and exits; the VM's depth >= 16 invariant leaves the all-zero 16-felt output region in place. - BatchKernel struct exposes prepare_inputs / build_input_stack / build_output_stack / parse_output_stack; build_advice_inputs returns the default empty AdviceInputs since the skeleton ignores advice data. - ProvenBatch carries a proof: ExecutionProof field through new_unchecked and serde. - LocalBatchProver::prove now runs the kernel via miden_prover::prove and attaches the proof to the returned ProvenBatch. The kernel's public outputs are not yet cross-checked against the proposed batch; that lands with the verification logic. - prove_dummy retained for tests that don't want proof generation. Smoke test exercises the full plumbing: builds a realistic two-transaction ProposedBatch, runs the kernel via FastProcessor, asserts the parsed outputs are empty / zero. TODO list in main.masm enumerates the checks the verification PR will introduce.
Co-authored-by: Marti <marcin.gorny.94@protonmail.com>
The batch kernel is compiled separately and its MASM errors are not extracted by generate_error_constants (which only scans the transaction kernel dir), so the BATCH entry in TX_KERNEL_ERROR_CATEGORIES is inert. Batch error handling will be added properly alongside the verification logic.
Pass transactions_commitment before block_hash so the parameter order matches the documented input stack [TRANSACTIONS_COMMITMENT, BLOCK_HASH]. Also drop the now-stale reference to the main.masm TODO from the BatchKernel doc comment.
The getter had no callers.
Replace the two separate pad-word checks with a single scan over every cell after batch_expiration_block_num, dropping the EXPIRATION_PAD_WORD_* and TRAILING_PAD_WORD_FELT_IDX constants.
Expose TestSetup and setup_chain from the proposed_batch test module and reuse them in the batch kernel smoke test instead of re-implementing the identical TestSetup/setup/generate_account fixtures.
…h-kernel-skeleton
…h-kernel-skeleton # Conflicts: # Cargo.lock # crates/miden-protocol/src/batch/mod.rs # crates/miden-testing/src/kernel_tests/batch/mod.rs # crates/miden-tx-batch-prover/Cargo.toml # crates/miden-tx-batch-prover/src/local_batch_prover.rs
…TMENT Rename the batch kernel's public inputs from TRANSACTIONS_COMMITMENT to BATCH_ID (consistent with the `BatchId` type the value comes from) and from BLOCK_HASH to BLOCK_COMMITMENT (we no longer use "hash"). Trim the over-detailed BATCH_ID doc comment down to just referencing `BatchId`. Addresses review comments on PR #2904.
Prefer the associated constant `Felt::ZERO` over the bare `ZERO` import in the batch output padding check. Addresses a review comment on PR #2904.
Stringifying the kernel error via `to_string` discarded the source error chain. Wrap the real source instead: `BatchKernelExecutionFailed` now carries `#[source] ExecutionError`, and a dedicated `BatchKernelOutputInvalid(#[source] BatchOutputError)` variant covers output-stack parsing failures. The batch prover maps these directly. Addresses a review comment on PR #2904.
Adopt the `test_*` naming used by `kernel_tests/tx/test_*.rs` so the `kernel_tests::batch::batch_kernel` path is no longer redundant and future per-feature batch kernel test modules slot in consistently. Addresses a review comment on PR #2904.
Separate batch kernel execution from proof generation, mirroring the transaction flow's ExecutedTransaction: ProposedBatch -> BatchExecutor::execute -> ExecutedBatch ExecutedBatch -> LocalBatchProver::prove -> ProvenBatch `BatchExecutor::execute` runs the batch kernel (via the synchronous trace APIs, `execute_trace_inputs_sync`), validates the output stack shape, and returns an `ExecutedBatch` holding the trace inputs. `LocalBatchProver` now consumes an `ExecutedBatch` and only builds the trace + proof (via `prove_from_trace_sync`), so the flow is fully synchronous. Transaction proofs are already verified in `ProposedBatch::new`, so the executor does not re-verify them. This lets tests exercise raw batch execution without re-proving. The batch kernel smoke test now goes through `BatchExecutor`, removing the inline FastProcessor setup, and a new test covers the execute -> prove path. Addresses review comment T19 on PR #2904.
Introduce a `BatchOutput` type (mirroring `TransactionOutputs`) that encapsulates the batch kernel's parsed outputs — input/output note commitments and the batch expiration block number — instead of returning a raw `(Word, Word, BlockNumber)` tuple. The output-stack layout indices move onto `BatchOutput` as associated constants. Addresses review comment T15 on PR #2904.
Order the batch kernel's public inputs as [BLOCK_COMMITMENT, BATCH_ID] to stay consistent with the transaction kernel's input layout. Addresses a review comment on PR #2904.
Rename the batch kernel's second output from OUTPUT_NOTES_COMMITMENT to BATCH_NOTE_TREE_ROOT (and the `BatchOutput` field/accessor/layout const accordingly). The end-goal output is the root of the batch's note tree, which lets the block kernel aggregate per-batch note trees instead of a flat output-notes commitment; renaming now fixes the contract name even though the value is still wired up in a follow-up. Addresses a review comment on PR #2904.
Take `BatchId` instead of a raw `Word` so the input contract is expressed through the domain type.
The type holds multiple outputs; rename it for consistency with `TransactionOutputs`.
Replace `BatchKernel::parse_output_stack` with `BatchOutputs::parse`, and return `BatchOutputError::OutputStackInvalid` instead of panicking when a required output word or element is missing from the stack.
Store the parsed `BatchOutputs` on `ExecutedBatch` and expose it via a typed `batch_outputs()` accessor, replacing the raw `stack_outputs()`.
5972411 to
ef11540
Compare
Add unit tests for the well-formed stack, non-zero padding rejection, and oversized expiration block number rejection.
batch_expiration_block_num as the running-min over transactions
batch_expiration_block_num as the running-min over transactionsbatch_expiration_block_num as the running-min over transactions
7e97e87 to
7dbd6b7
Compare
ef11540 to
56363ea
Compare
7dbd6b7 to
5bccee1
Compare
56363ea to
fc480f2
Compare
5bccee1 to
133f9bb
Compare
fc480f2 to
ea42818
Compare
Fill in the batch kernel to verify the batch's transaction list against its BATCH_ID (Layer 1), verify each transaction header (Layer 2), and recompute the batch INPUT_NOTES_COMMITMENT from the verified per-tx input notes (Layer 3). Output-notes (BATCH_NOTE_TREE_ROOT) and the expiration running-min stay as zero placeholders, wired up in follow-up PRs.
133f9bb to
59c2efb
Compare
ea42818 to
af57214
Compare
… injection Add BatchExecutor::extend_advice_inputs (mirroring TransactionContextBuilder) so the kernel's rejection paths can be exercised through the normal executor with tampered advice, and drop the low-level run_kernel test helper. The three negative tests now corrupt the Layer 1/2/3 advice-map entries via the executor.
Match the operand-stack (# =>) and advice-stack (# AS =>) comment style used throughout the rest of the protocol assembly.
…tions The batch kernel accumulates the minimum expiration_block_num across all transactions (popped per-tx from the advice stack during Layer 2 header verification) and emits it as the batch_expiration_block_num output. BatchExecutor cross-checks the kernel's value against the expiration the ProposedBatch independently derives, erroring with BatchExpirationMismatch on disagreement.
af57214 to
b46a277
Compare
093ac8e to
622bee3
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Stacked on top of #2905. Adds the batch's
batch_expiration_block_numoutput: the minimumexpiration_block_numacross all transactions in the batch.What this does
expiration_block_numfrom the advice stack and accumulates the running minimum intomemory::BATCH_EXPIRATION_PTR(initialised tou32::MAX). The minimum is order-independent, so advice-stack ordering carries no correctness risk.main.masmemits the accumulated minimum at output felt index 8:[INPUT_NOTES_COMMITMENT, BATCH_NOTE_TREE_ROOT, batch_expiration_block_num, pad(7)].BatchKernel::build_advice_inputspushes each transaction'sexpiration_block_numonto the advice stack.BatchExecutor::executecross-checks the kernel's emitted value against the expiration theProposedBatchindependently derives from its transactions, returningProvenBatchError::BatchExpirationMismatchon disagreement.BATCH_NOTE_TREE_ROOTremains a zero placeholder (BatchNoteTree work).Caveats (tracked as TODOs)
expiration_block_num_i > reference_block_numis not yet asserted.Tests
batch_kernel_emits_input_notes_commitment_and_expirationasserts the emitted expiration equals the proposed batch's independently-derived minimum (800 = min(1234, 800)).batch_executor_then_prover_produces_proven_batchexercises the executor cross-check end-to-end.