Functions to handle commitment tree nodes for Sapling and Orchard #100

Merged
pitmutt merged 50 commits from rav001 into milestone2 2024-11-15 18:48:36 +00:00
4 changed files with 88 additions and 0 deletions
Showing only changes of commit a13eab17d7 - Show all commits

View file

@ -1614,6 +1614,52 @@ pub extern "C" fn rust_wrapper_get_sapling_root(
marshall_to_haskell_var(&h, out, out_len, RW); marshall_to_haskell_var(&h, out, out_len, RW);
} }
#[no_mangle]
pub extern "C" fn rust_wrapper_read_sapling_commitment_tree_parts(
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 = read_commitment_tree(tree_reader);
match comm_tree {
Ok::<CommitmentTree<Node, 32>, _>(c1) => {
let left = match c1.left() {
Some(x) => {
Hhex { bytes: x.to_bytes().to_vec() }
},
None => {
Hhex { bytes: vec![0] }
}
};
let right = match c1.right() {
Some(x) => {
Hhex { bytes: x.to_bytes().to_vec() }
},
None => {
Hhex { bytes: vec![0] }
}
};
let parents = c1.parents().iter().map(|x| match x {
Some(y) => {
Hhex { bytes: y.to_bytes().to_vec() }
},
None => {
Hhex { bytes: vec![0] }
}
}).collect();
let ht = Htree { left, right, parents};
marshall_to_haskell_var(&ht, out, out_len, RW);
},
Err(_e) => {
let ht0 = Htree { left: Hhex { bytes: vec![0] } , right: Hhex { bytes: vec![0] }, parents: vec![Hhex { bytes: vec![0] }]};
marshall_to_haskell_var(&ht0, out, out_len, RW);
}
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn rust_wrapper_read_orchard_frontier( pub extern "C" fn rust_wrapper_read_orchard_frontier(
tree: *const u8, tree: *const u8,

View file

@ -269,6 +269,13 @@ import ZcashHaskell.Types
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_read_sapling_commitment_tree_parts as rustWrapperReadSaplingTreeParts
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer SaplingRawTree'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_read_orchard_node as rustWrapperReadOrchardNode {# fun unsafe rust_wrapper_read_orchard_node as rustWrapperReadOrchardNode
{ toBorshVar* `BS.ByteString'& { toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer HexString'& , getVarBuffer `Buffer HexString'&

View file

@ -26,6 +26,7 @@ import C.Zcash
, rustWrapperReadSaplingFrontier , rustWrapperReadSaplingFrontier
, rustWrapperReadSaplingNode , rustWrapperReadSaplingNode
, rustWrapperReadSaplingPosition , rustWrapperReadSaplingPosition
, rustWrapperReadSaplingTreeParts
, rustWrapperReadSaplingWitness , rustWrapperReadSaplingWitness
, rustWrapperSaplingCheck , rustWrapperSaplingCheck
, rustWrapperSaplingChgPaymentAddress , rustWrapperSaplingChgPaymentAddress
@ -211,6 +212,25 @@ getSaplingRootTest :: Int8 -> HexString
getSaplingRootTest level = getSaplingRootTest level =
withPureBorshVarBuffer $ rustWrapperGetSaplingRootTest level withPureBorshVarBuffer $ rustWrapperGetSaplingRootTest level
getSaplingTreeParts :: SaplingCommitmentTree -> Maybe SaplingTree
getSaplingTreeParts h =
if isBlank (srt_left tree) && isBlank (srt_right tree)
then Nothing
else Just $
SaplingTree
(parseHex $ srt_left tree)
(parseHex $ srt_right tree)
(map parseHex (srt_parents tree))
where
isBlank h = (BS.length $ hexBytes $ h) == 1
parseHex h =
if (BS.length $ hexBytes $ h) > 1
then Just h
else Nothing
tree =
withPureBorshVarBuffer $
rustWrapperReadSaplingTreeParts $ toBytes $ sapTree h
getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier
getSaplingFrontier tree = getSaplingFrontier tree =
if sf_pos updatedTree > 1 if sf_pos updatedTree > 1

View file

@ -611,6 +611,21 @@ newtype SaplingCommitmentTree = SaplingCommitmentTree
{ sapTree :: HexString { sapTree :: HexString
} deriving (Eq, Prelude.Show, Read) } deriving (Eq, Prelude.Show, Read)
data SaplingRawTree = SaplingRawTree
{ srt_left :: !HexString
, srt_right :: !HexString
, srt_parents :: ![HexString]
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingRawTree
data SaplingTree = SaplingTree
{ ot_left :: !(Maybe HexString)
, ot_right :: !(Maybe HexString)
, ot_parents :: ![Maybe HexString]
} deriving (Eq, Prelude.Show, Read)
data SaplingFrontier = SaplingFrontier data SaplingFrontier = SaplingFrontier
{ sf_pos :: !Int64 { sf_pos :: !Int64
, sf_leaf :: !HexString , sf_leaf :: !HexString