Skip to content

feat: Refactor block types for signatures and deferred proving#2012

Merged
sergerad merged 62 commits intonextfrom
sergerad-signed-block
Nov 23, 2025
Merged

feat: Refactor block types for signatures and deferred proving#2012
sergerad merged 62 commits intonextfrom
sergerad-signed-block

Conversation

@sergerad
Copy link
Contributor

@sergerad sergerad commented Oct 22, 2025

Context

Relates to #2009.

We are modifying the block proving flow in 0xMiden/node#1316.

Blocks will now transition from proposed->signed->proven states. The types in miden-base need to reflect these states and their transitions.

This PR introduces the initial changes required for the refactor. Future work will have to modify the BlockHeader further so that it no longer has proof_commitment field for example.

Changes

  • Add BlockBody and BlockProof structs.
  • Separate out BlockHeader construction from fns responsible for creating ProvenBlock.
  • Add miden-lib/src/blocks module with functionality to create block body and header from ProposedBlock.
  • Move unit tests and rename ProvenBlockError to ProposedBlockError.
  • Update local prover stub APIs for proving.

Copy link
Collaborator

@mmagician mmagician left a comment

Choose a reason for hiding this comment

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

LGTM

@bobbinth
Copy link
Contributor

Without having looked at the code (and so could be off here), I would consider doing this as a staged approach:

  1. Introduce new structure without updating the BlockHeader struct first. This would avoid the need to modify the MASM code at this stage.
  2. Update the BlockHeader struct - first to use dummy values for public key and signature. This would require updating the MASM code too (though changes should be pretty small).
  3. Implement the actual logic for block signing and public key consistency.

@sergerad sergerad force-pushed the sergerad-signed-block branch 2 times, most recently from d6fe7df to 6789fa6 Compare October 29, 2025 19:51
@sergerad sergerad force-pushed the sergerad-signed-block branch from 6789fa6 to ee8ee24 Compare October 29, 2025 19:57
@sergerad sergerad requested a review from bobbinth November 10, 2025 05:24
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Thank you! Looks good! I left a few more comments inline.

Also, let's add a changelog entry and take this PR out of the draft mode (draft mode means it is not ready for review yet).

@sergerad sergerad marked this pull request as ready for review November 10, 2025 06:10
@sergerad sergerad changed the title feat: Add Block Signing feat: Refactor block types for signatures and deferred proving Nov 10, 2025
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left a few more comments inline.

Comment on lines +18 to +20
pub fn build_block(
proposed_block: ProposedBlock,
) -> Result<(BlockHeader, BlockBody), ProposedBlockError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

In the next PR we'll probably add the signature parameter to this function (to include it in the block header).

@sergerad sergerad requested a review from bobbinth November 11, 2025 21:53
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks good to me.

I would bring back MockChain::prove_block to deduplicate some low-level-ish code.

I'm not sure if the structure of the code is optimal yet, since the entire block flow now requires interacting with various types like ProposedBlock, BlockHeader, BlockBody and ProvenBlock. It might be a bit nicer to have higher level wrapper types that represent the stages that the block goes through, but I think it's not essential for this PR. Once we have done #1563, maybe TransactionKernel will be accessible in a better way and allow us to refactor build_block to an inherent method on some higher-level *Block type.

Comment on lines 516 to 522
/// Mock-proves a proposed block into a proven block and returns it.
pub fn prove_block(&self, proposed_block: ProposedBlock) -> ProvenBlock {
let (header, body) = construct_block(proposed_block).unwrap();
let signed_block = SignedBlock::new_unchecked(header, body);
LocalBlockProver::new(0).prove_dummy(signed_block)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I would add this back as:

/// Mock-proves a proposed block into a proven block and returns it.
pub fn prove_block(&self, proposed_block: ProposedBlock) -> anyhow::Result<ProvenBlock> {
    let (header, body) = build_block(proposed_block.clone())?;
    let inputs = self.get_block_inputs(proposed_block.batches().as_slice())?;
    let block_proof = LocalBlockProver::new(MIN_PROOF_SECURITY_LEVEL).prove_dummy(
        proposed_block.batches(),
        header.clone(),
        inputs,
    )?;
    Ok(ProvenBlock::new_unchecked(header, body, block_proof))
}

and use this to replace this code block in crates/miden-testing/src/kernel_tests/block/proven_block_success.rs. This requires changing prove_dummy to take a reference to batches, but I don't think it should really need owned OrderedBatches in the future anyway.

I think we should try to avoid using ProvenBlock::new_unchecked in tests as it doesn't ensure any kind of consistency and reviewing the correctness of all the calls to it is hard. I think it indicates we're missing an easy to use API that we can call from tests. Ideally, we'd have just one or two places where ProvenBlock::new_unchecked is used and the function in which it is used ensures that it is used correctly and safely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have removed all the unnecessary ones and replaced with prove_block calls

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left just one small comment inline. Once @PhilippGackstatter's comments are addressed, this should be good to merge.

@bobbinth
Copy link
Contributor

I'm not sure if the structure of the code is optimal yet, since the entire block flow now requires interacting with various types like ProposedBlock, BlockHeader, BlockBody and ProvenBlock. It might be a bit nicer to have higher level wrapper types that represent the stages that the block goes through, but I think it's not essential for this PR. Once we have done #1563, maybe TransactionKernel will be accessible in a better way and allow us to refactor build_block to an inherent method on some higher-level *Block type.

Agreed - I think we'll revisit some of this post #1563.

@sergerad sergerad force-pushed the sergerad-signed-block branch from 0732fa2 to 1598277 Compare November 23, 2025 16:31
@sergerad sergerad merged commit 8136935 into next Nov 23, 2025
17 checks passed
@sergerad sergerad deleted the sergerad-signed-block branch November 23, 2025 16:42
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.

5 participants