diff --git a/CHANGELOG.md b/CHANGELOG.md index fdcf0e48a..7d356e327 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Implemented `to_hex` for `AccountIdPrefix` and `epoch_block_num` for `BlockHeader` (#1039). - Introduce `AccountIdBuilder` to simplify `AccountId` generation in tests (#1045). - Introduced `AccountComponentTemplate` with TOML serialization and templating (#1015, #1027). +- Add BlockNumber struct (feat: added BlockNumber struct #1043). ## 0.6.2 (2024-11-20) diff --git a/miden-lib/src/transaction/inputs.rs b/miden-lib/src/transaction/inputs.rs index d62a16725..b4f73bf4b 100644 --- a/miden-lib/src/transaction/inputs.rs +++ b/miden-lib/src/transaction/inputs.rs @@ -79,7 +79,7 @@ fn build_advice_stack( inputs.extend_stack(header.kernel_root()); inputs.extend_stack(header.proof_hash()); inputs.extend_stack([ - header.block_num().into(), + header.block_num().as_u32().into(), header.version().into(), header.timestamp().into(), ZERO, @@ -282,7 +282,7 @@ fn add_input_notes_to_advice_inputs( .inner_nodes(proof.location().node_index_in_block().into(), note.hash()) .unwrap(), ); - note_data.push(proof.location().block_num().into()); + note_data.push(proof.location().block_num().as_u32().into()); note_data.extend(note_block_header.sub_hash()); note_data.extend(note_block_header.note_root()); note_data.push(proof.location().node_index_in_block().into()); diff --git a/miden-tx/src/executor/data_store.rs b/miden-tx/src/executor/data_store.rs index 83a5aae29..989dd64f0 100644 --- a/miden-tx/src/executor/data_store.rs +++ b/miden-tx/src/executor/data_store.rs @@ -1,7 +1,9 @@ #[cfg(feature = "async")] use alloc::boxed::Box; -use miden_objects::{accounts::AccountId, notes::NoteId, transaction::TransactionInputs}; +use miden_objects::{ + accounts::AccountId, block::BlockNumber, notes::NoteId, transaction::TransactionInputs, +}; use winter_maybe_async::*; use crate::DataStoreError; @@ -32,7 +34,7 @@ pub trait DataStore { fn get_transaction_inputs( &self, account_id: AccountId, - block_ref: u32, + block_ref: BlockNumber, notes: &[NoteId], ) -> Result; } diff --git a/miden-tx/src/executor/mod.rs b/miden-tx/src/executor/mod.rs index 4b477daac..51ad4fbff 100644 --- a/miden-tx/src/executor/mod.rs +++ b/miden-tx/src/executor/mod.rs @@ -4,6 +4,7 @@ use miden_lib::transaction::TransactionKernel; use miden_objects::{ accounts::{AccountCode, AccountId}, assembly::Library, + block::BlockNumber, notes::NoteId, transaction::{ExecutedTransaction, TransactionArgs, TransactionInputs}, vm::StackOutputs, @@ -128,7 +129,7 @@ impl TransactionExecutor { pub fn execute_transaction( &self, account_id: AccountId, - block_ref: u32, + block_ref: BlockNumber, notes: &[NoteId], tx_args: TransactionArgs, ) -> Result { diff --git a/miden-tx/src/testing/mock_chain/mod.rs b/miden-tx/src/testing/mock_chain/mod.rs index 34a3f8a78..c30c8b65f 100644 --- a/miden-tx/src/testing/mock_chain/mod.rs +++ b/miden-tx/src/testing/mock_chain/mod.rs @@ -12,8 +12,8 @@ use miden_objects::{ }, assets::{Asset, FungibleAsset, TokenSymbol}, block::{ - block_num_from_epoch, compute_tx_hash, Block, BlockAccountUpdate, BlockNoteIndex, - BlockNoteTree, NoteBatch, + compute_tx_hash, Block, BlockAccountUpdate, BlockNoteIndex, BlockNoteTree, BlockNumber, + NoteBatch, }, crypto::{ dsa::rpo_falcon512::SecretKey, @@ -592,8 +592,8 @@ impl MockChain { let note_block_num = input_note.location().unwrap().block_num(); if note_block_num != block.header().block_num() { block_headers_map.insert( - note_block_num, - self.blocks.get(note_block_num as usize).unwrap().header(), + note_block_num.as_u32(), + self.blocks.get(note_block_num.as_u32() as usize).unwrap().header(), ); } input_notes.push(input_note); @@ -602,13 +602,13 @@ impl MockChain { // If the account is new, add the anchor block's header from which the account ID is derived // to the MMR. if account.is_new() { - let epoch_block_num = block_num_from_epoch(account.id().anchor_epoch()); + let epoch_block_num = BlockNumber::from_epoch(account.id().anchor_epoch()); // The reference block of the transaction is added to the MMR in // prologue::process_chain_data so we can skip adding it to the block headers here. if epoch_block_num != block.header().block_num() { block_headers_map.insert( - epoch_block_num, - self.blocks.get(epoch_block_num as usize).unwrap().header(), + epoch_block_num.as_u32(), + self.blocks.get(epoch_block_num.as_u32() as usize).unwrap().header(), ); } } @@ -637,7 +637,7 @@ impl MockChain { /// This will also make all the objects currently pending available for use. /// If `block_num` is `Some(number)`, blocks will be generated up to `number`. pub fn seal_block(&mut self, block_num: Option) -> Block { - let next_block_num = self.blocks.last().map_or(0, |b| b.header().block_num() + 1); + let next_block_num = self.blocks.last().map_or(0, |b| b.header().block_num().as_u32() + 1); let target_block_num = block_num.unwrap_or(next_block_num); if target_block_num < next_block_num { @@ -724,7 +724,7 @@ impl MockChain { BlockNoteIndex::new(batch_index, note_index).unwrap(); let note_path = notes_tree.get_note_path(block_note_index); let note_inclusion_proof = NoteInclusionProof::new( - block.header().block_num(), + block.header().block_num().as_u32(), block_note_index.leaf_index_value(), note_path, ) diff --git a/miden-tx/src/testing/tx_context/mod.rs b/miden-tx/src/testing/tx_context/mod.rs index e3cd17e9c..657f33080 100644 --- a/miden-tx/src/testing/tx_context/mod.rs +++ b/miden-tx/src/testing/tx_context/mod.rs @@ -7,6 +7,7 @@ use miden_lib::transaction::TransactionKernel; use miden_objects::{ accounts::{Account, AccountCode, AccountId}, assembly::Assembler, + block::BlockNumber, notes::{Note, NoteId}, transaction::{ExecutedTransaction, InputNote, InputNotes, TransactionArgs, TransactionInputs}, }; @@ -139,7 +140,7 @@ impl DataStore for TransactionInputs { fn get_transaction_inputs( &self, account_id: AccountId, - block_num: u32, + block_num: BlockNumber, notes: &[NoteId], ) -> Result { assert_eq!(account_id, self.account().id()); diff --git a/miden-tx/src/tests/kernel_tests/test_epilogue.rs b/miden-tx/src/tests/kernel_tests/test_epilogue.rs index b294624c6..412b12fc6 100644 --- a/miden-tx/src/tests/kernel_tests/test_epilogue.rs +++ b/miden-tx/src/tests/kernel_tests/test_epilogue.rs @@ -244,7 +244,8 @@ fn test_block_expiration_height_monotonically_decreases() { // Expiry block should be set to transaction's block + the stored expiration delta // (which can only decrease, not increase) - let expected_expiry = v1.min(v2) + tx_context.tx_inputs().block_header().block_num() as u64; + let expected_expiry = + v1.min(v2) + tx_context.tx_inputs().block_header().block_num().as_u32() as u64; assert_eq!(process.get_stack_item(8).as_int(), expected_expiry); } } diff --git a/miden-tx/src/tests/kernel_tests/test_prologue.rs b/miden-tx/src/tests/kernel_tests/test_prologue.rs index 24411caa1..c73e9d860 100644 --- a/miden-tx/src/tests/kernel_tests/test_prologue.rs +++ b/miden-tx/src/tests/kernel_tests/test_prologue.rs @@ -200,7 +200,7 @@ fn block_data_memory_assertions(process: &Process, inputs: &Transactio assert_eq!( read_root_mem_value(process, BLOCK_METADATA_PTR)[BLOCK_NUMBER_IDX], - inputs.tx_inputs().block_header().block_num().into(), + inputs.tx_inputs().block_header().block_num().as_u32().into(), "The block number should be stored at BLOCK_METADATA_PTR[BLOCK_NUMBER_IDX]" ); diff --git a/objects/src/accounts/account_id.rs b/objects/src/accounts/account_id.rs index 9d3565f2a..e74d930b3 100644 --- a/objects/src/accounts/account_id.rs +++ b/objects/src/accounts/account_id.rs @@ -308,7 +308,7 @@ impl From for AccountIdVersion { /// hashes to the user's ID can claim the assets sent to the user's ID. Adding the anchor /// block hash to ID generation process makes this attack practically impossible. /// -/// [epoch_len_exp]: crate::block::BlockHeader::EPOCH_LENGTH_EXPONENT +/// [epoch_len_exp]: crate::block::BlockNumber::EPOCH_LENGTH_EXPONENT #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct AccountId { prefix: Felt, diff --git a/objects/src/accounts/account_id_anchor.rs b/objects/src/accounts/account_id_anchor.rs index ef5d3fcd5..3c289a856 100644 --- a/objects/src/accounts/account_id_anchor.rs +++ b/objects/src/accounts/account_id_anchor.rs @@ -1,4 +1,4 @@ -use crate::{block::block_epoch_from_number, AccountError, BlockHeader, Digest, EMPTY_WORD}; +use crate::{block::BlockNumber, AccountError, BlockHeader, Digest, EMPTY_WORD}; // ACCOUNT ID ANCHOR // ================================================================================================ @@ -12,8 +12,8 @@ use crate::{block::block_epoch_from_number, AccountError, BlockHeader, Digest, E /// # Constraints /// /// This type enforces the following constraints. -/// - The `anchor_block_number` % 2^[`BlockHeader::EPOCH_LENGTH_EXPONENT`] must be zero. In other -/// words, the block number must a multiple of 2^[`BlockHeader::EPOCH_LENGTH_EXPONENT`]. +/// - The `anchor_block_number` % 2^[`BlockNumber::EPOCH_LENGTH_EXPONENT`] must be zero. In other +/// words, the block number must a multiple of 2^[`BlockNumber::EPOCH_LENGTH_EXPONENT`]. /// - The epoch derived from the `anchor_block_number` must be strictly less than [`u16::MAX`]. #[derive(Debug, Clone, Copy)] pub struct AccountIdAnchor { @@ -48,14 +48,18 @@ impl AccountIdAnchor { /// /// Returns an error if any of the anchor constraints are not met. See the [type /// documentation](AccountIdAnchor) for details. - pub fn new(anchor_block_number: u32, anchor_block_hash: Digest) -> Result { - if anchor_block_number & 0x0000_ffff != 0 { + pub fn new( + anchor_block_number: impl Into, + anchor_block_hash: Digest, + ) -> Result { + let anchor_block_number = anchor_block_number.into(); + if anchor_block_number.as_u32() & 0x0000_ffff != 0 { return Err(AccountError::AssumptionViolated(format!( "TODO: Make proper error: anchor block must be an epoch block, i.e. its block number must be a multiple of 2^{}", - BlockHeader::EPOCH_LENGTH_EXPONENT))); + BlockNumber::EPOCH_LENGTH_EXPONENT))); } - let anchor_epoch = block_epoch_from_number(anchor_block_number); + let anchor_epoch = anchor_block_number.block_epoch(); if anchor_epoch == u16::MAX { return Err(AccountError::AssumptionViolated(format!( diff --git a/objects/src/block/header.rs b/objects/src/block/header.rs index 7ae216b26..acf377d67 100644 --- a/objects/src/block/header.rs +++ b/objects/src/block/header.rs @@ -1,4 +1,5 @@ use alloc::vec::Vec; +use core::fmt; use super::{Digest, Felt, Hasher, ZERO}; use crate::utils::serde::{ @@ -29,7 +30,7 @@ use crate::utils::serde::{ pub struct BlockHeader { version: u32, prev_hash: Digest, - block_num: u32, + block_num: BlockNumber, chain_root: Digest, account_root: Digest, nullifier_root: Digest, @@ -43,13 +44,6 @@ pub struct BlockHeader { } impl BlockHeader { - /// The length of an epoch expressed as a power of two. `2^(EPOCH_LENGTH_EXPONENT)` is the - /// number of blocks in an epoch. - /// - /// The epoch of a block can be obtained by shifting the block number to the right by this - /// exponent. - pub const EPOCH_LENGTH_EXPONENT: u8 = 16; - /// Creates a new block header. #[allow(clippy::too_many_arguments)] pub fn new( @@ -88,7 +82,7 @@ impl BlockHeader { Self { version, prev_hash, - block_num, + block_num: block_num.into(), chain_root, account_root, nullifier_root, @@ -129,15 +123,15 @@ impl BlockHeader { } /// Returns the block number. - pub fn block_num(&self) -> u32 { + pub fn block_num(&self) -> BlockNumber { self.block_num } /// Returns the epoch to which this block belongs. /// - /// This is the block number shifted right by [`Self::EPOCH_LENGTH_EXPONENT`]. + /// This is the block number shifted right by [`BlockNumber::EPOCH_LENGTH_EXPONENT`]. pub fn block_epoch(&self) -> u16 { - block_epoch_from_number(self.block_num) + self.block_num.block_epoch() } /// Returns the chain root. @@ -187,8 +181,8 @@ impl BlockHeader { } /// Returns the block number of the epoch block to which this block belongs. - pub fn epoch_block_num(&self) -> u32 { - block_num_from_epoch(self.block_epoch()) + pub fn epoch_block_num(&self) -> BlockNumber { + BlockNumber::from_epoch(self.block_epoch()) } // HELPERS @@ -275,17 +269,58 @@ impl Deserializable for BlockHeader { } } -// UTILITIES -// ================================================================================================ +/// BLOCK NUMBER -/// Returns the block number of the epoch block for the given `epoch`. -pub const fn block_num_from_epoch(epoch: u16) -> u32 { - (epoch as u32) << BlockHeader::EPOCH_LENGTH_EXPONENT +/// A convenience wrapper around a `u32` representing the number of a block. +/// +/// Each block has a unique number and block numbers increase monotonically by `1`. +#[derive(Debug, Eq, PartialEq, Copy, Clone, PartialOrd, Ord, Hash)] +pub struct BlockNumber(u32); + +impl Serializable for BlockNumber { + fn write_into(&self, target: &mut W) { + target.write_u32(self.0); + } + + fn get_size_hint(&self) -> usize { + core::mem::size_of::() + } } -/// Returns the epoch of the given block number. -pub const fn block_epoch_from_number(block_number: u32) -> u16 { - (block_number >> BlockHeader::EPOCH_LENGTH_EXPONENT) as u16 +impl From for BlockNumber { + fn from(value: u32) -> Self { + BlockNumber(value) + } +} + +impl fmt::Display for BlockNumber { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl BlockNumber { + /// The length of an epoch expressed as a power of two. `2^(EPOCH_LENGTH_EXPONENT)` is the + /// number of blocks in an epoch. + /// + /// The epoch of a block can be obtained by shifting the block number to the right by this + /// exponent. + pub const EPOCH_LENGTH_EXPONENT: u8 = 16; + + /// Creates the [`BlockNumber`] corresponding to the epoch block for the provided `epoch`. + pub const fn from_epoch(epoch: u16) -> BlockNumber { + BlockNumber((epoch as u32) << BlockNumber::EPOCH_LENGTH_EXPONENT) + } + + /// Returns the epoch to which this block number belongs. + pub const fn block_epoch(&self) -> u16 { + (self.0 >> BlockNumber::EPOCH_LENGTH_EXPONENT) as u16 + } + + /// Returns the block number as a `u32`. + pub fn as_u32(&self) -> u32 { + self.0 + } } #[cfg(test)] diff --git a/objects/src/block/mod.rs b/objects/src/block/mod.rs index d915dea8a..8e616879e 100644 --- a/objects/src/block/mod.rs +++ b/objects/src/block/mod.rs @@ -6,7 +6,7 @@ use super::{ }; mod header; -pub use header::{block_epoch_from_number, block_num_from_epoch, BlockHeader}; +pub use header::{BlockHeader, BlockNumber}; mod note_tree; pub use note_tree::{BlockNoteIndex, BlockNoteTree}; diff --git a/objects/src/errors.rs b/objects/src/errors.rs index 783776e90..e02286bd8 100644 --- a/objects/src/errors.rs +++ b/objects/src/errors.rs @@ -17,7 +17,7 @@ use super::{ }; use crate::{ accounts::{AccountCode, AccountIdPrefix, AccountStorage, AccountType, StoragePlaceholder}, - block::block_num_from_epoch, + block::BlockNumber, notes::{NoteAssets, NoteExecutionHint, NoteTag, NoteType, Nullifier}, ACCOUNT_UPDATE_MAX_SIZE, MAX_INPUTS_PER_NOTE, MAX_INPUT_NOTES_PER_TX, MAX_OUTPUT_NOTES_PER_TX, }; @@ -279,16 +279,19 @@ pub enum ChainMmrError { } impl ChainMmrError { - pub fn block_num_too_big(chain_length: usize, block_num: u32) -> Self { - Self::BlockNumTooBig { chain_length, block_num } + pub fn block_num_too_big(chain_length: usize, block_num: BlockNumber) -> Self { + Self::BlockNumTooBig { + chain_length, + block_num: block_num.as_u32(), + } } - pub fn duplicate_block(block_num: u32) -> Self { - Self::DuplicateBlock { block_num } + pub fn duplicate_block(block_num: BlockNumber) -> Self { + Self::DuplicateBlock { block_num: block_num.as_u32() } } - pub fn untracked_block(block_num: u32) -> Self { - Self::UntrackedBlock { block_num } + pub fn untracked_block(block_num: BlockNumber) -> Self { + Self::UntrackedBlock { block_num: block_num.as_u32() } } } @@ -312,7 +315,7 @@ pub enum TransactionInputError { AccountSeedProvidedForExistingAccount, #[error( "anchor block header for epoch {0} (block number = {block_number}) must be provided in the chain mmr for the new account", - block_number = block_num_from_epoch(*.0), + block_number = BlockNumber::from_epoch(*.0), )] AnchorBlockHeaderNotProvidedForNewAccount(u16), #[error("transaction input note with nullifier {0} is a duplicate")] diff --git a/objects/src/notes/location.rs b/objects/src/notes/location.rs index 242c269c0..a9a13af29 100644 --- a/objects/src/notes/location.rs +++ b/objects/src/notes/location.rs @@ -1,13 +1,16 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, NoteError, Serializable, }; -use crate::{crypto::merkle::MerklePath, MAX_BATCHES_PER_BLOCK, MAX_OUTPUT_NOTES_PER_BATCH}; +use crate::{ + block::BlockNumber, crypto::merkle::MerklePath, MAX_BATCHES_PER_BLOCK, + MAX_OUTPUT_NOTES_PER_BATCH, +}; /// Contains information about the location of a note. #[derive(Clone, Debug, PartialEq, Eq)] pub struct NoteLocation { /// The block number the note was created in. - block_num: u32, + block_num: BlockNumber, /// The index of the note in the note Merkle tree of the block the note was created in. node_index_in_block: u16, @@ -15,7 +18,7 @@ pub struct NoteLocation { impl NoteLocation { /// Returns the block number the note was created in. - pub fn block_num(&self) -> u32 { + pub fn block_num(&self) -> BlockNumber { self.block_num } @@ -54,7 +57,10 @@ impl NoteInclusionProof { highest_index: HIGHEST_INDEX, }); } - let location = NoteLocation { block_num, node_index_in_block }; + let location = NoteLocation { + block_num: block_num.into(), + node_index_in_block, + }; Ok(Self { location, note_path }) } @@ -79,7 +85,7 @@ impl NoteInclusionProof { impl Serializable for NoteLocation { fn write_into(&self, target: &mut W) { - target.write_u32(self.block_num); + target.write_u32(self.block_num.as_u32()); target.write_u16(self.node_index_in_block); } } @@ -89,7 +95,10 @@ impl Deserializable for NoteLocation { let block_num = source.read_u32()?; let node_index_in_block = source.read_u16()?; - Ok(Self { block_num, node_index_in_block }) + Ok(Self { + block_num: block_num.into(), + node_index_in_block, + }) } } diff --git a/objects/src/transaction/chain_mmr.rs b/objects/src/transaction/chain_mmr.rs index 2519962e1..958317b08 100644 --- a/objects/src/transaction/chain_mmr.rs +++ b/objects/src/transaction/chain_mmr.rs @@ -3,6 +3,7 @@ use alloc::{collections::BTreeMap, vec::Vec}; use vm_core::utils::{Deserializable, Serializable}; use crate::{ + block::BlockNumber, crypto::merkle::{InnerNodeInfo, MmrPeaks, PartialMmr}, BlockHeader, ChainMmrError, }; @@ -26,7 +27,7 @@ pub struct ChainMmr { mmr: PartialMmr, /// A map of block_num |-> block_header for all blocks for which the partial MMR contains /// authentication paths. - blocks: BTreeMap, + blocks: BTreeMap, } impl ChainMmr { @@ -46,7 +47,7 @@ impl ChainMmr { let mut block_map = BTreeMap::new(); for block in blocks.into_iter() { - if block.block_num() as usize >= chain_length { + if block.block_num().as_u32() as usize >= chain_length { return Err(ChainMmrError::block_num_too_big(chain_length, block.block_num())); } @@ -54,7 +55,7 @@ impl ChainMmr { return Err(ChainMmrError::duplicate_block(block.block_num())); } - if !mmr.is_tracked(block.block_num() as usize) { + if !mmr.is_tracked(block.block_num().as_u32() as usize) { return Err(ChainMmrError::untracked_block(block.block_num())); } } @@ -76,13 +77,13 @@ impl ChainMmr { } /// Returns true if the block is present in this chain MMR. - pub fn contains_block(&self, block_num: u32) -> bool { + pub fn contains_block(&self, block_num: BlockNumber) -> bool { self.blocks.contains_key(&block_num) } /// Returns the block header for the specified block, or None if the block is not present in /// this chain MMR. - pub fn get_block(&self, block_num: u32) -> Option<&BlockHeader> { + pub fn get_block(&self, block_num: BlockNumber) -> Option<&BlockHeader> { self.blocks.get(&block_num) } @@ -99,7 +100,7 @@ impl ChainMmr { /// Panics if the `block_header.block_num` is not equal to the current chain length (i.e., the /// provided block header is not the next block in the chain). pub fn add_block(&mut self, block_header: BlockHeader, track: bool) { - assert_eq!(block_header.block_num(), self.chain_length() as u32); + assert_eq!(block_header.block_num().as_u32(), self.chain_length() as u32); self.mmr.add(block_header.hash(), track); } @@ -110,7 +111,9 @@ impl ChainMmr { /// MMR. pub fn inner_nodes(&self) -> impl Iterator + '_ { self.mmr.inner_nodes( - self.blocks.values().map(|block| (block.block_num() as usize, block.hash())), + self.blocks + .values() + .map(|block| (block.block_num().as_u32() as usize, block.hash())), ) } } @@ -149,6 +152,7 @@ mod tests { use super::ChainMmr; use crate::{ alloc::vec::Vec, + block::BlockNumber, crypto::merkle::{Mmr, PartialMmr}, BlockHeader, Digest, }; @@ -158,7 +162,7 @@ mod tests { // create chain MMR with 3 blocks - i.e., 2 peaks let mut mmr = Mmr::default(); for i in 0..3 { - let block_header = int_to_block_header(i); + let block_header = int_to_block_header(i.into()); mmr.add(block_header.hash()); } let partial_mmr: PartialMmr = mmr.peaks().into(); @@ -166,7 +170,7 @@ mod tests { // add a new block to the chain MMR, this reduces the number of peaks to 1 let block_num = 3; - let bock_header = int_to_block_header(block_num); + let bock_header = int_to_block_header(block_num.into()); mmr.add(bock_header.hash()); chain_mmr.add_block(bock_header, true); @@ -177,7 +181,7 @@ mod tests { // add one more block to the chain MMR, the number of peaks is again 2 let block_num = 4; - let bock_header = int_to_block_header(block_num); + let bock_header = int_to_block_header(block_num.into()); mmr.add(bock_header.hash()); chain_mmr.add_block(bock_header, true); @@ -188,7 +192,7 @@ mod tests { // add one more block to the chain MMR, the number of peaks is still 2 let block_num = 5; - let bock_header = int_to_block_header(block_num); + let bock_header = int_to_block_header(block_num.into()); mmr.add(bock_header.hash()); chain_mmr.add_block(bock_header, true); @@ -203,7 +207,7 @@ mod tests { // create chain MMR with 3 blocks - i.e., 2 peaks let mut mmr = Mmr::default(); for i in 0..3 { - let block_header = int_to_block_header(i); + let block_header = int_to_block_header(i.into()); mmr.add(block_header.hash()); } let partial_mmr: PartialMmr = mmr.peaks().into(); @@ -215,11 +219,11 @@ mod tests { assert_eq!(chain_mmr, deserialized); } - fn int_to_block_header(block_num: u32) -> BlockHeader { + fn int_to_block_header(block_num: BlockNumber) -> BlockHeader { BlockHeader::new( 0, Digest::default(), - block_num, + block_num.as_u32(), Digest::default(), Digest::default(), Digest::default(), diff --git a/objects/src/transaction/inputs.rs b/objects/src/transaction/inputs.rs index fc450a4e8..0dbd281d8 100644 --- a/objects/src/transaction/inputs.rs +++ b/objects/src/transaction/inputs.rs @@ -4,7 +4,7 @@ use core::fmt::Debug; use super::{BlockHeader, ChainMmr, Digest, Felt, Hasher, Word}; use crate::{ accounts::{Account, AccountId, AccountIdAnchor}, - block::block_num_from_epoch, + block::BlockNumber, notes::{Note, NoteId, NoteInclusionProof, NoteLocation, Nullifier}, utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}, TransactionInputError, MAX_INPUT_NOTES_PER_TX, @@ -44,9 +44,9 @@ impl TransactionInputs { // check the block_chain and block_header are consistent let block_num = block_header.block_num(); - if block_chain.chain_length() != block_header.block_num() as usize { + if block_chain.chain_length() != block_header.block_num().as_u32() as usize { return Err(TransactionInputError::InconsistentChainLength { - expected: block_header.block_num(), + expected: block_header.block_num().as_u32(), actual: block_chain.chain_length() as u32, }); } @@ -402,7 +402,10 @@ fn validate_is_in_block( .note_path() .verify(note_index, note_hash, &block_header.note_root()) .map_err(|_| { - TransactionInputError::InputNoteNotInBlock(note.id(), proof.location().block_num()) + TransactionInputError::InputNoteNotInBlock( + note.id(), + proof.location().block_num().as_u32(), + ) }) } @@ -477,7 +480,7 @@ pub fn validate_account_seed( ) -> Result<(), TransactionInputError> { match (account.is_new(), account_seed) { (true, Some(seed)) => { - let anchor_block_number = block_num_from_epoch(account.id().anchor_epoch()); + let anchor_block_number = BlockNumber::from_epoch(account.id().anchor_epoch()); let anchor_block_hash = if block_header.block_num() == anchor_block_number { block_header.hash()