Skip to content

Commit

Permalink
feat: missing BlockNumber s
Browse files Browse the repository at this point in the history
  • Loading branch information
SantiagoPittella committed Jan 17, 2025
1 parent 3326306 commit 673f508
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 53 deletions.
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
11 changes: 6 additions & 5 deletions objects/src/transaction/proven_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use miden_verifier::ExecutionProof;
use super::{InputNote, ToInputNoteCommitments};
use crate::{
accounts::delta::AccountUpdateDetails,
block::BlockNumber,
notes::NoteHeader,
transaction::{
AccountId, Digest, InputNotes, Nullifier, OutputNote, OutputNotes, TransactionId,
Expand Down Expand Up @@ -37,7 +38,7 @@ pub struct ProvenTransaction {
block_ref: Digest,

/// The block number by which the transaction will expire, as defined by the executed scripts.
expiration_block_num: u32,
expiration_block_num: BlockNumber,

/// A STARK proof that attests to the correct execution of the transaction.
proof: ExecutionProof,
Expand Down Expand Up @@ -85,7 +86,7 @@ impl ProvenTransaction {
}

/// Returns the block number at which the transaction will expire.
pub fn expiration_block_num(&self) -> u32 {
pub fn expiration_block_num(&self) -> BlockNumber {
self.expiration_block_num
}

Expand Down Expand Up @@ -166,7 +167,7 @@ impl Deserializable for ProvenTransaction {
let output_notes = OutputNotes::read_from(source)?;

let block_ref = Digest::read_from(source)?;
let expiration_block_num = u32::read_from(source)?;
let expiration_block_num = BlockNumber::read_from(source)?;
let proof = ExecutionProof::read_from(source)?;

let id = TransactionId::new(
Expand Down Expand Up @@ -220,7 +221,7 @@ pub struct ProvenTransactionBuilder {
block_ref: Digest,

/// The block number by which the transaction will expire, as defined by the executed scripts.
expiration_block_num: u32,
expiration_block_num: BlockNumber,

/// A STARK proof that attests to the correct execution of the transaction.
proof: ExecutionProof,
Expand All @@ -236,7 +237,7 @@ impl ProvenTransactionBuilder {
initial_account_hash: Digest,
final_account_hash: Digest,
block_ref: Digest,
expiration_block_num: u32,
expiration_block_num: BlockNumber,
proof: ExecutionProof,
) -> Self {
Self {
Expand Down

0 comments on commit 673f508

Please sign in to comment.