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

Moved Block and AccountUpdataData to miden-objects #621

Merged
merged 19 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 0.3.0 (TBD)

* [BREAKING] Removed the transaction script root output from the transaction kernel (#608).
* [BREAKING] Refactored account update details, moved `Block` to `miden-objects` (#618, #621).

## 0.2.1 (2024-04-12)

Expand All @@ -19,7 +20,8 @@
* Improved `ProvenTransaction` serialization (#543).
* Implemented note tree wrapper structs (#560).
* [BREAKING] Migrated to v0.9 version of Miden VM (#567).
* [BREAKING] Added account storage type parameter to `create_basic_wallet` and `create_basic_fungible_faucet` (miden-lib crate only) (#587).
* [BREAKING] Added account storage type parameter to `create_basic_wallet` and `create_basic_fungible_faucet` (miden-lib
crate only) (#587).
* Removed serialization of source locations from account code (#590).

## 0.1.1 (2024-03-07) - `miden-objects` crate only
Expand Down
9 changes: 5 additions & 4 deletions miden-tx/src/prover/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use miden_lib::transaction::{ToTransactionKernelInputs, TransactionKernel};
use miden_objects::{
notes::Nullifier,
transaction::{
AccountDetails, InputNotes, ProvenTransaction, ProvenTransactionBuilder, TransactionWitness,
AccountUpdateDetails, InputNotes, ProvenTransaction, ProvenTransactionBuilder,
TransactionWitness,
},
};
use miden_prover::prove;
Expand Down Expand Up @@ -81,12 +82,12 @@ impl TransactionProver {
.apply_delta(&account_delta)
.map_err(TransactionProverError::InvalidAccountDelta)?;

AccountDetails::Full(account)
AccountUpdateDetails::New(account)
} else {
AccountDetails::Delta(account_delta)
AccountUpdateDetails::Delta(account_delta)
};

builder.account_details(account_details)
builder.account_update_details(account_details)
},
false => builder,
};
Expand Down
4 changes: 2 additions & 2 deletions miden-tx/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ impl TransactionVerifier {
// build stack inputs and outputs
let stack_inputs = TransactionKernel::build_input_stack(
transaction.account_id(),
transaction.initial_account_hash(),
transaction.account_update().init_hash(),
transaction.input_notes().commitment(),
transaction.block_ref(),
);
let stack_outputs = TransactionKernel::build_output_stack(
transaction.final_account_hash(),
transaction.account_update().final_hash(),
transaction.output_notes().commitment(),
);

Expand Down
99 changes: 98 additions & 1 deletion objects/src/block/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,103 @@
use alloc::vec::Vec;

use super::{Digest, Felt, Hasher, ZERO};

mod header;
pub use header::BlockHeader;
mod note_tree;
pub use note_tree::BlockNoteTree;
pub use note_tree::{BlockNoteIndex, BlockNoteTree};

use crate::{
notes::Nullifier,
transaction::{AccountUpdateData, OutputNote},
utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
};

pub type NoteBatch = Vec<OutputNote>;

/// A block in the block chain.
#[derive(Debug, Clone)]
pub struct Block {
/// Block header.
header: BlockHeader,

/// Account updates for the block.
updated_accounts: Vec<AccountUpdateData>,

/// Note batches created in transactions in the block.
created_notes: Vec<NoteBatch>,

/// Nullifiers produced in transactions in the block.
created_nullifiers: Vec<Nullifier>,
//
// TODO: add zk proof
}

impl Block {
/// Creates a new block.
pub const fn new(
header: BlockHeader,
updated_accounts: Vec<AccountUpdateData>,
created_notes: Vec<NoteBatch>,
created_nullifiers: Vec<Nullifier>,
) -> Self {
Self {
header,
updated_accounts,
created_notes,
created_nullifiers,
}
}

/// Returns the block header.
pub fn header(&self) -> BlockHeader {
self.header
}

/// Returns the account updates.
pub fn updated_accounts(&self) -> &Vec<AccountUpdateData> {
&self.updated_accounts
}

/// Returns the note batches.
pub fn created_notes(&self) -> &Vec<NoteBatch> {
&self.created_notes
}

/// Returns the nullifiers.
pub fn created_nullifiers(&self) -> &Vec<Nullifier> {
&self.created_nullifiers
}

/// Returns an iterator over created notes in the block.
pub fn notes(&self) -> impl Iterator<Item = (BlockNoteIndex, &OutputNote)> {
self.created_notes.iter().enumerate().flat_map(|(batch_idx, notes)| {
notes.iter().enumerate().map(move |(note_idx_in_batch, note)| {
(BlockNoteIndex::new(batch_idx, note_idx_in_batch), note)
})
})
}
}

// SERIALIZATION
// ================================================================================================

impl Serializable for Block {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.header.write_into(target);
self.updated_accounts.write_into(target);
self.created_notes.write_into(target);
self.created_nullifiers.write_into(target);
}
}

impl Deserializable for Block {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
Ok(Self {
header: BlockHeader::read_from(source)?,
updated_accounts: <Vec<AccountUpdateData>>::read_from(source)?,
created_notes: <Vec<NoteBatch>>::read_from(source)?,
created_nullifiers: <Vec<Nullifier>>::read_from(source)?,
})
}
}
55 changes: 37 additions & 18 deletions objects/src/block/note_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
/// Wrapper over [SimpleSmt<BLOCK_OUTPUT_NOTES_TREE_DEPTH>] for notes tree.
///
/// Each note is stored as two adjacent leaves: odd leaf for id, even leaf for metadata hash.
/// Id leaf index is calculated as [(batch_idx * MAX_NOTES_PER_BATCH + note_idx_in_batch) * 2].
/// ID's leaf index is calculated as [(batch_idx * MAX_NOTES_PER_BATCH + note_idx_in_batch) * 2].
/// Metadata hash leaf is stored the next after id leaf: [id_index + 1].
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
Expand All @@ -23,7 +23,7 @@ pub struct BlockNoteTree(SimpleSmt<BLOCK_OUTPUT_NOTES_TREE_DEPTH>);
impl BlockNoteTree {
/// Returns a new [BlockNoteTree] instantiated with entries set as specified by the provided entries.
///
/// Entry format: (batch_index, note_index, (note_id, note_metadata)).
/// Entry format: (note_index, note_id, note_metadata).
///
/// All leaves omitted from the entries list are set to [ZERO; 4].
///
Expand All @@ -32,13 +32,12 @@ impl BlockNoteTree {
/// - The number of entries exceeds the maximum notes tree capacity, that is 2^21.
/// - The provided entries contain multiple values for the same key.
pub fn with_entries(
entries: impl IntoIterator<Item = (usize, usize, (RpoDigest, NoteMetadata))>,
entries: impl IntoIterator<Item = (BlockNoteIndex, RpoDigest, NoteMetadata)>,
) -> Result<Self, MerkleError> {
let interleaved =
entries.into_iter().flat_map(|(batch_index, note_index, (note_id, metadata))| {
let id_index = Self::leaf_index(batch_index, note_index);
[(id_index, note_id.into()), (id_index + 1, metadata.into())]
});
let interleaved = entries.into_iter().flat_map(|(index, note_id, metadata)| {
let id_index = Self::leaf_index(index);
[(id_index, note_id.into()), (id_index + 1, metadata.into())]
});

SimpleSmt::with_leaves(interleaved).map(Self)
}
Expand All @@ -51,13 +50,9 @@ impl BlockNoteTree {
/// Returns merkle path for the note with specified batch/note indexes.
///
/// The returned path is to the node which is the parent of both note and note metadata node.
pub fn get_note_path(
&self,
batch_idx: usize,
note_idx_in_batch: usize,
) -> Result<MerklePath, MerkleError> {
pub fn get_note_path(&self, index: BlockNoteIndex) -> Result<MerklePath, MerkleError> {
// get the path to the leaf containing the note (path len = 21)
let leaf_index = LeafIndex::new(Self::leaf_index(batch_idx, note_idx_in_batch))?;
let leaf_index = LeafIndex::new(Self::leaf_index(index))?;

// move up the path by removing the first node, this path now points to the parent of the
// note path
Expand All @@ -67,15 +62,15 @@ impl BlockNoteTree {
}

/// Returns an index to the node which the parent of both the note and note metadata.
pub fn note_index(batch_idx: usize, note_idx_in_batch: usize) -> u64 {
(batch_idx * MAX_NOTES_PER_BATCH + note_idx_in_batch) as u64
pub fn note_index(index: BlockNoteIndex) -> u64 {
(index.batch_idx() * MAX_NOTES_PER_BATCH + index.note_idx_in_batch()) as u64
}

// HELPERS
// --------------------------------------------------------------------------------------------

fn leaf_index(batch_idx: usize, note_idx_in_batch: usize) -> u64 {
Self::note_index(batch_idx, note_idx_in_batch) * 2
fn leaf_index(index: BlockNoteIndex) -> u64 {
Self::note_index(index) * 2
}
}

Expand All @@ -85,6 +80,30 @@ impl Default for BlockNoteTree {
}
}

/// Index of a block note.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BlockNoteIndex {
batch_idx: usize,
note_idx_in_batch: usize,
}

impl BlockNoteIndex {
/// Creates a new [BlockNoteIndex].
pub fn new(batch_idx: usize, note_idx_in_batch: usize) -> Self {
Self { batch_idx, note_idx_in_batch }
}

/// Returns the batch index.
pub fn batch_idx(&self) -> usize {
self.batch_idx
}

/// Returns the note index in the batch.
pub fn note_idx_in_batch(&self) -> usize {
self.note_idx_in_batch
}
}

// SERIALIZATION
// ================================================================================================

Expand Down
Loading
Loading