Implements FFI for transactions from Zebra #49
1 changed files with 137 additions and 12 deletions
|
@ -32,6 +32,7 @@ use zcash_primitives::{
|
||||||
},
|
},
|
||||||
zip339::{Count, Mnemonic},
|
zip339::{Count, Mnemonic},
|
||||||
transaction::components::{
|
transaction::components::{
|
||||||
|
amount::Amount,
|
||||||
transparent::{
|
transparent::{
|
||||||
Bundle as TransparentBundle,
|
Bundle as TransparentBundle,
|
||||||
TxIn,
|
TxIn,
|
||||||
|
@ -41,7 +42,10 @@ use zcash_primitives::{
|
||||||
},
|
},
|
||||||
sapling::{
|
sapling::{
|
||||||
GrothProofBytes,
|
GrothProofBytes,
|
||||||
OutputDescription
|
OutputDescription,
|
||||||
|
SpendDescription,
|
||||||
|
Authorized as SaplingAuthorized,
|
||||||
|
Bundle as SaplingBundle
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sapling::{
|
sapling::{
|
||||||
|
@ -77,6 +81,8 @@ use zcash_client_backend::keys::sapling::{
|
||||||
use zcash_primitives::zip32::DiversifierIndex;
|
use zcash_primitives::zip32::DiversifierIndex;
|
||||||
|
|
||||||
use orchard::{
|
use orchard::{
|
||||||
|
Bundle as OrchardBundle,
|
||||||
|
bundle::Authorized as OrchardAuthorized,
|
||||||
Action,
|
Action,
|
||||||
keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope},
|
keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope},
|
||||||
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
||||||
|
@ -234,7 +240,9 @@ pub struct Htx {
|
||||||
txid: Vec<u8>,
|
txid: Vec<u8>,
|
||||||
locktime: u32,
|
locktime: u32,
|
||||||
expiry: u32,
|
expiry: u32,
|
||||||
t_bundle: HTBundle
|
t_bundle: HTBundle,
|
||||||
|
s_bundle: HSBundle,
|
||||||
|
o_bundle: HOBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<RW> ToHaskell<RW> for Htx {
|
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)]
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Hufvk {
|
pub struct Hufvk {
|
||||||
net: u8,
|
net: u8,
|
||||||
|
@ -673,19 +775,42 @@ pub extern "C" fn rust_wrapper_tx_read(
|
||||||
match parsed_tx {
|
match parsed_tx {
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
let tb = t.transparent_bundle();
|
let tb = t.transparent_bundle();
|
||||||
match tb {
|
let sb = t.sapling_bundle();
|
||||||
Some(my_tb) => {
|
let ob = t.orchard_bundle();
|
||||||
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) };
|
let h1 = Htx
|
||||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
{ txid: t.txid().as_ref().to_vec()
|
||||||
},
|
, locktime: t.lock_time()
|
||||||
None => {
|
, expiry: u32::from(t.expiry_height())
|
||||||
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} };
|
, t_bundle: match tb {
|
||||||
marshall_to_haskell_var(&h0, out, out_len, RW);
|
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) => {
|
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);
|
marshall_to_haskell_var(&h0, out, out_len, RW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue