Skip to content

chore: propagate CodePatch from the transaction kernel to the proven transaction - #4103

Open
PhilippGackstatter wants to merge 8 commits into
pgackst-code-tree-patchfrom
pgackst-code-patch-integration
Open

PhilippGackstatter wants to merge 8 commits into
pgackst-code-tree-patchfrom
pgackst-code-patch-integration

Conversation

@PhilippGackstatter

Copy link
Copy Markdown
Contributor

Changes

This wires CodePatch through the whole transaction pipeline: from the kernel output stack, through the executor's consistency checks and the proven transaction, to the verifier. The kernel still emits an empty patch, so later work only needs to fill in the kernel side and the advice map read.

  • Transaction kernel: the output stack is now [OUTPUT_NOTES_COMMITMENT, ACCOUNT_UPDATE_COMMITMENT, CODE_PATCH_COMMITMENT, LOGS_EXPIRATION_COMMITMENT].
    • The code patch commitment needs a full word and the stack had no room left, so the expiration block number is now hashed together with the logs commitment, and the preimage is stored in the advice map.
    • CODE_PATCH_COMMITMENT is EMPTY_WORD for now.
  • Transaction ID: the ID now commits to the code patch commitment (see below). TransactionHeader carries the commitment so that it can recompute the ID.

Why the transaction ID commits to the code patch

  • The patch is a public effect of the transaction: it adds entries to the code tree and the code registry. Without it, two transactions with different effects would share an ID, which breaks the "identical if and only if they have the same ID" property of TransactionId. The reference block is not in the ID, but it is a precondition, not an effect.
  • Two transactions can have the same account transition and notes but a different patch. For example, against an old reference block a procedure is not yet in the code tree, so the transaction must create it. Against a newer block, the same procedure is a dependency. Different advice data for created procedures has the same result.
  • Batches, blocks and the mempool deduplicate transactions by ID. Without the patch in the ID, a node could drop a transaction as a duplicate even though it registers different code, and clients that track transactions by ID could not tell which code was registered. This is not a double-inclusion risk: the empty-transaction rule requires each transaction to change the account or consume a note, so only one of two transactions with the same ID can be included.
  • The cost is negligible: the hash input grows from 20 to 24 elements, which is the same number of permutations at a rate of 8.

Part of #4006

@PhilippGackstatter
PhilippGackstatter marked this pull request as ready for review October 23, 2026 08:08

@partylikeits1983 partylikeits1983 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@mmagician mmagician left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines +185 to +198
# The transaction outputs occupy the top 16 elements, so the padding below them cannot be
# reached directly. Save the output notes commitment in a local to bring the padding up to the
# top four words, one word at a time.
loc_storew_le.OUTPUT_NOTES_COMMITMENT_LOC dropw
# => [ACCOUNT_UPDATE_COMMITMENT, CODE_PATCH_COMMITMENT, LOGS_EXPIRATION_COMMITMENT, pad(16)]

repeat.3
movupw.3 dropw
end
# => [OUTPUT_NOTES_COMMITMENT, ACCOUNT_UPDATE_COMMITMENT, LOGS_COMMITMENT, tx_expiration_block_num, pad(3)]
# => [ACCOUNT_UPDATE_COMMITMENT, CODE_PATCH_COMMITMENT, LOGS_EXPIRATION_COMMITMENT, pad(4)]

# replace the last padding word with the output notes commitment
movupw.3 loc_loadw_le.OUTPUT_NOTES_COMMITMENT_LOC
# => [OUTPUT_NOTES_COMMITMENT, ACCOUNT_UPDATE_COMMITMENT, CODE_PATCH_COMMITMENT, LOGS_EXPIRATION_COMMITMENT]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever

padw
# => [CODE_PATCH_COMMITMENT, LOGS_EXPIRATION_COMMITMENT, ACCOUNT_UPDATE_COMMITMENT]

# place the account update commitment above the code patch commitment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?


# truncate the stack
repeat.13 movup.13 drop end
exec.sys::truncate_stack

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually would truncate_stack not work in crates/miden-protocol/asm/kernels/transaction/bin/main.masm instead of saving one word to locals and then moving and dropping the words?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants