From dbae2150da0d6bfb0a2906b37faefc5890017ede Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Fri, 29 Mar 2024 13:54:21 -0500 Subject: [PATCH] Advance bundle FFI --- librustzcash-wrapper/src/lib.rs | 149 +++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 12 deletions(-) diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index e74beb3..f140d0f 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -32,6 +32,7 @@ use zcash_primitives::{ }, zip339::{Count, Mnemonic}, transaction::components::{ + amount::Amount, transparent::{ Bundle as TransparentBundle, TxIn, @@ -41,7 +42,10 @@ use zcash_primitives::{ }, sapling::{ GrothProofBytes, - OutputDescription + OutputDescription, + SpendDescription, + Authorized as SaplingAuthorized, + Bundle as SaplingBundle } }, sapling::{ @@ -77,6 +81,8 @@ use zcash_client_backend::keys::sapling::{ use zcash_primitives::zip32::DiversifierIndex; use orchard::{ + Bundle as OrchardBundle, + bundle::Authorized as OrchardAuthorized, Action, keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope}, note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment}, @@ -234,7 +240,9 @@ pub struct Htx { txid: Vec, locktime: u32, expiry: u32, - t_bundle: HTBundle + t_bundle: HTBundle, + s_bundle: HSBundle, + o_bundle: HOBundle } impl ToHaskell for Htx { @@ -324,6 +332,100 @@ impl Houtpoint { } } +#[derive(BorshSerialize, BorshDeserialize)] +pub struct HSBundle { + empty: bool, + spends: Vec, + outputs: Vec , + value: i64, + sig: Vec +} + +impl ToHaskell for HSBundle { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl HSBundle { + pub fn from_bundle(sb: &SaplingBundle) -> HSBundle { + let s = Vec::new(); + sb.authorization().binding_sig.write(s); + return HSBundle {empty: true, spends: sb.shielded_spends() , outputs: sb.shielded_outputs() , value: i64::from(sb.value_balance()) , sig: s } + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hspend { + cv: Vec, + anchor: Vec, + nullifier: Vec, + rk: Vec, + proof: Vec, + authsig: Vec +} + +impl ToHaskell for Hspend { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl Hspend { + pub fn pack(sp: &SpendDescription) -> Hspend { + let rk = Vec::new(); + let authsig = Vec::new(); + sp.rk().write(rk); + sp.spend_auth_sig().write(authsig); + return Hspend {cv: sp.cv().to_bytes().to_vec(), anchor: sp.anchor().to_bytes().to_vec(), nullifier: sp.nullifier().to_vec(), rk, proof: sp.zkproof().to_vec(), authsig } + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct HOBundle { + empty: bool, + actions: Vec, + flags: Vec, + value: i64, + anchor: Vec, + auth: Vec +} + +impl ToHaskell for HOBundle { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl HOBundle { + pub fn from_bundle(b: &OrchardBundle) -> HOBundle { + return HOBundle {actions: b.actions(), flags: b.flags(), value: b.value_balance(), anchor: b.anchor(), auth: b.authorization()} + } +} + + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct Hflags { + spends: bool, + outputs: bool +} + +impl ToHaskell for Hflags { + fn to_haskell(&self, writer: &mut W, _tag: PhantomData) -> Result<()> { + self.serialize(writer)?; + Ok(()) + } +} + +impl Hflags { + pub fn pack(f: &Flags) -> Hflags { + return Hflags {spends: f.spends_enabled(), outputs: f.outputs_enabled()} + } +} + #[derive(BorshSerialize, BorshDeserialize)] pub struct Hufvk { net: u8, @@ -673,19 +775,42 @@ pub extern "C" fn rust_wrapper_tx_read( match parsed_tx { Ok(t) => { let tb = t.transparent_bundle(); - match tb { - Some(my_tb) => { - let h = Htx {txid: t.txid().as_ref().to_vec(), locktime: t.lock_time(), expiry: u32::from(t.expiry_height()), t_bundle: HTBundle::from_bundle(my_tb) }; - marshall_to_haskell_var(&h, out, out_len, RW); - }, - None => { - let h0 = Htx {txid: t.txid().as_ref().to_vec(), locktime: t.lock_time(), expiry: u32::from(t.expiry_height()), t_bundle: HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: true} }; - marshall_to_haskell_var(&h0, out, out_len, RW); + let sb = t.sapling_bundle(); + let ob = t.orchard_bundle(); + let h1 = Htx + { txid: t.txid().as_ref().to_vec() + , locktime: t.lock_time() + , expiry: u32::from(t.expiry_height()) + , t_bundle: match tb { + Some(tb1) => {HTBundle::from_bundle(tb1)}, + None => {HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: false}}} + , s_bundle: match sb { + Some(sb1) => {HSBundle::from_bundle(sb1)}, + None => {} } + , o_bundle: match ob { + Some(ob1) => {HOBundle::from_bundle(ob1)}, + None => {} } - } + }; + marshall_to_haskell_var(&h1, out, out_len, RW); }, Err(_e) => { - let h0 = Htx {txid: vec![0], locktime: 0, expiry: 0, t_bundle: HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: true} }; + let h0 = Htx + {txid: vec![0], + locktime: 0, + expiry: 0, + t_bundle: HTBundle + {empty: true, + vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], + vout: vec![HTxOut {amt: 0, script: vec![0]}], + coinbase: true}, + s_bundle: HSBundle + {empty: true, + }, + o_bundle: HOBundle + {empty: true, + } + }; marshall_to_haskell_var(&h0, out, out_len, RW); } }