Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
- [BREAKING] Removed redundant outputs from kernel procedures: `note::write_assets_to_memory`, `active_note::get_assets`, `input_note::get_assets`, `output_note::get_assets`, `active_note::get_storage`, and `faucet::mint` no longer return values identical to their inputs ([#2523](https://github.com/0xMiden/protocol/issues/2523)).
- Added PSWAP (partial swap) note for decentralized partial-fill asset exchange with remainder note re-creation ([#2636](https://github.com/0xMiden/protocol/pull/2636)).
- [BREAKING] Add support for multiple attachments per note ([#2795](https://github.com/0xMiden/protocol/pull/2795), [#2871](https://github.com/0xMiden/protocol/pull/2871)).
- [BREAKING] Collapsed `NoteMetadataHeader` into `NoteMetadata` and reshaped the public note-construction API ([#2876](https://github.com/0xMiden/protocol/pull/2876)):
- Added `Note::builder()` (via `bon`) as the canonical way to construct a `Note`. `sender` and `recipient` are required; `assets`, `attachments`, `note_tag`, and `note_type` default.
- Removed `Note::new`, `Note::with_attachments`, `NoteMetadata::new`, `NoteMetadata::with_tag`, `NoteMetadata::with_attachments`, and `NoteMetadata::set_tag`. `NoteMetadata::from_parts` is the only remaining public constructor.
- Removed `NoteMetadataHeader` (and `NoteHeader::metadata_header()` / `into_metadata_header()`); `NoteHeader` now holds a `NoteMetadata` directly with `metadata()` / `into_metadata()` accessors.
- Renamed the test helper `miden_standards::testing::note::NoteBuilder` to `TestNoteBuilder`.
- `OutputNoteBuilder` and `TransactionEvent::NoteBeforeCreated` now carry `sender` / `note_type` / `note_tag` instead of a stub `NoteMetadata`.
- `TransactionKernelError::PublicNoteMissingDetails` is now a struct variant with `sender`, `note_type`, `note_tag`, and `recipient_digest` fields.
- [BREAKING] Renamed `set_attachment` to `add_attachment`, `set_word_attachment` to `add_word_attachment`, and `set_array_attachment` to `add_array_attachment` in `miden::protocol::output_note` ([#2795](https://github.com/0xMiden/protocol/pull/2795), [#2849](https://github.com/0xMiden/protocol/pull/2849)).
- [BREAKING] Replaced `metadata_into_attachment_info` with `metadata_into_attachment_schemes` in `miden::protocol::note` ([#2795](https://github.com/0xMiden/protocol/pull/2795), [#2849](https://github.com/0xMiden/protocol/pull/2849)).
- [BREAKING] All `get_metadata` procedures (`active_note`, `input_note`, `output_note`) no longer return attachments ([#2795](https://github.com/0xMiden/protocol/pull/2795), [#2849](https://github.com/0xMiden/protocol/pull/2849)).
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions bin/bench-note-checker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use miden_protocol::testing::account_id::{
ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE,
ACCOUNT_ID_SENDER,
};
use miden_standards::testing::note::NoteBuilder;
use miden_standards::testing::note::TestNoteBuilder;
use miden_testing::{Auth, MockChain, TxContextInput};
use miden_tx::auth::UnreachableAuth;
use miden_tx::{NoteConsumptionChecker, TransactionExecutor};
Expand Down Expand Up @@ -82,7 +82,7 @@ pub fn setup_mixed_notes_benchmark(config: MixedNotesConfig) -> anyhow::Result<M

for i in 0..config.failing_note_count {
let mut rng = RandomCoin::new([i as u32, 0, 0, 0].into());
let failing_note = NoteBuilder::new(sender, &mut rng)
let failing_note = TestNoteBuilder::new(sender, &mut rng)
.code("@note_script pub proc main push.0 div end") // Division by zero - will fail.
.build()?;
failing_notes.push(failing_note);
Expand Down
11 changes: 7 additions & 4 deletions crates/miden-agglayer/src/b2agg_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use miden_protocol::note::{
NoteAssets,
NoteAttachment,
NoteAttachments,
NoteMetadata,
NoteRecipient,
NoteScript,
NoteScriptRoot,
Expand Down Expand Up @@ -104,11 +103,15 @@ impl B2AggNote {
})?;
let attachments = NoteAttachments::from(NoteAttachment::from(attachment));

let metadata = NoteMetadata::new(sender_account_id, NoteType::Public);

let recipient = NoteRecipient::new(rng.draw_word(), Self::script(), note_storage);

Ok(Note::with_attachments(assets, metadata, recipient, attachments))
Ok(Note::builder()
.sender(sender_account_id)
.recipient(recipient)
.assets(assets)
.attachments(attachments)
.note_type(NoteType::Public)
.build())
}
}

Expand Down
12 changes: 6 additions & 6 deletions crates/miden-agglayer/src/claim_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ use miden_protocol::crypto::rand::FeltRng;
use miden_protocol::errors::NoteError;
use miden_protocol::note::{
Note,
NoteAssets,
NoteAttachment,
NoteAttachments,
NoteMetadata,
NoteRecipient,
NoteStorage,
NoteType,
Expand Down Expand Up @@ -194,10 +192,12 @@ pub fn create_claim_note<R: FeltRng>(
.map_err(|e| NoteError::other(e.to_string()))?;
let attachments = NoteAttachments::from(NoteAttachment::from(attachment));

let metadata = NoteMetadata::new(sender_account_id, NoteType::Public);

let recipient = NoteRecipient::new(rng.draw_word(), claim_script(), note_storage);
let assets = NoteAssets::new(vec![])?;

Ok(Note::with_attachments(assets, metadata, recipient, attachments))
Ok(Note::builder()
.sender(sender_account_id)
.recipient(recipient)
.attachments(attachments)
.note_type(NoteType::Public)
.build())
}
14 changes: 6 additions & 8 deletions crates/miden-agglayer/src/config_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
extern crate alloc;

use alloc::string::ToString;
use alloc::vec;
use alloc::vec::Vec;

use miden_assembly::Library;
Expand All @@ -17,10 +16,8 @@ use miden_protocol::crypto::rand::FeltRng;
use miden_protocol::errors::NoteError;
use miden_protocol::note::{
Note,
NoteAssets,
NoteAttachment,
NoteAttachments,
NoteMetadata,
NoteRecipient,
NoteScript,
NoteScriptRoot,
Expand Down Expand Up @@ -117,11 +114,12 @@ impl ConfigAggBridgeNote {
let attachment = NetworkAccountTarget::new(target_account_id, NoteExecutionHint::Always)
.map_err(|e| NoteError::other(e.to_string()))?;
let attachments = NoteAttachments::from(NoteAttachment::from(attachment));
let metadata = NoteMetadata::new(sender_account_id, NoteType::Public);

// CONFIG_AGG_BRIDGE notes don't carry assets
let assets = NoteAssets::new(vec![])?;

Ok(Note::with_attachments(assets, metadata, recipient, attachments))
Ok(Note::builder()
.sender(sender_account_id)
.recipient(recipient)
.attachments(attachments)
.note_type(NoteType::Public)
.build())
}
}
14 changes: 6 additions & 8 deletions crates/miden-agglayer/src/update_ger_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
extern crate alloc;

use alloc::string::ToString;
use alloc::vec;

use miden_assembly::Library;
use miden_assembly::serde::Deserializable;
Expand All @@ -15,10 +14,8 @@ use miden_protocol::crypto::rand::FeltRng;
use miden_protocol::errors::NoteError;
use miden_protocol::note::{
Note,
NoteAssets,
NoteAttachment,
NoteAttachments,
NoteMetadata,
NoteRecipient,
NoteScript,
NoteScriptRoot,
Expand Down Expand Up @@ -104,11 +101,12 @@ impl UpdateGerNote {
let attachment = NetworkAccountTarget::new(target_account_id, NoteExecutionHint::Always)
.map_err(|e| NoteError::other(e.to_string()))?;
let attachments = NoteAttachments::from(NoteAttachment::from(attachment));
let metadata = NoteMetadata::new(sender_account_id, NoteType::Public);

// UPDATE_GER notes don't carry assets
let assets = NoteAssets::new(vec![])?;

Ok(Note::with_attachments(assets, metadata, recipient, attachments))
Ok(Note::builder()
.sender(sender_account_id)
.recipient(recipient)
.attachments(attachments)
.note_type(NoteType::Public)
.build())
}
}
1 change: 1 addition & 0 deletions crates/miden-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ miden-verifier = { workspace = true }

# External dependencies
bech32 = { default-features = false, features = ["alloc"], version = "0.11" }
bon = { workspace = true }
rand = { workspace = true }
rand_xoshiro = { default-features = false, optional = true, version = "0.7" }
semver = { features = ["serde"], version = "1.0" }
Expand Down
6 changes: 3 additions & 3 deletions crates/miden-protocol/src/batch/note_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::vec::Vec;

use crate::crypto::merkle::MerkleError;
use crate::crypto::merkle::smt::{LeafIndex, SimpleSmt};
use crate::note::{NoteId, NoteMetadataHeader, compute_note_commitment};
use crate::note::{NoteId, NoteMetadata, compute_note_commitment};
use crate::utils::serde::{
ByteReader,
ByteWriter,
Expand All @@ -26,11 +26,11 @@ impl BatchNoteTree {
/// Returns an error if the number of entries exceeds the maximum tree capacity, that is
/// 2^{depth}.
pub fn with_contiguous_leaves<'a>(
entries: impl IntoIterator<Item = (NoteId, &'a NoteMetadataHeader)>,
entries: impl IntoIterator<Item = (NoteId, &'a NoteMetadata)>,
) -> Result<Self, MerkleError> {
let leaves = entries
.into_iter()
.map(|(note_id, metadata_header)| compute_note_commitment(note_id, metadata_header));
.map(|(note_id, metadata)| compute_note_commitment(note_id, metadata));

SimpleSmt::with_contiguous_leaves(leaves).map(Self)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/miden-protocol/src/block/block_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl BlockBody {
pub fn compute_block_note_tree(&self) -> BlockNoteTree {
let entries = self
.output_notes()
.map(|(note_index, note)| (note_index, note.id(), note.metadata_header()));
.map(|(note_index, note)| (note_index, note.id(), note.metadata()));

// SAFETY: We only construct block bodies that:
// - do not contain duplicates
Expand Down
11 changes: 4 additions & 7 deletions crates/miden-protocol/src/block/note_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use miden_crypto::merkle::SparseMerklePath;
use crate::batch::BatchNoteTree;
use crate::crypto::merkle::MerkleError;
use crate::crypto::merkle::smt::{LeafIndex, SimpleSmt};
use crate::note::{NoteId, NoteMetadataHeader, compute_note_commitment};
use crate::note::{NoteId, NoteMetadata, compute_note_commitment};
use crate::utils::serde::{
ByteReader,
ByteWriter,
Expand Down Expand Up @@ -44,13 +44,10 @@ impl BlockNoteTree {
/// - The number of entries exceeds the maximum notes tree capacity, that is 2^16.
/// - The provided entries contain multiple values for the same key.
pub fn with_entries<'a>(
entries: impl IntoIterator<Item = (BlockNoteIndex, NoteId, &'a NoteMetadataHeader)>,
entries: impl IntoIterator<Item = (BlockNoteIndex, NoteId, &'a NoteMetadata)>,
) -> Result<Self, MerkleError> {
let leaves = entries.into_iter().map(|(index, note_id, metadata_header)| {
(
index.leaf_index_value() as u64,
compute_note_commitment(note_id, metadata_header),
)
let leaves = entries.into_iter().map(|(index, note_id, metadata)| {
(index.leaf_index_value() as u64, compute_note_commitment(note_id, metadata))
});

SimpleSmt::with_leaves(leaves).map(Self)
Expand Down
2 changes: 1 addition & 1 deletion crates/miden-protocol/src/block/proposed_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ impl ProposedBlock {
"max batches in block and max notes in batches should be enforced",
),
note.id(),
note.metadata_header(),
note.metadata(),
)
})
});
Expand Down
10 changes: 7 additions & 3 deletions crates/miden-protocol/src/note/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ mod tests {
NoteAssets,
NoteFile,
NoteInclusionProof,
NoteMetadata,
NoteRecipient,
NoteScript,
NoteStorage,
Expand All @@ -175,9 +174,14 @@ mod tests {
let recipient = NoteRecipient::new(serial_num, script, note_storage);

let asset = Asset::Fungible(FungibleAsset::new(faucet, 100).unwrap());
let metadata = NoteMetadata::new(faucet, NoteType::Public).with_tag(NoteTag::from(123));

Note::new(NoteAssets::new(vec![asset]).unwrap(), metadata, recipient)
Note::builder()
.sender(faucet)
.recipient(recipient)
.assets(NoteAssets::new(vec![asset]).unwrap())
.note_tag(NoteTag::from(123))
.note_type(NoteType::Public)
.build()
}

#[test]
Expand Down
41 changes: 15 additions & 26 deletions crates/miden-protocol/src/note/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use super::{
DeserializationError,
NoteId,
NoteMetadata,
NoteMetadataHeader,
Serializable,
Word,
};
Expand All @@ -16,17 +15,17 @@ use crate::Hasher;

/// Holds the strictly required, public information of a note.
///
/// See [NoteId] and [NoteMetadataHeader] for additional details.
/// See [NoteId] and [NoteMetadata] for additional details.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoteHeader {
note_id: NoteId,
metadata_header: NoteMetadataHeader,
metadata: NoteMetadata,
}

impl NoteHeader {
/// Returns a new [NoteHeader] instantiated from the specified note ID and metadata header.
pub fn new(note_id: NoteId, metadata_header: NoteMetadataHeader) -> Self {
Self { note_id, metadata_header }
/// Returns a new [NoteHeader] instantiated from the specified note ID and metadata.
pub fn new(note_id: NoteId, metadata: NoteMetadata) -> Self {
Self { note_id, metadata }
}

/// Returns the note's identifier.
Expand All @@ -36,24 +35,14 @@ impl NoteHeader {
self.note_id
}

/// Returns the note's metadata.
/// Returns a reference to the note's metadata.
pub fn metadata(&self) -> &NoteMetadata {
self.metadata_header.metadata()
}

/// Returns a reference to the note's metadata header.
pub fn metadata_header(&self) -> &NoteMetadataHeader {
&self.metadata_header
&self.metadata
}

/// Consumes self and returns the note header's metadata.
pub fn into_metadata(self) -> NoteMetadata {
self.metadata_header.into_metadata()
}

/// Consumes self and returns the note header's metadata header.
pub fn into_metadata_header(self) -> NoteMetadataHeader {
self.metadata_header
self.metadata
}

/// Returns a commitment to the note and its metadata.
Expand All @@ -63,7 +52,7 @@ impl NoteHeader {
/// This value is used primarily for authenticating notes consumed when they are consumed
/// in a transaction.
pub fn to_commitment(&self) -> Word {
compute_note_commitment(self.id(), &self.metadata_header)
compute_note_commitment(self.id(), &self.metadata)
}
}

Expand All @@ -76,8 +65,8 @@ impl NoteHeader {
///
/// This value is used primarily for authenticating notes consumed when they are consumed
/// in a transaction.
pub fn compute_note_commitment(id: NoteId, metadata_header: &NoteMetadataHeader) -> Word {
Hasher::merge(&[id.as_word(), metadata_header.to_commitment()])
pub fn compute_note_commitment(id: NoteId, metadata: &NoteMetadata) -> Word {
Hasher::merge(&[id.as_word(), metadata.to_commitment()])
}

// SERIALIZATION
Expand All @@ -86,19 +75,19 @@ pub fn compute_note_commitment(id: NoteId, metadata_header: &NoteMetadataHeader)
impl Serializable for NoteHeader {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.note_id.write_into(target);
self.metadata_header.write_into(target);
self.metadata.write_into(target);
}

fn get_size_hint(&self) -> usize {
self.note_id.get_size_hint() + self.metadata_header.get_size_hint()
self.note_id.get_size_hint() + self.metadata.get_size_hint()
}
}

impl Deserializable for NoteHeader {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let note_id = NoteId::read_from(source)?;
let metadata_header = NoteMetadataHeader::read_from(source)?;
let metadata = NoteMetadata::read_from(source)?;

Ok(Self::new(note_id, metadata_header))
Ok(Self::new(note_id, metadata))
}
}
Loading
Loading