Implements FFI for transactions from Zebra #49

Merged
pitmutt merged 3 commits from rav001 into dev040 2024-04-02 17:09:43 +00:00
Showing only changes of commit dbae2150da - Show all commits

View file

@ -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<u8>,
locktime: u32,
expiry: u32,
t_bundle: HTBundle
t_bundle: HTBundle,
s_bundle: HSBundle,
o_bundle: HOBundle
}
impl<RW> ToHaskell<RW> for Htx {
@ -324,6 +332,100 @@ impl Houtpoint {
}
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct HSBundle {
empty: bool,
spends: Vec<Hspend>,
outputs: Vec<HshieldedOutput> ,
value: i64,
sig: Vec<u8>
}
impl<RW> ToHaskell<RW> for HSBundle {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl HSBundle {
pub fn from_bundle(sb: &SaplingBundle<SaplingAuthorized>) -> 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<u8>,
anchor: Vec<u8>,
nullifier: Vec<u8>,
rk: Vec<u8>,
proof: Vec<u8>,
authsig: Vec<u8>
}
impl<RW> ToHaskell<RW> for Hspend {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl Hspend {
pub fn pack(sp: &SpendDescription<SaplingAuthorized>) -> 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<Haction>,
flags: Vec<Hflags>,
value: i64,
anchor: Vec<u8>,
auth: Vec<u8>
}
impl<RW> ToHaskell<RW> for HOBundle {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl HOBundle {
pub fn from_bundle(b: &OrchardBundle<OrchardAuthorized, Amount>) -> 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<RW> ToHaskell<RW> for Hflags {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> 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);
}
}