Skip to content
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

feat: missing BlockNumber s #1080

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
- Added tracing to the `miden-tx-prover` CLI (#1014).
- Added metrics to the `miden-tx-prover` proxy (#1017).
- Implemented `to_hex` for `AccountIdPrefix` and `epoch_block_num` for `BlockHeader` (#1039).
- Add `BlockNumber` struct (#1043).
- Introduce `AccountIdBuilder` to simplify `AccountId` generation in tests (#1045).
- Introduced `AccountComponentTemplate` with TOML serialization and templating (#1015, #1027).
- [BREAKING] Updated the names and values of the kernel procedure offsets and corresponding kernel procedures (#1037).
Expand All @@ -33,6 +32,7 @@
- Made `BasicFungibleFaucet::MAX_DECIMALS` public (#1063).
- [BREAKING] Removed `miden-tx-prover` crate and created `miden-proving-service` and `miden-remote-provers` (#1047).
- Deduplicate `masm` procedures across kernel and miden lib to a shared `util` module (#1070).
- [BREAKING] Added `BlockNumber` struct (#1043, #1080).

## 0.6.2 (2024-11-20)

Expand Down
17 changes: 10 additions & 7 deletions miden-lib/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use alloc::{string::ToString, sync::Arc, vec::Vec};
use miden_objects::{
accounts::{AccountCode, AccountHeader, AccountId, AccountStorageHeader},
assembly::{Assembler, DefaultSourceManager, KernelLibrary},
block::BlockNumber,
crypto::merkle::{MerkleError, MerklePath},
transaction::{
OutputNote, OutputNotes, TransactionArgs, TransactionInputs, TransactionOutputs,
Expand Down Expand Up @@ -220,7 +221,7 @@ impl TransactionKernel {
pub fn build_output_stack(
final_acct_hash: Digest,
output_notes_hash: Digest,
expiration_block_num: u32,
expiration_block_num: BlockNumber,
) -> StackOutputs {
let mut outputs: Vec<Felt> = Vec::with_capacity(9);
outputs.push(Felt::from(expiration_block_num));
Expand Down Expand Up @@ -252,7 +253,7 @@ impl TransactionKernel {
/// - Overflow addresses are not empty.
pub fn parse_output_stack(
stack: &StackOutputs,
) -> Result<(Digest, Digest, u32), TransactionOutputError> {
) -> Result<(Digest, Digest, BlockNumber), TransactionOutputError> {
let output_notes_hash = stack
.get_stack_word(OUTPUT_NOTES_COMMITMENT_WORD_IDX * 4)
.expect("first word missing")
Expand All @@ -267,11 +268,13 @@ impl TransactionKernel {
.get_stack_item(EXPIRATION_BLOCK_ELEMENT_IDX)
.expect("element on index 8 missing");

let expiration_block_num = u32::try_from(expiration_block_num.as_int()).map_err(|_| {
TransactionOutputError::OutputStackInvalid(
"Expiration block number should be smaller than u32::MAX".into(),
)
})?;
let expiration_block_num = u32::try_from(expiration_block_num.as_int())
.map_err(|_| {
TransactionOutputError::OutputStackInvalid(
"Expiration block number should be smaller than u32::MAX".into(),
)
})?
.into();

if stack.get_stack_word(12).expect("fourth word missing") != EMPTY_WORD {
return Err(TransactionOutputError::OutputStackInvalid(
Expand Down
2 changes: 1 addition & 1 deletion miden-tx/src/tests/kernel_tests/test_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ fn test_build_note_metadata() {
sender,
NoteType::Private,
NoteTag::from_account_id(receiver, NoteExecutionMode::Local).unwrap(),
NoteExecutionHint::after_block(500).unwrap(),
NoteExecutionHint::after_block(500.into()).unwrap(),
Felt::try_from(1u64 << 63).unwrap(),
)
.unwrap();
Expand Down
8 changes: 4 additions & 4 deletions miden-tx/src/tests/kernel_tests/test_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn test_create_note() {
",
recipient = prepare_word(&recipient),
PUBLIC_NOTE = NoteType::Public as u8,
note_execution_hint = Felt::from(NoteExecutionHint::after_block(23).unwrap()),
note_execution_hint = Felt::from(NoteExecutionHint::after_block(23.into()).unwrap()),
tag = tag,
);

Expand All @@ -104,7 +104,7 @@ fn test_create_note() {
account_id,
NoteType::Public,
tag,
NoteExecutionHint::after_block(23).unwrap(),
NoteExecutionHint::after_block(23.into()).unwrap(),
Felt::new(27),
)
.unwrap()
Expand Down Expand Up @@ -242,7 +242,7 @@ fn test_get_output_notes_commitment() {
tx_context.tx_inputs().account().id(),
NoteType::Public,
output_tag_2,
NoteExecutionHint::after_block(123).unwrap(),
NoteExecutionHint::after_block(123.into()).unwrap(),
ZERO,
)
.unwrap();
Expand Down Expand Up @@ -631,7 +631,7 @@ fn test_build_recipient_hash() {
output_serial_no = prepare_word(&output_serial_no),
PUBLIC_NOTE = NoteType::Public as u8,
tag = tag,
execution_hint = Felt::from(NoteExecutionHint::after_block(2).unwrap()),
execution_hint = Felt::from(NoteExecutionHint::after_block(2.into()).unwrap()),
aux = aux,
);

Expand Down
4 changes: 2 additions & 2 deletions objects/src/block/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl BlockHeader {
kernel_root,
proof_hash,
timestamp,
block_num.as_u32(),
block_num,
);

// The sub hash is merged with the note_root - hash(sub_hash, note_root) to produce the
Expand Down Expand Up @@ -204,7 +204,7 @@ impl BlockHeader {
kernel_root: Digest,
proof_hash: Digest,
timestamp: u32,
block_num: u32,
block_num: BlockNumber,
) -> Digest {
let mut elements: Vec<Felt> = Vec::with_capacity(32);
elements.extend_from_slice(prev_hash.as_elements());
Expand Down
55 changes: 28 additions & 27 deletions objects/src/notes/execution_hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use vm_core::Felt;

use crate::NoteError;
use crate::{block::BlockNumber, NoteError};

/// Specifies the conditions under which a note is ready to be consumed.
/// These conditions are meant to be encoded in the note script as well.
Expand Down Expand Up @@ -79,7 +79,7 @@ impl NoteExecutionHint {
/// # Errors
///
/// Returns an error if `block_num` is equal to [`u32::MAX`].
pub fn after_block(block_num: u32) -> Result<Self, NoteError> {
pub fn after_block(block_num: BlockNumber) -> Result<Self, NoteError> {
AfterBlockNumber::new(block_num)
.map(|block_number| NoteExecutionHint::AfterBlock { block_num: block_number })
}
Expand All @@ -104,7 +104,7 @@ impl NoteExecutionHint {
}
Ok(NoteExecutionHint::Always)
},
Self::AFTER_BLOCK_TAG => NoteExecutionHint::after_block(payload),
Self::AFTER_BLOCK_TAG => NoteExecutionHint::after_block(payload.into()),
Self::ON_BLOCK_SLOT_TAG => {
let remainder = (payload >> 24 & 0xff) as u8;
if remainder != 0 {
Expand All @@ -128,7 +128,8 @@ impl NoteExecutionHint {
/// - `None` if we don't know whether the note can be consumed.
/// - `Some(true)` if the note is consumable for the given `block_num`
/// - `Some(false)` if the note is not consumable for the given `block_num`
pub fn can_be_consumed(&self, block_num: u32) -> Option<bool> {
pub fn can_be_consumed(&self, block_num: BlockNumber) -> Option<bool> {
let block_num = block_num.as_u32();
match self {
NoteExecutionHint::None => None,
NoteExecutionHint::Always => Some(true),
Expand Down Expand Up @@ -213,7 +214,7 @@ impl From<NoteExecutionHint> for u64 {
///
/// Used for the [`NoteExecutionHint::AfterBlock`] variant where this constraint is needed.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AfterBlockNumber(u32);
pub struct AfterBlockNumber(BlockNumber);

impl AfterBlockNumber {
/// Creates a new [`AfterBlockNumber`] from the given `block_number`.
Expand All @@ -222,8 +223,8 @@ impl AfterBlockNumber {
///
/// Returns an error if:
/// - `block_number` is equal to `u32::MAX`.
pub fn new(block_number: u32) -> Result<Self, NoteError> {
if block_number == u32::MAX {
pub fn new(block_number: BlockNumber) -> Result<Self, NoteError> {
if block_number.as_u32() == u32::MAX {
Err(NoteError::NoteExecutionHintAfterBlockCannotBeU32Max)
} else {
Ok(Self(block_number))
Expand All @@ -232,21 +233,21 @@ impl AfterBlockNumber {

/// Returns the block number as a `u32`.
pub fn as_u32(&self) -> u32 {
self.0
self.0.as_u32()
}
}

impl From<AfterBlockNumber> for u32 {
fn from(block_number: AfterBlockNumber) -> Self {
block_number.0
block_number.0.as_u32()
}
}

impl TryFrom<u32> for AfterBlockNumber {
type Error = NoteError;

fn try_from(block_number: u32) -> Result<Self, Self::Error> {
Self::new(block_number)
Self::new(block_number.into())
}
}

Expand All @@ -269,7 +270,7 @@ mod tests {
fn test_serialization_round_trip() {
assert_hint_serde(NoteExecutionHint::None);
assert_hint_serde(NoteExecutionHint::Always);
assert_hint_serde(NoteExecutionHint::after_block(15).unwrap());
assert_hint_serde(NoteExecutionHint::after_block(15.into()).unwrap());
assert_hint_serde(NoteExecutionHint::OnBlockSlot {
round_len: 9,
slot_len: 12,
Expand All @@ -279,7 +280,7 @@ mod tests {

#[test]
fn test_encode_round_trip() {
let hint = NoteExecutionHint::after_block(15).unwrap();
let hint = NoteExecutionHint::after_block(15.into()).unwrap();
let hint_int: u64 = hint.into();
let decoded_hint: NoteExecutionHint = hint_int.try_into().unwrap();
assert_eq!(hint, decoded_hint);
Expand All @@ -300,25 +301,25 @@ mod tests {
#[test]
fn test_can_be_consumed() {
let none = NoteExecutionHint::none();
assert!(none.can_be_consumed(100).is_none());
assert!(none.can_be_consumed(100.into()).is_none());

let always = NoteExecutionHint::always();
assert!(always.can_be_consumed(100).unwrap());
assert!(always.can_be_consumed(100.into()).unwrap());

let after_block = NoteExecutionHint::after_block(12345).unwrap();
assert!(!after_block.can_be_consumed(12344).unwrap());
assert!(after_block.can_be_consumed(12345).unwrap());
let after_block = NoteExecutionHint::after_block(12345.into()).unwrap();
assert!(!after_block.can_be_consumed(12344.into()).unwrap());
assert!(after_block.can_be_consumed(12345.into()).unwrap());

let on_block_slot = NoteExecutionHint::on_block_slot(10, 7, 1);
assert!(!on_block_slot.can_be_consumed(127).unwrap()); // Block 127 is not in the slot 128..255
assert!(on_block_slot.can_be_consumed(128).unwrap()); // Block 128 is in the slot 128..255
assert!(on_block_slot.can_be_consumed(255).unwrap()); // Block 255 is in the slot 128..255
assert!(!on_block_slot.can_be_consumed(256).unwrap()); // Block 256 is not in the slot 128..255
assert!(on_block_slot.can_be_consumed(1152).unwrap()); // Block 1152 is in the slot 1152..1279
assert!(on_block_slot.can_be_consumed(1279).unwrap()); // Block 1279 is in the slot 1152..1279
assert!(on_block_slot.can_be_consumed(2176).unwrap()); // Block 2176 is in the slot 2176..2303
assert!(!on_block_slot.can_be_consumed(2175).unwrap()); // Block 1279 is in the slot
// 2176..2303
assert!(!on_block_slot.can_be_consumed(127.into()).unwrap()); // Block 127 is not in the slot 128..255
assert!(on_block_slot.can_be_consumed(128.into()).unwrap()); // Block 128 is in the slot 128..255
assert!(on_block_slot.can_be_consumed(255.into()).unwrap()); // Block 255 is in the slot 128..255
assert!(!on_block_slot.can_be_consumed(256.into()).unwrap()); // Block 256 is not in the slot 128..255
assert!(on_block_slot.can_be_consumed(1152.into()).unwrap()); // Block 1152 is in the slot 1152..1279
assert!(on_block_slot.can_be_consumed(1279.into()).unwrap()); // Block 1279 is in the slot 1152..1279
assert!(on_block_slot.can_be_consumed(2176.into()).unwrap()); // Block 2176 is in the slot 2176..2303
assert!(!on_block_slot.can_be_consumed(2175.into()).unwrap()); // Block 1279 is in the slot
// 2176..2303
}

#[test]
Expand All @@ -335,7 +336,7 @@ mod tests {
#[test]
fn test_after_block_fails_on_u32_max() {
assert_matches!(
NoteExecutionHint::after_block(u32::MAX).unwrap_err(),
NoteExecutionHint::after_block(u32::MAX.into()).unwrap_err(),
NoteError::NoteExecutionHintAfterBlockCannotBeU32Max
);
}
Expand Down
15 changes: 10 additions & 5 deletions objects/src/notes/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use vm_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use vm_processor::DeserializationError;

use super::{Note, NoteDetails, NoteId, NoteInclusionProof, NoteTag};
use crate::block::BlockNumber;

// NOTE FILE
// ================================================================================================
Expand All @@ -20,7 +21,7 @@ pub enum NoteFile {
/// treated as a hint.
NoteDetails {
details: NoteDetails,
after_block_num: u32,
after_block_num: BlockNumber,
tag: Option<NoteTag>,
},
/// The note has been recorded on chain.
Expand All @@ -29,7 +30,11 @@ pub enum NoteFile {

impl From<NoteDetails> for NoteFile {
fn from(details: NoteDetails) -> Self {
NoteFile::NoteDetails { details, after_block_num: 0, tag: None }
NoteFile::NoteDetails {
details,
after_block_num: 0.into(),
tag: None,
}
}
}

Expand Down Expand Up @@ -77,7 +82,7 @@ impl Deserializable for NoteFile {
0 => Ok(NoteFile::NoteId(NoteId::read_from(source)?)),
1 => {
let details = NoteDetails::read_from(source)?;
let after_block_num = u32::read_from(source)?;
let after_block_num = BlockNumber::read_from(source)?;
let tag = Option::<NoteTag>::read_from(source)?;
Ok(NoteFile::NoteDetails { details, after_block_num, tag })
},
Expand Down Expand Up @@ -175,7 +180,7 @@ mod tests {
let note = create_example_note();
let file = NoteFile::NoteDetails {
details: note.details.clone(),
after_block_num: 456,
after_block_num: 456.into(),
tag: Some(NoteTag::from(123)),
};
let mut buffer = Vec::new();
Expand All @@ -186,7 +191,7 @@ mod tests {
match file_copy {
NoteFile::NoteDetails { details, after_block_num, tag } => {
assert_eq!(details, note.details);
assert_eq!(after_block_num, 456);
assert_eq!(after_block_num, 456.into());
assert_eq!(tag, Some(NoteTag::from(123)));
},
_ => panic!("Invalid note file variant"),
Expand Down
2 changes: 1 addition & 1 deletion objects/src/notes/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ mod tests {
NoteExecutionHint::always(),
NoteExecutionHint::none(),
NoteExecutionHint::on_block_slot(10, 11, 12),
NoteExecutionHint::after_block(u32::MAX - 1).unwrap(),
NoteExecutionHint::after_block((u32::MAX - 1).into()).unwrap(),
] {
let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux).unwrap();
NoteMetadata::read_from_bytes(&metadata.to_bytes())
Expand Down
3 changes: 2 additions & 1 deletion objects/src/transaction/outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use vm_processor::DeserializationError;

use crate::{
accounts::AccountHeader,
block::BlockNumber,
notes::{compute_note_hash, Note, NoteAssets, NoteHeader, NoteId, NoteMetadata, PartialNote},
Digest, Felt, Hasher, TransactionOutputError, Word, MAX_OUTPUT_NOTES_PER_TX,
};
Expand All @@ -20,7 +21,7 @@ pub struct TransactionOutputs {
/// Set of output notes created by the transaction.
pub output_notes: OutputNotes,
/// Defines up to which block the transaction is considered valid.
pub expiration_block_num: u32,
pub expiration_block_num: BlockNumber,
}

// OUTPUT NOTES
Expand Down
Loading
Loading