diff --git a/mock/Cargo.toml b/mock/Cargo.toml index dd6bd7735..d352b25dc 100644 --- a/mock/Cargo.toml +++ b/mock/Cargo.toml @@ -28,6 +28,7 @@ env_logger = { version = "0.11" } hex = "0.4" miden-lib = { path = "../miden-lib" } miden-objects = { path = "../objects" , features = ["serde", "log", "testing"]} +miden-prover = { package = "miden-prover", git = "https://github.com/0xPolygonMiden/miden-vm", branch = "next", default-features = false } miden-test-utils = { package = "miden-test-utils", git = "https://github.com/0xPolygonMiden/miden-vm", branch = "next", default-features = false } postcard = { version = "1.0", features = [ "alloc" ] } rand = { version = "0.8" } diff --git a/mock/src/builders/mod.rs b/mock/src/builders/mod.rs index d2216e06e..a2df68a1b 100644 --- a/mock/src/builders/mod.rs +++ b/mock/src/builders/mod.rs @@ -9,6 +9,7 @@ mod error; mod fungible_asset; mod nonfungible_asset; mod note; +mod tx; // RE-EXPORTS // ================================================================================================ @@ -19,6 +20,7 @@ pub use error::AccountBuilderError; pub use fungible_asset::FungibleAssetBuilder; pub use nonfungible_asset::{NonFungibleAssetBuilder, NonFungibleAssetDetailsBuilder}; pub use note::NoteBuilder; +pub use tx::ProvenTransactionBuilder; pub fn str_to_account_code(source: &str) -> Result { let assembler = TransactionKernel::assembler(); diff --git a/mock/src/builders/tx.rs b/mock/src/builders/tx.rs new file mode 100644 index 000000000..321c1b49a --- /dev/null +++ b/mock/src/builders/tx.rs @@ -0,0 +1,68 @@ +use miden_objects::{ + accounts::AccountId, + notes::{NoteEnvelope, Nullifier}, + transaction::{InputNotes, OutputNotes, ProvenTransaction, ToEnvelope, ToNullifier}, + vm::ExecutionProof, + Digest, +}; +use miden_prover::{HashFunction, StarkProof}; + +/// Builder for an `ProvenTransaction`, the builder allows for a fluent API to construct an account. +/// Each transaction needs a unique builder. +#[derive(Debug, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct ProvenTransactionBuilder { + account_id: AccountId, + note_envelopes: Vec, + nullifiers: Vec, + initial_account_hash: Digest, + final_account_hash: Digest, +} + +impl ProvenTransactionBuilder { + pub fn new( + account_id: AccountId, + initial_account_hash: Digest, + final_account_hash: Digest, + ) -> Self { + Self { + account_id, + initial_account_hash, + final_account_hash, + note_envelopes: Vec::new(), + nullifiers: Vec::new(), + } + } + + pub fn add_note_envelope(mut self, note_envelope: I) -> Self { + self.note_envelopes.push(note_envelope.to_envelope()); + self + } + pub fn add_note_envelopes>( + mut self, + note_envelopes: I, + ) -> Self { + for note_envelope in note_envelopes.into_iter() { + self.note_envelopes.push(note_envelope.to_envelope()); + } + self + } + + pub fn add_nullifier(mut self, nullifier: I) -> Self { + self.nullifiers.push(nullifier.nullifier()); + self + } + + pub fn build(self) -> ProvenTransaction { + ProvenTransaction::new( + self.account_id, + self.initial_account_hash, + self.final_account_hash, + InputNotes::new(self.nullifiers).unwrap(), + OutputNotes::new(self.note_envelopes).unwrap(), + None, + Digest::default(), + ExecutionProof::new(StarkProof::new_dummy(), HashFunction::Blake3_192), + ) + } +} diff --git a/objects/src/notes/envelope.rs b/objects/src/notes/envelope.rs index 77a6efc4a..bad967eac 100644 --- a/objects/src/notes/envelope.rs +++ b/objects/src/notes/envelope.rs @@ -18,6 +18,7 @@ use crate::utils::collections::*; /// - num assets /// - ZERO #[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct NoteEnvelope { note_id: NoteId, note_metadata: NoteMetadata, diff --git a/objects/src/notes/note_id.rs b/objects/src/notes/note_id.rs index fa88ed55c..a5aa7cf88 100644 --- a/objects/src/notes/note_id.rs +++ b/objects/src/notes/note_id.rs @@ -22,6 +22,7 @@ use crate::utils::{ /// - To compute a note ID, we do not need to know the note's serial_num. Knowing the hash /// of the serial_num (as well as script hash, input hash, and note assets) is sufficient. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct NoteId(Digest); impl NoteId { diff --git a/objects/src/notes/nullifier.rs b/objects/src/notes/nullifier.rs index 081d4987e..fd680c3d3 100644 --- a/objects/src/notes/nullifier.rs +++ b/objects/src/notes/nullifier.rs @@ -19,6 +19,7 @@ use crate::utils::{hex_to_bytes, string::*, HexParseError}; /// - To compute the nullifier we must know all components of the note: serial_num, script_hash, /// input_hash and asset_hash. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Nullifier(Digest); impl Nullifier { diff --git a/objects/src/transaction/mod.rs b/objects/src/transaction/mod.rs index 078cebbf1..fb92e2346 100644 --- a/objects/src/transaction/mod.rs +++ b/objects/src/transaction/mod.rs @@ -17,8 +17,8 @@ mod tx_witness; pub use chain_mmr::ChainMmr; pub use executed_tx::ExecutedTransaction; -pub use inputs::{InputNote, InputNotes, TransactionInputs}; -pub use outputs::{OutputNote, OutputNotes, TransactionOutputs}; +pub use inputs::{InputNote, InputNotes, ToNullifier, TransactionInputs}; +pub use outputs::{OutputNote, OutputNotes, ToEnvelope, TransactionOutputs}; pub use prepared_tx::PreparedTransaction; pub use proven_tx::ProvenTransaction; pub use transaction_id::TransactionId; diff --git a/objects/src/transaction/outputs.rs b/objects/src/transaction/outputs.rs index c543ef8fc..064ad7063 100644 --- a/objects/src/transaction/outputs.rs +++ b/objects/src/transaction/outputs.rs @@ -33,6 +33,10 @@ pub trait ToEnvelope: { fn id(&self) -> NoteId; fn metadata(&self) -> NoteMetadata; + + fn to_envelope(&self) -> NoteEnvelope { + NoteEnvelope::new(self.id(), self.metadata()) + } } impl ToEnvelope for OutputNote {