Functions to create and manage Orchard commitment trees (#99)
This PR contains the functions to create, update and validate Orchard commitment trees. Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/99 Co-authored-by: Rene Vergara <rene@vergara.network> Co-committed-by: Rene Vergara <rene@vergara.network>
This commit is contained in:
parent
6d4b6840d3
commit
5ce149c54f
4 changed files with 273 additions and 11 deletions
|
@ -36,7 +36,8 @@ use incrementalmerkletree::{
|
||||||
frontier::{
|
frontier::{
|
||||||
CommitmentTree,
|
CommitmentTree,
|
||||||
Frontier,
|
Frontier,
|
||||||
NonEmptyFrontier
|
NonEmptyFrontier,
|
||||||
|
PathFiller
|
||||||
},
|
},
|
||||||
witness::IncrementalWitness
|
witness::IncrementalWitness
|
||||||
};
|
};
|
||||||
|
@ -271,6 +272,12 @@ impl<RW> ToHaskell<RW> for Hhex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<RW> FromHaskell<RW> for Hhex {
|
||||||
|
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||||
|
let x = Hhex::deserialize(buf)?;
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Haction {
|
pub struct Haction {
|
||||||
|
@ -716,6 +723,47 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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] {
|
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()))
|
||||||
}
|
}
|
||||||
|
@ -1513,7 +1561,13 @@ pub extern "C" fn rust_wrapper_read_orchard_frontier(
|
||||||
Some(f2) => {
|
Some(f2) => {
|
||||||
let (pos, leaf, omm) = f2.clone().into_parts();
|
let (pos, leaf, omm) = f2.clone().into_parts();
|
||||||
let f = Hfrontier { position: <u64>::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()};
|
let f = Hfrontier { position: <u64>::from(pos), leaf: Hhex { bytes: leaf.to_bytes().to_vec()}, ommers: omm.iter().map(|&x| Hhex { bytes: x.to_bytes().to_vec()}).collect()};
|
||||||
|
let comm_tree2: Frontier<MerkleHashOrchard,32> = Frontier::from_parts(Position::from(f.position), MerkleHashOrchard::from_bytes(&to_array(f.leaf.bytes.clone())).unwrap(), f.ommers.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() ).collect()).unwrap();
|
||||||
|
if f1.root() == comm_tree2.root() {
|
||||||
marshall_to_haskell_var(&f, out, out_len, RW);
|
marshall_to_haskell_var(&f, out, out_len, RW);
|
||||||
|
} else {
|
||||||
|
let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]};
|
||||||
|
marshall_to_haskell_var(&f0, out, out_len, RW);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]};
|
let f0 = Hfrontier { position: 0, leaf: Hhex { bytes: vec![0]}, ommers: vec![Hhex { bytes: vec![0]}]};
|
||||||
|
@ -1535,12 +1589,66 @@ pub extern "C" fn rust_wrapper_read_orchard_tree_anchor(
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
out_len: &mut usize
|
out_len: &mut usize
|
||||||
){
|
){
|
||||||
let tree_in: Hfrontier = marshall_from_haskell_var(tree, tree_len, RW);
|
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW);
|
||||||
let leaf = MerkleHashOrchard::from_bytes(&to_array(tree_in.leaf.bytes)).unwrap();
|
let tree_reader = Cursor::new(tree_in);
|
||||||
let comm_tree: NonEmptyFrontier<MerkleHashOrchard> = NonEmptyFrontier::from_parts(Position::from(tree_in.position), leaf, tree_in.ommers.iter().map(|x| MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap() ).collect()).unwrap();
|
let comm_tree = read_commitment_tree(tree_reader);
|
||||||
let root = comm_tree.root(None);
|
match comm_tree {
|
||||||
|
Ok::<CommitmentTree<MerkleHashOrchard, 32>, _>(c1) => {
|
||||||
|
let root = c1.root();
|
||||||
let h = Hhex { bytes: root.to_bytes().to_vec() };
|
let h = Hhex { bytes: root.to_bytes().to_vec() };
|
||||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
let h0 = Hhex { bytes: vec![0] };
|
||||||
|
marshall_to_haskell_var(&h0, 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]
|
||||||
|
@ -1577,6 +1685,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]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_wrapper_combine_orchard_nodes(
|
pub extern "C" fn rust_wrapper_combine_orchard_nodes(
|
||||||
level: u8,
|
level: u8,
|
||||||
|
@ -1618,6 +1749,47 @@ pub extern "C" fn rust_wrapper_combine_orchard_nodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_get_orchard_root(
|
||||||
|
level: u8,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
){
|
||||||
|
let tree: CommitmentTree<MerkleHashOrchard, 32> = CommitmentTree::empty();
|
||||||
|
let root = tree.root();
|
||||||
|
let h = Hhex { bytes: root.to_bytes().to_vec() };
|
||||||
|
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_orchard_add_node(
|
||||||
|
level: u8,
|
||||||
|
node: *const u8,
|
||||||
|
node_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
){
|
||||||
|
let mut tree: CommitmentTree<MerkleHashOrchard, 32> = CommitmentTree::empty();
|
||||||
|
let node_in: Vec<u8> = marshall_from_haskell_var(node, node_len, RW);
|
||||||
|
let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in));
|
||||||
|
if orchard_note_comm.is_some().into() {
|
||||||
|
let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap());
|
||||||
|
match tree.append(n) {
|
||||||
|
Ok(()) => {
|
||||||
|
let root = tree.root_at_depth(level, PathFiller::empty());
|
||||||
|
let h = Hhex { bytes: root.to_bytes().to_vec() };
|
||||||
|
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_wrapper_read_orchard_commitment_tree(
|
pub extern "C" fn rust_wrapper_read_orchard_commitment_tree(
|
||||||
|
|
|
@ -263,7 +263,7 @@ import ZcashHaskell.Types
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_read_orchard_tree_anchor as rustWrapperReadOrchardTreeAnchor
|
{# fun unsafe rust_wrapper_read_orchard_tree_anchor as rustWrapperReadOrchardTreeAnchor
|
||||||
{ toBorshVar* `OrchardFrontier'&
|
{ toBorshVar* `BS.ByteString'&
|
||||||
, getVarBuffer `Buffer HexString'&
|
, getVarBuffer `Buffer HexString'&
|
||||||
}
|
}
|
||||||
-> `()'
|
-> `()'
|
||||||
|
@ -276,6 +276,21 @@ 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'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_read_orchard_commitment_tree as rustWrapperReadOrchardCommitmentTree
|
{# fun unsafe rust_wrapper_read_orchard_commitment_tree as rustWrapperReadOrchardCommitmentTree
|
||||||
{ toBorshVar* `OrchardFrontier'&
|
{ toBorshVar* `OrchardFrontier'&
|
||||||
, toBorshVar* `BS.ByteString'&
|
, toBorshVar* `BS.ByteString'&
|
||||||
|
@ -284,6 +299,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'&
|
||||||
|
@ -304,6 +326,15 @@ import ZcashHaskell.Types
|
||||||
-> `Word64'
|
-> `Word64'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_orchard_add_node as rustWrapperOrchardAddNodeTest
|
||||||
|
{ `Int8'
|
||||||
|
, toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
|
||||||
|
#}
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_update_sapling_witness as rustWrapperUpdateSaplingWitness
|
{# fun unsafe rust_wrapper_update_sapling_witness as rustWrapperUpdateSaplingWitness
|
||||||
{ toBorshVar* `BS.ByteString'&
|
{ toBorshVar* `BS.ByteString'&
|
||||||
, toBorshVar* `[BS.ByteString]'&
|
, toBorshVar* `[BS.ByteString]'&
|
||||||
|
|
|
@ -21,14 +21,18 @@ import C.Zcash
|
||||||
( rustWrapperCombineOrchardNodes
|
( rustWrapperCombineOrchardNodes
|
||||||
, rustWrapperGenOrchardReceiver
|
, rustWrapperGenOrchardReceiver
|
||||||
, rustWrapperGenOrchardSpendKey
|
, rustWrapperGenOrchardSpendKey
|
||||||
|
, rustWrapperGetOrchardRootTest
|
||||||
|
, rustWrapperOrchardAddNodeTest
|
||||||
, rustWrapperOrchardCheck
|
, rustWrapperOrchardCheck
|
||||||
, rustWrapperOrchardNoteDecode
|
, rustWrapperOrchardNoteDecode
|
||||||
, rustWrapperOrchardNoteDecodeSK
|
, rustWrapperOrchardNoteDecodeSK
|
||||||
, rustWrapperReadOrchardCommitmentTree
|
, rustWrapperReadOrchardCommitmentTree
|
||||||
, rustWrapperReadOrchardFrontier
|
, rustWrapperReadOrchardFrontier
|
||||||
, rustWrapperReadOrchardNode
|
, rustWrapperReadOrchardNode
|
||||||
|
, rustWrapperReadOrchardPathAnchor
|
||||||
, rustWrapperReadOrchardPosition
|
, rustWrapperReadOrchardPosition
|
||||||
, rustWrapperReadOrchardTreeAnchor
|
, rustWrapperReadOrchardTreeAnchor
|
||||||
|
, rustWrapperReadOrchardTreeParts
|
||||||
, rustWrapperReadOrchardWitness
|
, rustWrapperReadOrchardWitness
|
||||||
, rustWrapperReadOrchardWitnessAnchor
|
, rustWrapperReadOrchardWitnessAnchor
|
||||||
, rustWrapperUADecode
|
, rustWrapperUADecode
|
||||||
|
@ -209,15 +213,47 @@ getOrchardFrontier tree =
|
||||||
withPureBorshVarBuffer $
|
withPureBorshVarBuffer $
|
||||||
rustWrapperReadOrchardFrontier $ toBytes $ orchTree tree
|
rustWrapperReadOrchardFrontier $ toBytes $ orchTree tree
|
||||||
|
|
||||||
getOrchardTreeAnchor :: OrchardFrontier -> HexString
|
getOrchardTreeAnchor :: OrchardCommitmentTree -> HexString
|
||||||
getOrchardTreeAnchor tree =
|
getOrchardTreeAnchor tree =
|
||||||
withPureBorshVarBuffer $ rustWrapperReadOrchardTreeAnchor tree
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperReadOrchardTreeAnchor $ toBytes $ orchTree tree
|
||||||
|
|
||||||
getOrchardWitnessAnchor :: OrchardWitness -> HexString
|
getOrchardWitnessAnchor :: OrchardWitness -> HexString
|
||||||
getOrchardWitnessAnchor wit =
|
getOrchardWitnessAnchor wit =
|
||||||
withPureBorshVarBuffer $
|
withPureBorshVarBuffer $
|
||||||
rustWrapperReadOrchardWitnessAnchor $ toBytes $ orchWit wit
|
rustWrapperReadOrchardWitnessAnchor $ toBytes $ orchWit wit
|
||||||
|
|
||||||
|
getOrchardRootTest :: Int -> HexString
|
||||||
|
getOrchardRootTest level =
|
||||||
|
withPureBorshVarBuffer $ rustWrapperGetOrchardRootTest $ fromIntegral level
|
||||||
|
|
||||||
|
addOrchardNodeGetRoot :: Int -> BS.ByteString -> HexString
|
||||||
|
addOrchardNodeGetRoot 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
|
||||||
|
|
||||||
|
getOrchardPathAnchor :: HexString -> MerklePath -> HexString
|
||||||
|
getOrchardPathAnchor hex p =
|
||||||
|
withPureBorshVarBuffer $ rustWrapperReadOrchardPathAnchor p (hexBytes hex)
|
||||||
|
|
||||||
-- | Update a Orchard commitment tree
|
-- | Update a Orchard commitment tree
|
||||||
updateOrchardCommitmentTree ::
|
updateOrchardCommitmentTree ::
|
||||||
OrchardFrontier -- ^ the base tree
|
OrchardFrontier -- ^ the base tree
|
||||||
|
|
|
@ -722,11 +722,34 @@ instance FromJSON OrchardAction where
|
||||||
a <- obj .: "spendAuthSig"
|
a <- obj .: "spendAuthSig"
|
||||||
pure $ OrchardAction n r c ephKey encText outText cval a
|
pure $ OrchardAction n r c ephKey encText outText cval a
|
||||||
|
|
||||||
|
data MerklePath = MerklePath
|
||||||
|
{ mp_position :: !Int32
|
||||||
|
, mp_path :: ![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 MerklePath
|
||||||
|
|
||||||
-- | Type for a Orchard note commitment tree
|
-- | Type for a Orchard note commitment tree
|
||||||
newtype OrchardCommitmentTree = OrchardCommitmentTree
|
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