From 1ce7dc24feb8fc7063a49e3fd9f8e5e0512cba2f Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Mon, 11 Nov 2024 11:21:24 -0600 Subject: [PATCH] feat: Implement transaction creation with new trees --- librustzcash-wrapper/src/lib.rs | 70 ++++++++++++--------------------- src/ZcashHaskell/Types.hs | 4 +- src/ZcashHaskell/Utils.hs | 12 ++---- 3 files changed, 31 insertions(+), 55 deletions(-) diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index 6c4095f..1e99fbe 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -570,11 +570,11 @@ impl Hspend { } } -#[derive(Debug, BorshSerialize, BorshDeserialize)] +#[derive(BorshSerialize, BorshDeserialize)] pub struct HsaplingInput { sk: Vec, note: Hnote, - iw: Vec + iw: Hpath } impl FromHaskell for HsaplingInput { @@ -585,11 +585,11 @@ impl FromHaskell for HsaplingInput { } -#[derive(Debug, BorshSerialize, BorshDeserialize)] +#[derive(BorshSerialize, BorshDeserialize)] pub struct HorchardInput { sk: Vec, note: Hnote, - iw: Vec + iw: Hpath } impl FromHaskell for HorchardInput { @@ -2144,47 +2144,25 @@ pub extern "C" fn rust_wrapper_create_transaction( out: *mut u8, out_len: &mut usize){ let sap_input: Vec = marshall_from_haskell_var(s_input, s_input_len, RW); - let sap_anchor = - if sap_input.is_empty() { - let sap_wit_in: Vec = marshall_from_haskell_var(sap_wit, sap_wit_len, RW); - let sap_wit_reader = Cursor::new(sap_wit_in); - let sap_iw = read_commitment_tree::>, SAPLING_DEPTH>(sap_wit_reader); - match sap_iw { - Ok(s_iw) => { - Some(SaplingAnchor::from(s_iw.root())) - }, - Err(_e) => { - None - } - } + let sap_anchor_in: Vec = marshall_from_haskell_var(sap_wit, sap_wit_len, RW); + let sap_anchor = SaplingAnchor::from_bytes(to_array(sap_anchor_in)); + let sapling_anchor = + if sap_anchor.is_some().into() { + Some(sap_anchor.unwrap()) } else { - let si = &sap_input[0]; - let swit_reader = Cursor::new(&si.iw); - let iw: IncrementalWitness = read_incremental_witness(swit_reader).unwrap(); - Some(SaplingAnchor::from(iw.root())) + None }; //println!("{:?}", sap_anchor); let orch_input: Vec = marshall_from_haskell_var(o_input, o_input_len, RW); - let orch_anchor = - if orch_input.is_empty() { - let orch_wit_in: Vec = marshall_from_haskell_var(orch_wit, orch_wit_len, RW); - let orch_wit_reader = Cursor::new(orch_wit_in); - let orch_iw = read_commitment_tree::>, 32>(orch_wit_reader); - match orch_iw { - Ok(o_iw) => { - Some(OrchardAnchor::from(o_iw.root())) - }, - Err(_e) => { - None - } - } + let orch_anchor_in : Vec = marshall_from_haskell_var(orch_wit, orch_wit_len, RW); + let orch_anchor = OrchardAnchor::from_bytes(to_array(orch_anchor_in)); + let orchard_anchor = + if orch_anchor.is_some().into() { + Some(orch_anchor.unwrap()) } else { - let oi = &orch_input[0]; - let wit_reader = Cursor::new(&oi.iw); - let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); - Some(OrchardAnchor::from(iw.root())) + None }; - let build_config = BuildConfig::Standard {sapling_anchor: sap_anchor, orchard_anchor: orch_anchor}; + let build_config = BuildConfig::Standard {sapling_anchor, orchard_anchor}; let mut main_builder = Builder::new(MainNetwork, BlockHeight::from(bl_height), build_config); let mut test_builder = Builder::new(TestNetwork, BlockHeight::from(bl_height), build_config); let trans_input: Vec = marshall_from_haskell_var(t_input, t_input_len, RW); @@ -2224,9 +2202,13 @@ pub extern "C" fn rust_wrapper_create_transaction( Rseed::AfterZip212(to_array(s_in.note.rseed.bytes)) }; let note = SaplingNote::from_parts(pay_addr, SaplingNoteValue::from_raw(s_in.note.note), rseed); - let wit_reader = Cursor::new(s_in.iw); - let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); - let merkle_path = iw.path().unwrap(); + let mk_path = sapling_crypto::MerklePath::from_parts(s_in.iw.path.iter().map(|x| + if x.bytes.len() > 1 { + Node::from_bytes(to_array(x.bytes.clone())).unwrap() + } else { + Node::empty_leaf() + }).collect(), Position::from(u64::from(s_in.iw.position))); + let merkle_path = mk_path.unwrap(); if net { let mb = main_builder.add_sapling_spend::(&sk, note, merkle_path); match mb { @@ -2267,9 +2249,7 @@ pub extern "C" fn rust_wrapper_create_transaction( let val = NoteValue::from_raw(o_in.note.note); //println!("o inp: {:?}", val); let note = Note::from_parts(pay_addr, val, rho, rseed).unwrap(); - let wit_reader = Cursor::new(o_in.iw); - let iw: IncrementalWitness = read_incremental_witness(wit_reader).unwrap(); - let merkle_path = OrchardMerklePath::from(iw.path().unwrap()); + let merkle_path = orchard::tree::MerklePath::from_parts(o_in.iw.position, to_array(o_in.iw.path.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap()).collect())); if net { let mb = main_builder.add_orchard_spend::(&sp_key, note, merkle_path); match mb { diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index ada4a58..1c55a73 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -812,7 +812,7 @@ data TransparentTxSpend = TransparentTxSpend data SaplingTxSpend = SaplingTxSpend { ss_sk :: !BS.ByteString , ss_note :: !DecodedNote - , ss_iw :: !BS.ByteString + , ss_iw :: !MerklePath } deriving stock (Eq, Prelude.Show, GHC.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (Data.Structured.Show) @@ -821,7 +821,7 @@ data SaplingTxSpend = SaplingTxSpend data OrchardTxSpend = OrchardTxSpend { ss_sk :: !BS.ByteString , ss_note :: !DecodedNote - , ss_iw :: !BS.ByteString + , ss_iw :: !MerklePath } deriving stock (Eq, Prelude.Show, GHC.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (Data.Structured.Show) diff --git a/src/ZcashHaskell/Utils.hs b/src/ZcashHaskell/Utils.hs index ee0a0d9..03db2b5 100644 --- a/src/ZcashHaskell/Utils.hs +++ b/src/ZcashHaskell/Utils.hs @@ -123,8 +123,8 @@ readZebraTransaction hex = rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex createTransaction :: - Maybe SaplingCommitmentTree -- ^ to obtain the Sapling anchor - -> Maybe OrchardCommitmentTree -- ^ to obtain the Orchard anchor + HexString -- ^ to obtain the Sapling anchor + -> HexString -- ^ to obtain the Orchard anchor -> [TransparentTxSpend] -- ^ the list of transparent notes to spend -> [SaplingTxSpend] -- ^ the list of Sapling notes to spend -> [OrchardTxSpend] -- ^ the list of Orchard notes to spend @@ -137,12 +137,8 @@ createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing znet bh bui txResult <- withBorshBufferOfInitSize 51200 $ rustWrapperCreateTx - (case sapAnchor of - Nothing -> "0" - Just sA -> toBytes $ sapTree sA) - (case orchAnchor of - Nothing -> "0" - Just oA -> toBytes $ orchTree oA) + (hexBytes sapAnchor) + (hexBytes orchAnchor) tSpend sSpend oSpend