From b1078f80f9ad0c2a3409321c47754d91ad410d62 Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:21:33 +0500 Subject: [PATCH 1/4] fix: don't copy note's metadata (#593) --- miden-tx/tests/integration/scripts/faucet.rs | 2 +- objects/src/transaction/outputs.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/miden-tx/tests/integration/scripts/faucet.rs b/miden-tx/tests/integration/scripts/faucet.rs index 9f20cddcc..24af7882c 100644 --- a/miden-tx/tests/integration/scripts/faucet.rs +++ b/miden-tx/tests/integration/scripts/faucet.rs @@ -95,7 +95,7 @@ fn prove_faucet_contract_mint_fungible_asset_succeeds() { assert_eq!(created_note.id(), id); assert_eq!( created_note.metadata(), - NoteMetadata::new(faucet_account.id(), NoteType::OffChain, tag, ZERO).unwrap() + &NoteMetadata::new(faucet_account.id(), NoteType::OffChain, tag, ZERO).unwrap() ); } diff --git a/objects/src/transaction/outputs.rs b/objects/src/transaction/outputs.rs index 8f731c1b1..2a7cbc5ba 100644 --- a/objects/src/transaction/outputs.rs +++ b/objects/src/transaction/outputs.rs @@ -181,10 +181,10 @@ impl OutputNote { } /// Note's metadata. - pub fn metadata(&self) -> NoteMetadata { + pub fn metadata(&self) -> &NoteMetadata { match self { - OutputNote::Public(note) => *note.metadata(), - OutputNote::Private(note) => *note.metadata(), + OutputNote::Public(note) => note.metadata(), + OutputNote::Private(note) => note.metadata(), } } } From b2aa9aa76643e60bf7c48968d95cab1e24059359 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Date: Thu, 11 Apr 2024 12:12:19 -0700 Subject: [PATCH 2/4] feat: add more conversions for note type (#597) --- objects/src/notes/note_type.rs | 49 +++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/objects/src/notes/note_type.rs b/objects/src/notes/note_type.rs index 903a63608..18eb48040 100644 --- a/objects/src/notes/note_type.rs +++ b/objects/src/notes/note_type.rs @@ -28,27 +28,64 @@ pub enum NoteType { Public = PUBLIC, } +// CONVERSIONS FROM NOTE TYPE +// ================================================================================================ + impl From for Felt { fn from(id: NoteType) -> Self { Felt::new(id as u64) } } -impl TryFrom for NoteType { +// CONVERSIONS INTO NOTE TYPE +// ================================================================================================ + +impl TryFrom for NoteType { type Error = NoteError; - fn try_from(value: Felt) -> Result { - let value = value.as_int(); - let note_type: u8 = value.try_into().map_err(|_| NoteError::InvalidNoteTypeValue(value))?; - match note_type { + fn try_from(value: u8) -> Result { + match value { OFF_CHAIN => Ok(NoteType::OffChain), ENCRYPTED => Ok(NoteType::Encrypted), PUBLIC => Ok(NoteType::Public), - _ => Err(NoteError::InvalidNoteTypeValue(value)), + _ => Err(NoteError::InvalidNoteTypeValue(value.into())), } } } +impl TryFrom for NoteType { + type Error = NoteError; + + fn try_from(value: u16) -> Result { + Self::try_from(value as u64) + } +} + +impl TryFrom for NoteType { + type Error = NoteError; + + fn try_from(value: u32) -> Result { + Self::try_from(value as u64) + } +} + +impl TryFrom for NoteType { + type Error = NoteError; + + fn try_from(value: u64) -> Result { + let value: u8 = value.try_into().map_err(|_| NoteError::InvalidNoteTypeValue(value))?; + value.try_into() + } +} + +impl TryFrom for NoteType { + type Error = NoteError; + + fn try_from(value: Felt) -> Result { + value.as_int().try_into() + } +} + // SERIALIZATION // ================================================================================================ From 03b16d4e71645395fc53f68ca6a1705cc8d54dc4 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:00:09 -0700 Subject: [PATCH 3/4] fix: use different key for un-padded note inputs (#598) --- miden-tx/src/host/mod.rs | 3 ++- objects/src/notes/inputs.rs | 18 ++++++++++++++++-- objects/src/transaction/tx_args.rs | 16 ++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/miden-tx/src/host/mod.rs b/miden-tx/src/host/mod.rs index cf7c44d3f..c87dda485 100644 --- a/miden-tx/src/host/mod.rs +++ b/miden-tx/src/host/mod.rs @@ -100,9 +100,10 @@ impl TransactionHost { return Err(TransactionKernelError::MalformedRecipientData(data.to_vec())); } let inputs_hash = Digest::new([data[0], data[1], data[2], data[3]]); + let inputs_key = NoteInputs::commitment_to_key(inputs_hash); let script_hash = Digest::new([data[4], data[5], data[6], data[7]]); let serial_num = [data[8], data[9], data[10], data[11]]; - let input_els = self.adv_provider.get_mapped_values(&inputs_hash); + let input_els = self.adv_provider.get_mapped_values(&inputs_key); let script_data = self.adv_provider.get_mapped_values(&script_hash).unwrap_or(&[]); let inputs = NoteInputs::new(input_els.map(|e| e.to_vec()).unwrap_or_default()) diff --git a/objects/src/notes/inputs.rs b/objects/src/notes/inputs.rs index f8b35f2b1..7428e5408 100644 --- a/objects/src/notes/inputs.rs +++ b/objects/src/notes/inputs.rs @@ -2,9 +2,9 @@ use alloc::vec::Vec; use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, Digest, Felt, Hasher, NoteError, - Serializable, WORD_SIZE, ZERO, + Serializable, Word, WORD_SIZE, ZERO, }; -use crate::MAX_INPUTS_PER_NOTE; +use crate::{MAX_INPUTS_PER_NOTE, ONE}; // NOTE INPUTS // ================================================================================================ @@ -79,6 +79,20 @@ impl NoteInputs { pub fn to_vec(&self) -> Vec { self.values.to_vec() } + + // UTILITIES + // -------------------------------------------------------------------------------------------- + + /// Returns the key under which the raw (un-padded inputs) are located in the advice map. + /// + /// TODO: eventually, this should go away. for now we need it because note inputs for input + /// notes are padded, while note inputs for expected output notes are note. switching to a + /// different padding scheme (e.g., RPX) would eliminate the need to have two different keys. + pub fn commitment_to_key(commitment: Digest) -> Digest { + let mut key: Word = commitment.into(); + key[3] += ONE; + key.into() + } } impl PartialEq for NoteInputs { diff --git a/objects/src/transaction/tx_args.rs b/objects/src/transaction/tx_args.rs index 0a34a5d5f..c18d4d537 100644 --- a/objects/src/transaction/tx_args.rs +++ b/objects/src/transaction/tx_args.rs @@ -5,7 +5,7 @@ use vm_processor::AdviceMap; use super::{Digest, Felt, Word}; use crate::{ assembly::{Assembler, AssemblyContext, ProgramAst}, - notes::{Note, NoteId}, + notes::{Note, NoteId, NoteInputs}, vm::CodeBlock, TransactionScriptError, }; @@ -71,9 +71,10 @@ impl TransactionArgs { /// /// The map is extended with the following keys: /// - /// - recipient |-> recipient details (inputs_hash, script_hash, serial_num) - /// - intputs_hash |-> inputs - /// - script_hash |-> script + /// - recipient |-> recipient details (inputs_hash, script_hash, serial_num). + /// - inputs_key |-> inputs, where inputs_key is computed by taking note inputs commitment and + /// adding ONE to its most significant element. + /// - script_hash |-> script. /// pub fn add_expected_output_note(&mut self, note: &Note) { let recipient = note.recipient(); @@ -81,8 +82,10 @@ impl TransactionArgs { let script = note.script(); let script_encoded: Vec = script.into(); + let inputs_key = NoteInputs::commitment_to_key(inputs.commitment()); + self.advice_map.insert(recipient.digest(), recipient.to_elements()); - self.advice_map.insert(inputs.commitment(), inputs.to_padded_values()); + self.advice_map.insert(inputs_key, inputs.to_vec()); self.advice_map.insert(script.hash(), script_encoded); } @@ -91,7 +94,8 @@ impl TransactionArgs { /// The map is extended with the following keys: /// /// - recipient |-> recipient details (inputs_hash, script_hash, serial_num) - /// - intputs_hash |-> inputs + /// - inputs_key |-> inputs, where inputs_key is computed by taking note inputs commitment and + /// adding ONE to its most significant element. /// - script_hash |-> script /// pub fn extend_expected_output_notes(&mut self, notes: T) From 04073052172bd9168e467d3344aa76902b44960a Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 11 Apr 2024 14:10:48 -0700 Subject: [PATCH 4/4] chore: update changelog and increment crate versions to v0.2.1 --- CHANGELOG.md | 8 +++++++- Cargo.lock | 8 ++++---- miden-lib/Cargo.toml | 2 +- objects/Cargo.toml | 2 +- objects/src/notes/inputs.rs | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13a6e5514..cc9fd8670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog -## 0.2.0 +## 0.2.1 (2024-04-12) + +* [BREAKING] Return a reference to `NoteMetadata` from output notes (#593). +* Add more type conversions for `NoteType` (#597). +* Fix note input padding for expected output notes (#598). + +## 0.2.0 (2024-04-11) * [BREAKING] Implement support for public accounts (#481, #485, #538). * [BREAKING] Implement support for public notes (#515, #540, #572). diff --git a/Cargo.lock b/Cargo.lock index d9167bdc2..a677785fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,9 +518,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "f08474e32172238f2827bd160c67871cdb2801430f65c3979184dc362e3ca118" dependencies = [ "libc", ] @@ -629,7 +629,7 @@ dependencies = [ [[package]] name = "miden-lib" -version = "0.2.0" +version = "0.2.1" dependencies = [ "miden-assembly", "miden-mock", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "miden-objects" -version = "0.2.0" +version = "0.2.1" dependencies = [ "criterion", "log", diff --git a/miden-lib/Cargo.toml b/miden-lib/Cargo.toml index da83f860e..20a8ea067 100644 --- a/miden-lib/Cargo.toml +++ b/miden-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miden-lib" -version = "0.2.0" +version = "0.2.1" description = "Standard library of the Miden rollup" categories = ["no-std"] keywords = ["miden", "program", "stdlib", "transaction", "kernel"] diff --git a/objects/Cargo.toml b/objects/Cargo.toml index a43cf97c8..7140a453f 100644 --- a/objects/Cargo.toml +++ b/objects/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miden-objects" -version = "0.2.0" +version = "0.2.1" description = "Core components of the Miden rollup" keywords = ["miden", "objects"] edition.workspace = true diff --git a/objects/src/notes/inputs.rs b/objects/src/notes/inputs.rs index 7428e5408..ae58e74d9 100644 --- a/objects/src/notes/inputs.rs +++ b/objects/src/notes/inputs.rs @@ -86,7 +86,7 @@ impl NoteInputs { /// Returns the key under which the raw (un-padded inputs) are located in the advice map. /// /// TODO: eventually, this should go away. for now we need it because note inputs for input - /// notes are padded, while note inputs for expected output notes are note. switching to a + /// notes are padded, while note inputs for expected output notes are not. switching to a /// different padding scheme (e.g., RPX) would eliminate the need to have two different keys. pub fn commitment_to_key(commitment: Digest) -> Digest { let mut key: Word = commitment.into();