Support for Zebra 2.1.0 #102

Merged
pitmutt merged 97 commits from rav001 into master 2024-12-14 12:51:07 +00:00
6 changed files with 156 additions and 73 deletions
Showing only changes of commit 662a0d1148 - Show all commits

View file

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.7.2.0]
### Changed
- Modified Sapling commitment trees to use Frontier
## [0.7.1.1] ## [0.7.1.1]
### Added ### Added

View file

@ -1369,6 +1369,31 @@ pub extern "C" fn rust_wrapper_bech32_encode(
marshall_to_haskell_var(&string, out, out_len, RW); marshall_to_haskell_var(&string, out, out_len, RW);
} }
#[no_mangle]
pub extern "C" fn rust_wrapper_read_sapling_frontier(
tree: *const u8,
tree_len: usize,
out: *mut u8,
out_len: &mut usize
){
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW);
let tree_reader = Cursor::new(tree_in);
let comm_tree: CommitmentTree<Node, SAPLING_DEPTH> = read_commitment_tree(tree_reader).unwrap();
//let comm_tree: Frontier<MerkleHashOrchard, 32> = read_frontier_v1(tree_reader).unwrap();
let frontier: Frontier<Node, SAPLING_DEPTH> = comm_tree.to_frontier();
match frontier.value() {
Some(f1) => {
let (pos, leaf, omm) = f1.clone().into_parts();
let f = Hfrontier { position: <u64>::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| x.to_bytes().to_vec()).collect()};
marshall_to_haskell_var(&f, out, out_len, RW);
},
None => {
let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![vec![0]]};
marshall_to_haskell_var(&f0, out, out_len, RW);
}
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn rust_wrapper_read_sapling_commitment_tree( pub extern "C" fn rust_wrapper_read_sapling_commitment_tree(
tree: *const u8, tree: *const u8,
@ -1378,39 +1403,21 @@ pub extern "C" fn rust_wrapper_read_sapling_commitment_tree(
out: *mut u8, out: *mut u8,
out_len: &mut usize out_len: &mut usize
){ ){
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW); let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW);
let tree_reader = Cursor::new(tree_in); let leaf = Node::from_bytes(to_array(tree_in.leaf.bytes)).unwrap();
let mut ct = read_commitment_tree::<Node, Cursor<Vec<u8>>, SAPLING_DEPTH>(tree_reader); let mut comm_tree = NonEmptyFrontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| Node::from_bytes(to_array(x.clone())).unwrap() ).collect()).unwrap();
match ct { let node_in: Vec<u8> = marshall_from_haskell_var(node, node_len, RW);
Ok(mut comm_tree) => { let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in));
let node_in: Vec<u8> = marshall_from_haskell_var(node, node_len, RW); if sap_note_comm.is_some().into() {
let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in)); let n = Node::from_cmu(&sap_note_comm.unwrap());
if sap_note_comm.is_some().into() { comm_tree.append(n);
let n = Node::from_cmu(&sap_note_comm.unwrap()); let (pos, leaf, omm) = comm_tree.into_parts();
comm_tree.append(n); let f = Hfrontier { position: <u64>::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| x.to_bytes().to_vec()).collect()};
let mut out_bytes: Vec<u8> = Vec::new(); marshall_to_haskell_var(&f, out, out_len, RW);
let result = write_commitment_tree(&comm_tree, &mut out_bytes ); } else {
match result { let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![vec![0]]};
Ok(()) => { marshall_to_haskell_var(&f0, out, out_len, RW);
let h = Hhex { bytes: out_bytes};
marshall_to_haskell_var(&h, out, out_len, RW);
},
Err(_e) => {
let h0 = Hhex { bytes: vec![0]};
marshall_to_haskell_var(&h0, out, out_len, RW);
}
}
} else {
let h0 = Hhex { bytes: vec![0]};
marshall_to_haskell_var(&h0, out, out_len, RW);
}
},
Err(_e) => {
let h0 = Hhex { bytes: vec![0]};
marshall_to_haskell_var(&h0, out, out_len, RW);
}
} }
} }
#[no_mangle] #[no_mangle]
@ -1420,9 +1427,10 @@ pub extern "C" fn rust_wrapper_read_sapling_witness(
out: *mut u8, out: *mut u8,
out_len: &mut usize out_len: &mut usize
){ ){
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW); let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW);
let tree_reader = Cursor::new(tree_in); let leaf = Node::from_bytes(to_array(tree_in.leaf.bytes)).unwrap();
let ct: CommitmentTree<Node, SAPLING_DEPTH> = read_commitment_tree(tree_reader).unwrap(); let frontier: Frontier<Node, SAPLING_DEPTH> = Frontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| Node::from_bytes(to_array(x.clone())).unwrap() ).collect()).unwrap();
let ct: CommitmentTree<Node, SAPLING_DEPTH> = CommitmentTree::from_frontier(&frontier);
let inc_wit = IncrementalWitness::from_tree(ct); let inc_wit = IncrementalWitness::from_tree(ct);
let mut out_bytes: Vec<u8> = Vec::new(); let mut out_bytes: Vec<u8> = Vec::new();
let result = write_incremental_witness(&inc_wit, &mut out_bytes); let result = write_incremental_witness(&inc_wit, &mut out_bytes);
@ -1687,21 +1695,31 @@ pub extern "C" fn rust_wrapper_create_transaction(
build: bool, build: bool,
out: *mut u8, out: *mut u8,
out_len: &mut usize){ out_len: &mut usize){
let sap_wit_in: Vec<u8> = marshall_from_haskell_var(sap_wit, sap_wit_len, RW); //let sap_wit_in: Vec<u8> = marshall_from_haskell_var(sap_wit, sap_wit_len, RW);
let sap_wit_reader = Cursor::new(sap_wit_in); //let sap_wit_reader = Cursor::new(sap_wit_in);
let sap_iw = read_commitment_tree::<Node, Cursor<Vec<u8>>, SAPLING_DEPTH>(sap_wit_reader); //let sap_iw = read_commitment_tree::<Node, Cursor<Vec<u8>>, SAPLING_DEPTH>(sap_wit_reader);
let sap_anchor = match sap_iw { let sap_input: Vec<HsaplingInput> = marshall_from_haskell_var(s_input, s_input_len, RW);
Ok(s_iw) => { let sap_anchor =
Some(SaplingAnchor::from(s_iw.root())) if sap_input.is_empty() {
},
Err(_e) => {
None None
} } else {
}; let si = &sap_input[0];
let swit_reader = Cursor::new(&si.iw);
let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(swit_reader).unwrap();
Some(SaplingAnchor::from(iw.root()))
};
//let sap_anchor = match sap_iw {
//Ok(s_iw) => {
//Some(SaplingAnchor::from(s_iw.root()))
//},
//Err(_e) => {
//None
//}
//};
//println!("{:?}", sap_anchor); //println!("{:?}", sap_anchor);
let orch_wit_in: Vec<u8> = marshall_from_haskell_var(orch_wit, orch_wit_len, RW); //let orch_wit_in: Vec<u8> = marshall_from_haskell_var(orch_wit, orch_wit_len, RW);
let orch_wit_reader = Cursor::new(orch_wit_in); //let orch_wit_reader = Cursor::new(orch_wit_in);
let orch_iw = read_commitment_tree::<MerkleHashOrchard, Cursor<Vec<u8>>, 32>(orch_wit_reader); //let orch_iw = read_commitment_tree::<MerkleHashOrchard, Cursor<Vec<u8>>, 32>(orch_wit_reader);
let orch_input: Vec<HorchardInput> = marshall_from_haskell_var(o_input, o_input_len, RW); let orch_input: Vec<HorchardInput> = marshall_from_haskell_var(o_input, o_input_len, RW);
//let orch_anchor = match orch_iw { //let orch_anchor = match orch_iw {
//Ok(o_iw) => { //Ok(o_iw) => {
@ -1746,7 +1764,6 @@ pub extern "C" fn rust_wrapper_create_transaction(
} }
} }
} }
let sap_input: Vec<HsaplingInput> = marshall_from_haskell_var(s_input, s_input_len, RW);
for s_in in sap_input { for s_in in sap_input {
if s_in.sk.len() > 1 { if s_in.sk.len() > 1 {
let sp_key = ExtendedSpendingKey::from_bytes(&s_in.sk); let sp_key = ExtendedSpendingKey::from_bytes(&s_in.sk);
@ -1763,13 +1780,32 @@ pub extern "C" fn rust_wrapper_create_transaction(
let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(wit_reader).unwrap(); let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(wit_reader).unwrap();
let merkle_path = iw.path().unwrap(); let merkle_path = iw.path().unwrap();
if net { if net {
let _mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path).unwrap(); let mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
match mb {
Ok(()) => {
continue;
},
Err(_e) => {
let x = Hhex {bytes: vec![5]};
marshall_to_haskell_var(&x, out, out_len, RW);
}
}
} else { } else {
let _tb = test_builder.add_sapling_spend::<String>(&sk, note, merkle_path).unwrap(); let tb = test_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
match tb {
Ok(()) => {
continue;
},
Err(_e) => {
let x = Hhex {bytes: vec![5]};
marshall_to_haskell_var(&x, out, out_len, RW);
}
}
} }
}, },
Err(_e) => { Err(_e) => {
continue; let x = Hhex {bytes: vec![5]};
marshall_to_haskell_var(&x, out, out_len, RW);
} }
} }
} }
@ -1786,9 +1822,27 @@ pub extern "C" fn rust_wrapper_create_transaction(
let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap(); let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
let merkle_path = OrchardMerklePath::from(iw.path().unwrap()); let merkle_path = OrchardMerklePath::from(iw.path().unwrap());
if net { if net {
let _mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path).unwrap(); let mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
match mb {
Ok(()) => {
continue;
},
Err(_e) => {
let x = Hhex {bytes: vec![7]};
marshall_to_haskell_var(&x, out, out_len, RW);
}
}
} else { } else {
let _tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path).unwrap(); let tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
match tb {
Ok(()) => {
continue;
},
Err(_e) => {
let x = Hhex {bytes: vec![7]};
marshall_to_haskell_var(&x, out, out_len, RW);
}
}
} }
} }
} }

View file

@ -204,15 +204,15 @@ import ZcashHaskell.Types
#} #}
{# fun unsafe rust_wrapper_read_sapling_commitment_tree as rustWrapperReadSaplingCommitmentTree {# fun unsafe rust_wrapper_read_sapling_commitment_tree as rustWrapperReadSaplingCommitmentTree
{ toBorshVar* `BS.ByteString'& { toBorshVar* `SaplingFrontier'&
, toBorshVar* `BS.ByteString'& , toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer HexString'& , getVarBuffer `Buffer SaplingFrontier'&
} }
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_read_sapling_witness as rustWrapperReadSaplingWitness {# fun unsafe rust_wrapper_read_sapling_witness as rustWrapperReadSaplingWitness
{ toBorshVar* `BS.ByteString'& { toBorshVar* `SaplingFrontier'&
, getVarBuffer `Buffer HexString'& , getVarBuffer `Buffer HexString'&
} }
-> `()' -> `()'
@ -232,6 +232,13 @@ import ZcashHaskell.Types
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_read_sapling_frontier as rustWrapperReadSaplingFrontier
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer SaplingFrontier'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_decode_sapling_address as rustWrapperDecodeSaplingAddress {# fun unsafe rust_wrapper_decode_sapling_address as rustWrapperDecodeSaplingAddress
{ toBorshVar* `BS.ByteString'& { toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer (BS.ByteString)'& , getVarBuffer `Buffer (BS.ByteString)'&

View file

@ -21,6 +21,7 @@ import C.Zcash
( rustWrapperDecodeSaplingAddress ( rustWrapperDecodeSaplingAddress
, rustWrapperIsShielded , rustWrapperIsShielded
, rustWrapperReadSaplingCommitmentTree , rustWrapperReadSaplingCommitmentTree
, rustWrapperReadSaplingFrontier
, rustWrapperReadSaplingPosition , rustWrapperReadSaplingPosition
, rustWrapperReadSaplingWitness , rustWrapperReadSaplingWitness
, rustWrapperSaplingCheck , rustWrapperSaplingCheck
@ -184,32 +185,38 @@ genSaplingInternalAddress sk =
res = res =
withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk) withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk)
-- | Update a Sapling commitment tree getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier
updateSaplingCommitmentTree :: getSaplingFrontier tree =
SaplingCommitmentTree -- ^ the base tree if sf_pos updatedTree > 1
-> HexString -- ^ the new note commitment then Just updatedTree
-> Maybe SaplingCommitmentTree
updateSaplingCommitmentTree tree cmu =
if BS.length (hexBytes updatedTree) > 1
then Just $ SaplingCommitmentTree updatedTree
else Nothing else Nothing
where where
updatedTree = updatedTree =
withPureBorshVarBuffer $ withPureBorshVarBuffer $
rustWrapperReadSaplingCommitmentTree rustWrapperReadSaplingFrontier $ toBytes $ sapTree tree
(hexBytes $ sapTree tree)
(hexBytes cmu) -- | Update a Sapling commitment tree
updateSaplingCommitmentTree ::
SaplingFrontier -- ^ the base tree
-> HexString -- ^ the new note commitment
-> Maybe SaplingFrontier
updateSaplingCommitmentTree tree cmu =
if sf_pos updatedTree > 1
then Just updatedTree
else Nothing
where
updatedTree =
withPureBorshVarBuffer $
rustWrapperReadSaplingCommitmentTree tree (hexBytes cmu)
-- | Get the Sapling incremental witness from a commitment tree -- | Get the Sapling incremental witness from a commitment tree
getSaplingWitness :: SaplingCommitmentTree -> Maybe SaplingWitness getSaplingWitness :: SaplingFrontier -> Maybe SaplingWitness
getSaplingWitness tree = getSaplingWitness tree =
if BS.length (hexBytes wit) > 1 if BS.length (hexBytes wit) > 1
then Just $ SaplingWitness wit then Just $ SaplingWitness wit
else Nothing else Nothing
where where
wit = wit = withPureBorshVarBuffer $ rustWrapperReadSaplingWitness tree
withPureBorshVarBuffer $
rustWrapperReadSaplingWitness (hexBytes $ sapTree tree)
-- | Get the Sapling note position from a witness -- | Get the Sapling note position from a witness
getSaplingNotePosition :: SaplingWitness -> Integer getSaplingNotePosition :: SaplingWitness -> Integer

View file

@ -611,6 +611,15 @@ newtype SaplingCommitmentTree = SaplingCommitmentTree
{ sapTree :: HexString { sapTree :: HexString
} deriving (Eq, Prelude.Show, Read) } deriving (Eq, Prelude.Show, Read)
data SaplingFrontier = SaplingFrontier
{ sf_pos :: !Int64
, sf_leaf :: !HexString
, sf_ommers :: ![BS.ByteString]
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingFrontier
-- | Type for a Sapling incremental witness -- | Type for a Sapling incremental witness
newtype SaplingWitness = SaplingWitness newtype SaplingWitness = SaplingWitness
{ sapWit :: HexString { sapWit :: HexString

View file

@ -5,7 +5,7 @@ cabal-version: 3.0
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: zcash-haskell name: zcash-haskell
version: 0.7.1.1 version: 0.7.2.0
synopsis: Utilities to interact with the Zcash blockchain synopsis: Utilities to interact with the Zcash blockchain
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme> description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
category: Blockchain category: Blockchain