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
3 changed files with 56 additions and 0 deletions
Showing only changes of commit b748cba310 - Show all commits

View file

@ -738,6 +738,26 @@ impl<RW> FromHaskell<RW> for Htree {
}
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Hpath {
position: u32,
path: Vec<Hhex>
}
impl<RW> ToHaskell<RW> for Hpath {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl<RW> FromHaskell<RW> for Hpath {
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
let x = Hpath::deserialize(buf)?;
Ok(x)
}
}
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()))
}
@ -1659,6 +1679,29 @@ pub extern "C" fn rust_wrapper_read_orchard_node(
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_read_orchard_path_anchor(
path: *const u8,
path_len: usize,
cmx: *const u8,
cmx_len: usize,
out: *mut u8,
out_len: &mut usize
){
let path_in: Hpath = marshall_from_haskell_var(path, path_len, RW);
let cmx_in: Vec<u8> = marshall_from_haskell_var(cmx, cmx_len, RW);
let mk_path = orchard::tree::MerklePath::from_parts(path_in.position, to_array(path_in.path.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap()).collect()));
let nc = ExtractedNoteCommitment::from_bytes(&to_array(cmx_in));
if nc.is_some().into() {
let anchor = mk_path.root(nc.unwrap());
let h = Hhex { bytes: anchor.to_bytes().to_vec() };
marshall_to_haskell_var(&h, out, out_len, RW);
} else {
let h0 = Hhex { bytes: vec![0] };
marshall_to_haskell_var(&h0, out, out_len, RW);
}
}
#[no_mangle]
pub extern "C" fn rust_wrapper_combine_orchard_nodes(
level: u8,

View file

@ -276,6 +276,14 @@ import ZcashHaskell.Types
-> `()'
#}
{# fun unsafe rust_wrapper_read_orchard_path_anchor as rustWrapperReadOrchardPathAnchor
{ toBorshVar* `MerklePath'&
, toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer HexString'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_get_orchard_root as rustWrapperGetOrchardRootTest
{ `Int8'
, getVarBuffer `Buffer HexString'&

View file

@ -29,6 +29,7 @@ import C.Zcash
, rustWrapperReadOrchardCommitmentTree
, rustWrapperReadOrchardFrontier
, rustWrapperReadOrchardNode
, rustWrapperReadOrchardPathAnchor
, rustWrapperReadOrchardPosition
, rustWrapperReadOrchardTreeAnchor
, rustWrapperReadOrchardTreeParts
@ -249,6 +250,10 @@ getOrchardTreeParts h =
withPureBorshVarBuffer $
rustWrapperReadOrchardTreeParts $ toBytes $ orchTree h
getOrchardPathAnchor :: HexString -> MerklePath -> HexString
getOrchardPathAnchor hex p =
withPureBorshVarBuffer $ rustWrapperReadOrchardPathAnchor p (hexBytes hex)
-- | Update a Orchard commitment tree
updateOrchardCommitmentTree ::
OrchardFrontier -- ^ the base tree