Functions to handle commitment tree nodes for Sapling and Orchard #100
4 changed files with 109 additions and 0 deletions
|
@ -717,6 +717,27 @@ impl<RW> FromHaskell<RW> for Hfrontier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
|
pub struct Htree {
|
||||||
|
left: Hhex,
|
||||||
|
right: Hhex,
|
||||||
|
parents: Vec<Hhex>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<RW> ToHaskell<RW> for Htree {
|
||||||
|
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||||
|
self.serialize(writer)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<RW> FromHaskell<RW> for Htree {
|
||||||
|
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||||
|
let x = Htree::deserialize(buf)?;
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_array<T, const N: usize>(v: Vec<T>) -> [T; N] {
|
fn to_array<T, const N: usize>(v: Vec<T>) -> [T; N] {
|
||||||
v.try_into().unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
|
v.try_into().unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
|
||||||
}
|
}
|
||||||
|
@ -1550,6 +1571,52 @@ pub extern "C" fn rust_wrapper_read_orchard_tree_anchor(
|
||||||
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_orchard_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<MerkleHashOrchard, 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_witness_anchor(
|
pub extern "C" fn rust_wrapper_read_orchard_witness_anchor(
|
||||||
wit: *const u8,
|
wit: *const u8,
|
||||||
|
|
|
@ -291,6 +291,13 @@ import ZcashHaskell.Types
|
||||||
-> `()'
|
-> `()'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_read_orchard_commitment_tree_parts as rustWrapperReadOrchardTreeParts
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer OrchardRawTree'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_read_orchard_frontier as rustWrapperReadOrchardFrontier
|
{# fun unsafe rust_wrapper_read_orchard_frontier as rustWrapperReadOrchardFrontier
|
||||||
{ toBorshVar* `BS.ByteString'&
|
{ toBorshVar* `BS.ByteString'&
|
||||||
, getVarBuffer `Buffer OrchardFrontier'&
|
, getVarBuffer `Buffer OrchardFrontier'&
|
||||||
|
|
|
@ -31,6 +31,7 @@ import C.Zcash
|
||||||
, rustWrapperReadOrchardNode
|
, rustWrapperReadOrchardNode
|
||||||
, rustWrapperReadOrchardPosition
|
, rustWrapperReadOrchardPosition
|
||||||
, rustWrapperReadOrchardTreeAnchor
|
, rustWrapperReadOrchardTreeAnchor
|
||||||
|
, rustWrapperReadOrchardTreeParts
|
||||||
, rustWrapperReadOrchardWitness
|
, rustWrapperReadOrchardWitness
|
||||||
, rustWrapperReadOrchardWitnessAnchor
|
, rustWrapperReadOrchardWitnessAnchor
|
||||||
, rustWrapperUADecode
|
, rustWrapperUADecode
|
||||||
|
@ -228,6 +229,25 @@ addOrchardNodeGetRoot :: Int -> BS.ByteString -> HexString
|
||||||
addOrchardNodeGetRoot l n =
|
addOrchardNodeGetRoot l n =
|
||||||
withPureBorshVarBuffer $ rustWrapperOrchardAddNodeTest (fromIntegral l) n
|
withPureBorshVarBuffer $ rustWrapperOrchardAddNodeTest (fromIntegral l) n
|
||||||
|
|
||||||
|
getOrchardTreeParts :: OrchardCommitmentTree -> Maybe OrchardTree
|
||||||
|
getOrchardTreeParts h =
|
||||||
|
if isBlank (ort_left tree) && isBlank (ort_right tree)
|
||||||
|
then Nothing
|
||||||
|
else Just $
|
||||||
|
OrchardTree
|
||||||
|
(parseHex $ ort_left tree)
|
||||||
|
(parseHex $ ort_right tree)
|
||||||
|
(map parseHex (ort_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 $
|
||||||
|
rustWrapperReadOrchardTreeParts $ toBytes $ orchTree h
|
||||||
|
|
||||||
-- | Update a Orchard commitment tree
|
-- | Update a Orchard commitment tree
|
||||||
updateOrchardCommitmentTree ::
|
updateOrchardCommitmentTree ::
|
||||||
OrchardFrontier -- ^ the base tree
|
OrchardFrontier -- ^ the base tree
|
||||||
|
|
|
@ -727,6 +727,21 @@ newtype OrchardCommitmentTree = OrchardCommitmentTree
|
||||||
{ orchTree :: HexString
|
{ orchTree :: HexString
|
||||||
} deriving (Eq, Prelude.Show, Read)
|
} deriving (Eq, Prelude.Show, Read)
|
||||||
|
|
||||||
|
data OrchardRawTree = OrchardRawTree
|
||||||
|
{ ort_left :: !HexString
|
||||||
|
, ort_right :: !HexString
|
||||||
|
, ort_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 OrchardRawTree
|
||||||
|
|
||||||
|
data OrchardTree = OrchardTree
|
||||||
|
{ ot_left :: !(Maybe HexString)
|
||||||
|
, ot_right :: !(Maybe HexString)
|
||||||
|
, ot_parents :: ![Maybe HexString]
|
||||||
|
} deriving (Eq, Prelude.Show, Read)
|
||||||
|
|
||||||
data OrchardFrontier = OrchardFrontier
|
data OrchardFrontier = OrchardFrontier
|
||||||
{ of_pos :: !Int64
|
{ of_pos :: !Int64
|
||||||
, of_leaf :: !HexString
|
, of_leaf :: !HexString
|
||||||
|
|
Loading…
Reference in a new issue