Functions to handle commitment tree nodes for Sapling and Orchard (#100)
This PR includes the functions for hashing commitment nodes for both Sapling and Orchard. It also includes functions to validate tree roots and Merkle paths. Reviewed-on: https://git.vergara.tech///Vergara_Tech/zcash-haskell/pulls/100 Co-authored-by: Rene Vergara <rene@vergara.network> Co-committed-by: Rene Vergara <rene@vergara.network>
This commit is contained in:
parent
62cda9cc15
commit
dea960c2ac
9 changed files with 403 additions and 97 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -5,6 +5,23 @@ 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.5.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Sapling commitment node functions
|
||||||
|
- Sapling Merkle path test
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgraded Rust dependencies to latest versions:
|
||||||
|
- `zcash_primitives` 0.19.0
|
||||||
|
- `zcash_client_backend` 0.14.0
|
||||||
|
- `orchard` 0.10.0
|
||||||
|
- `sapling-crypto` 0.3.0
|
||||||
|
- `incrementalmerkletree` 0.7.0
|
||||||
|
- `zip32` 0.1.2
|
||||||
|
|
||||||
## [0.7.4.0]
|
## [0.7.4.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
61
librustzcash-wrapper/Cargo.lock
generated
61
librustzcash-wrapper/Cargo.lock
generated
|
@ -60,9 +60,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.2"
|
version = "0.22.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
|
@ -757,9 +757,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "incrementalmerkletree"
|
name = "incrementalmerkletree"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75346da3bd8e3d8891d02508245ed2df34447ca6637e343829f8d08986e9cde2"
|
checksum = "d45063fbc4b0a37837f6bfe0445f269d13d730ad0aa3b5a7f74aa7bf27a0f4df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
@ -987,9 +987,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orchard"
|
name = "orchard"
|
||||||
version = "0.9.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4dc7bde644aeb980be296cd908c6650894dc8541deb56f9f5294c52ed7ca568f"
|
checksum = "4f18e997fa121de5c73e95cdc7e8512ae43b7de38904aeea5e5713cc48f3c0ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
|
@ -1379,9 +1379,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sapling-crypto"
|
name = "sapling-crypto"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15e379398fffad84e49f9a45a05635fc004f66086e65942dbf4eb95332c26d2a"
|
checksum = "cfff8cfce16aeb38da50b8e2ed33c9018f30552beff2210c266662a021b17f38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bellman",
|
"bellman",
|
||||||
|
@ -1488,9 +1488,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shardtree"
|
name = "shardtree"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78222845cd8bbe5eb95687407648ff17693a35de5e8abaa39a4681fb21e033f9"
|
checksum = "b5f2390975ebfe8838f9e861f7a588123d49a7a7a0a08568ea831d8ad53fc9b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
"either",
|
"either",
|
||||||
|
@ -1883,9 +1883,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_address"
|
name = "zcash_address"
|
||||||
version = "0.4.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6d26f21381dc220836dd8d2a9a10dbe85928a26232b011bc6a42b611789b743"
|
checksum = "4ff95eac82f71286a79c750e674550d64fb2b7aadaef7b89286b2917f645457d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32 0.9.1",
|
"bech32 0.9.1",
|
||||||
"bs58 0.5.0",
|
"bs58 0.5.0",
|
||||||
|
@ -1896,9 +1896,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_client_backend"
|
name = "zcash_client_backend"
|
||||||
version = "0.13.0"
|
version = "0.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80e3a0f3e5d7f299d8b7ef3237697630989c31ab1b162824c99c1cd8bc83715e"
|
checksum = "cbeeede366fdb642710d3c59fc2090489affd075f66db53ed11bb7138d2d0258"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bech32 0.9.1",
|
"bech32 0.9.1",
|
||||||
|
@ -1924,7 +1924,7 @@ dependencies = [
|
||||||
"tonic-build",
|
"tonic-build",
|
||||||
"tracing",
|
"tracing",
|
||||||
"which",
|
"which",
|
||||||
"zcash_address 0.4.0",
|
"zcash_address 0.6.0",
|
||||||
"zcash_encoding",
|
"zcash_encoding",
|
||||||
"zcash_keys",
|
"zcash_keys",
|
||||||
"zcash_note_encryption",
|
"zcash_note_encryption",
|
||||||
|
@ -1946,9 +1946,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_keys"
|
name = "zcash_keys"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712faf4070107ab0b2828d0eda6aeaf4c3cb02564109832d95b97ad3467c95a5"
|
checksum = "e8162c94957f1e379b8e2fb30f97b95cfa93ac9c6bc02895946ca6392d1abb81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bech32 0.9.1",
|
"bech32 0.9.1",
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
|
@ -1963,7 +1963,7 @@ dependencies = [
|
||||||
"secrecy",
|
"secrecy",
|
||||||
"subtle",
|
"subtle",
|
||||||
"tracing",
|
"tracing",
|
||||||
"zcash_address 0.4.0",
|
"zcash_address 0.6.0",
|
||||||
"zcash_encoding",
|
"zcash_encoding",
|
||||||
"zcash_primitives",
|
"zcash_primitives",
|
||||||
"zcash_protocol",
|
"zcash_protocol",
|
||||||
|
@ -1985,9 +1985,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_primitives"
|
name = "zcash_primitives"
|
||||||
version = "0.16.0"
|
version = "0.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f044bc9cf2887ec408196fbafb44749e5581f57cc18d8da7aabaeb60cc40c64"
|
checksum = "6ab47d526d7fd6f88b3a2854ad81b54757a80c2aeadd1d8b06f690556af9743c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"bip32",
|
"bip32",
|
||||||
|
@ -2014,7 +2014,7 @@ dependencies = [
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
"subtle",
|
"subtle",
|
||||||
"tracing",
|
"tracing",
|
||||||
"zcash_address 0.4.0",
|
"zcash_address 0.6.0",
|
||||||
"zcash_encoding",
|
"zcash_encoding",
|
||||||
"zcash_note_encryption",
|
"zcash_note_encryption",
|
||||||
"zcash_protocol",
|
"zcash_protocol",
|
||||||
|
@ -2024,9 +2024,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_protocol"
|
name = "zcash_protocol"
|
||||||
version = "0.2.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f35eac659fdbba614333d119217c5963c0d7cea43aee33176c4f2f95e5460d8d"
|
checksum = "6bc22b9155b2c7eb20105cd06de170d188c1bc86489b92aa3fda7b8da8d96acf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"document-features",
|
"document-features",
|
||||||
"memuse",
|
"memuse",
|
||||||
|
@ -2034,9 +2034,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zcash_spec"
|
name = "zcash_spec"
|
||||||
version = "0.1.0"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b"
|
checksum = "9cede95491c2191d3e278cab76e097a44b17fde8d6ca0d4e3a22cf4807b2d857"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
]
|
]
|
||||||
|
@ -2063,24 +2063,25 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip32"
|
name = "zip32"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4226d0aee9c9407c27064dfeec9d7b281c917de3374e1e5a2e2cfad9e09de19e"
|
checksum = "92022ac1e47c7b78f9cee29efac8a1a546e189506f3bb5ad46d525be7c519bf6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2b_simd",
|
"blake2b_simd",
|
||||||
"memuse",
|
"memuse",
|
||||||
"subtle",
|
"subtle",
|
||||||
|
"zcash_spec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip321"
|
name = "zip321"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8dc85f862f7be64fb0d46f9eb5b82ad54e58cde314fa979d5bae591bc0143693"
|
checksum = "1f3e613defb0940acef1f54774b51c7f48f2fa705613dd800870dc69f35cd2ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"nom",
|
"nom",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"zcash_address 0.4.0",
|
"zcash_address 0.6.0",
|
||||||
"zcash_protocol",
|
"zcash_protocol",
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,15 +11,15 @@ f4jumble = "0.1"
|
||||||
zcash_address = "0.2.0"
|
zcash_address = "0.2.0"
|
||||||
borsh = "0.10"
|
borsh = "0.10"
|
||||||
bech32 = "0.11"
|
bech32 = "0.11"
|
||||||
orchard = "0.9.0"
|
orchard = "0.10.0"
|
||||||
zcash_note_encryption = "0.4.0"
|
zcash_note_encryption = "0.4.0"
|
||||||
zcash_primitives = { version = "0.16.0", features = ["transparent-inputs"]}
|
zcash_primitives = { version = "0.19.0", features = ["transparent-inputs"]}
|
||||||
zcash_client_backend = "0.13.0"
|
zcash_client_backend = "0.14.0"
|
||||||
sapling-crypto = "0.2"
|
sapling-crypto = "0.3"
|
||||||
zip32 = "0.1.0"
|
zip32 = "0.1.2"
|
||||||
proc-macro2 = "1.0.66"
|
proc-macro2 = "1.0.66"
|
||||||
nonempty = "0.7.0"
|
nonempty = "0.7.0"
|
||||||
incrementalmerkletree = "0.6.0"
|
incrementalmerkletree = "0.7.0"
|
||||||
secp256k1 = "0.27.0"
|
secp256k1 = "0.27.0"
|
||||||
jubjub = "0.10.0"
|
jubjub = "0.10.0"
|
||||||
rand_core = { version = "0.6.4", features = ["getrandom"]}
|
rand_core = { version = "0.6.4", features = ["getrandom"]}
|
||||||
|
|
|
@ -570,11 +570,11 @@ impl Hspend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
pub struct HsaplingInput {
|
pub struct HsaplingInput {
|
||||||
sk: Vec<u8>,
|
sk: Vec<u8>,
|
||||||
note: Hnote,
|
note: Hnote,
|
||||||
iw: Vec<u8>
|
iw: Hpath
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<RW> FromHaskell<RW> for HsaplingInput {
|
impl<RW> FromHaskell<RW> for HsaplingInput {
|
||||||
|
@ -585,11 +585,11 @@ impl<RW> FromHaskell<RW> for HsaplingInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, BorshSerialize, BorshDeserialize)]
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
pub struct HorchardInput {
|
pub struct HorchardInput {
|
||||||
sk: Vec<u8>,
|
sk: Vec<u8>,
|
||||||
note: Hnote,
|
note: Hnote,
|
||||||
iw: Vec<u8>
|
iw: Hpath
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<RW> FromHaskell<RW> for HorchardInput {
|
impl<RW> FromHaskell<RW> for HorchardInput {
|
||||||
|
@ -1542,6 +1542,183 @@ pub extern "C" fn rust_wrapper_update_sapling_witness(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_read_sapling_node(
|
||||||
|
cmu: *const u8,
|
||||||
|
cmu_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
){
|
||||||
|
let node_in: Vec<u8> = marshall_from_haskell_var(cmu, cmu_len, RW);
|
||||||
|
let sapling_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in));
|
||||||
|
if sapling_note_comm.is_some().into() {
|
||||||
|
let n = Node::from_cmu(&sapling_note_comm.unwrap());
|
||||||
|
let h = Hhex { bytes: n.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_sapling_nodes(
|
||||||
|
level: u8,
|
||||||
|
left: *const u8,
|
||||||
|
left_len: usize,
|
||||||
|
right: *const u8,
|
||||||
|
right_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
){
|
||||||
|
let left_in: Vec<u8> = marshall_from_haskell_var(left, left_len, RW);
|
||||||
|
let right_in: Vec<u8> = marshall_from_haskell_var(right, right_len, RW);
|
||||||
|
if left_in.len() == 1 {
|
||||||
|
let n = Node::combine(Level::new(level), &Node::empty_leaf(), &Node::empty_leaf());
|
||||||
|
let h = Hhex { bytes: n.to_bytes().to_vec() };
|
||||||
|
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||||
|
} else {
|
||||||
|
let left_node = Node::from_bytes(to_array(left_in));
|
||||||
|
if left_node.is_some().into() {
|
||||||
|
if right_in.len() > 1 {
|
||||||
|
let right_node = Node::from_bytes(to_array(right_in));
|
||||||
|
if right_node.is_some().into() {
|
||||||
|
let n = Node::combine(Level::new(level), &left_node.unwrap(), &right_node.unwrap());
|
||||||
|
let h = Hhex { bytes: n.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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let n = Node::combine(Level::new(level), &left_node.unwrap(), &Node::empty_leaf());
|
||||||
|
let h = Hhex { bytes: n.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_get_sapling_root(
|
||||||
|
level: u8,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
){
|
||||||
|
let tree: CommitmentTree<Node, 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_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]
|
||||||
|
pub extern "C" fn rust_wrapper_read_sapling_tree_anchor(
|
||||||
|
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 root = c1.root();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_read_sapling_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 = sapling_crypto::MerklePath::from_parts(path_in.path.iter().map(|x|
|
||||||
|
if x.bytes.len() > 1 {
|
||||||
|
Node::from_bytes(to_array(x.bytes.clone())).unwrap()
|
||||||
|
} else {
|
||||||
|
Node::empty_leaf()
|
||||||
|
}).collect(), Position::from(u64::from(path_in.position)));
|
||||||
|
match mk_path {
|
||||||
|
Ok(mp1) => {
|
||||||
|
let nc = SaplingNoteCommitment::from_bytes(&to_array(cmx_in));
|
||||||
|
if nc.is_some().into() {
|
||||||
|
let anchor = mp1.root(Node::from_cmu(&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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_e) =>{
|
||||||
|
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_frontier(
|
pub extern "C" fn rust_wrapper_read_orchard_frontier(
|
||||||
tree: *const u8,
|
tree: *const u8,
|
||||||
|
@ -1696,7 +1873,13 @@ pub extern "C" fn rust_wrapper_read_orchard_path_anchor(
|
||||||
){
|
){
|
||||||
let path_in: Hpath = marshall_from_haskell_var(path, path_len, RW);
|
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 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 mk_path = orchard::tree::MerklePath::from_parts(path_in.position, to_array(path_in.path.iter().map(|x|
|
||||||
|
if x.bytes.len() > 1 {
|
||||||
|
MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap()
|
||||||
|
} else {
|
||||||
|
MerkleHashOrchard::empty_leaf()
|
||||||
|
}
|
||||||
|
).collect()));
|
||||||
let nc = ExtractedNoteCommitment::from_bytes(&to_array(cmx_in));
|
let nc = ExtractedNoteCommitment::from_bytes(&to_array(cmx_in));
|
||||||
if nc.is_some().into() {
|
if nc.is_some().into() {
|
||||||
let anchor = mk_path.root(nc.unwrap());
|
let anchor = mk_path.root(nc.unwrap());
|
||||||
|
@ -1967,47 +2150,26 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
out_len: &mut usize){
|
out_len: &mut usize){
|
||||||
let sap_input: Vec<HsaplingInput> = marshall_from_haskell_var(s_input, s_input_len, RW);
|
let sap_input: Vec<HsaplingInput> = marshall_from_haskell_var(s_input, s_input_len, RW);
|
||||||
let sap_anchor =
|
let sap_anchor_in: Vec<u8> = marshall_from_haskell_var(sap_wit, sap_wit_len, RW);
|
||||||
if sap_input.is_empty() {
|
let sap_anchor = Node::from_bytes(to_array(sap_anchor_in));
|
||||||
let sap_wit_in: Vec<u8> = marshall_from_haskell_var(sap_wit, sap_wit_len, RW);
|
let sapling_anchor =
|
||||||
let sap_wit_reader = Cursor::new(sap_wit_in);
|
if sap_anchor.is_some().into() {
|
||||||
let sap_iw = read_commitment_tree::<Node, Cursor<Vec<u8>>, SAPLING_DEPTH>(sap_wit_reader);
|
Some(SaplingAnchor::from(sap_anchor.unwrap()))
|
||||||
match sap_iw {
|
|
||||||
Ok(s_iw) => {
|
|
||||||
Some(SaplingAnchor::from(s_iw.root()))
|
|
||||||
},
|
|
||||||
Err(_e) => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let si = &sap_input[0];
|
None
|
||||||
let swit_reader = Cursor::new(&si.iw);
|
|
||||||
let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(swit_reader).unwrap();
|
|
||||||
Some(SaplingAnchor::from(iw.root()))
|
|
||||||
};
|
};
|
||||||
//println!("{:?}", sap_anchor);
|
//println!("{:?}", sapling_anchor);
|
||||||
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 =
|
let orch_anchor_in : Vec<u8> = marshall_from_haskell_var(orch_wit, orch_wit_len, RW);
|
||||||
if orch_input.is_empty() {
|
let orch_anchor = MerkleHashOrchard::from_bytes(&to_array(orch_anchor_in));
|
||||||
let orch_wit_in: Vec<u8> = marshall_from_haskell_var(orch_wit, orch_wit_len, RW);
|
let orchard_anchor =
|
||||||
let orch_wit_reader = Cursor::new(orch_wit_in);
|
if orch_anchor.is_some().into() {
|
||||||
let orch_iw = read_commitment_tree::<MerkleHashOrchard, Cursor<Vec<u8>>, 32>(orch_wit_reader);
|
Some(OrchardAnchor::from(orch_anchor.unwrap()))
|
||||||
match orch_iw {
|
|
||||||
Ok(o_iw) => {
|
|
||||||
Some(OrchardAnchor::from(o_iw.root()))
|
|
||||||
},
|
|
||||||
Err(_e) => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let oi = &orch_input[0];
|
None
|
||||||
let wit_reader = Cursor::new(&oi.iw);
|
|
||||||
let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
|
|
||||||
Some(OrchardAnchor::from(iw.root()))
|
|
||||||
};
|
};
|
||||||
let build_config = BuildConfig::Standard {sapling_anchor: sap_anchor, orchard_anchor: orch_anchor};
|
//println!("{:?}", orchard_anchor);
|
||||||
|
let build_config = BuildConfig::Standard {sapling_anchor, orchard_anchor};
|
||||||
let mut main_builder = Builder::new(MainNetwork, BlockHeight::from(bl_height), build_config);
|
let mut main_builder = Builder::new(MainNetwork, BlockHeight::from(bl_height), build_config);
|
||||||
let mut test_builder = Builder::new(TestNetwork, BlockHeight::from(bl_height), build_config);
|
let mut test_builder = Builder::new(TestNetwork, BlockHeight::from(bl_height), build_config);
|
||||||
let trans_input: Vec<HtransparentInput> = marshall_from_haskell_var(t_input, t_input_len, RW);
|
let trans_input: Vec<HtransparentInput> = marshall_from_haskell_var(t_input, t_input_len, RW);
|
||||||
|
@ -2047,9 +2209,13 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
Rseed::AfterZip212(to_array(s_in.note.rseed.bytes))
|
Rseed::AfterZip212(to_array(s_in.note.rseed.bytes))
|
||||||
};
|
};
|
||||||
let note = SaplingNote::from_parts(pay_addr, SaplingNoteValue::from_raw(s_in.note.note), rseed);
|
let note = SaplingNote::from_parts(pay_addr, SaplingNoteValue::from_raw(s_in.note.note), rseed);
|
||||||
let wit_reader = Cursor::new(s_in.iw);
|
let mk_path = sapling_crypto::MerklePath::from_parts(s_in.iw.path.iter().map(|x|
|
||||||
let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(wit_reader).unwrap();
|
if x.bytes.len() > 1 {
|
||||||
let merkle_path = iw.path().unwrap();
|
Node::from_bytes(to_array(x.bytes.clone())).unwrap()
|
||||||
|
} else {
|
||||||
|
Node::empty_leaf()
|
||||||
|
}).collect(), Position::from(u64::from(s_in.iw.position)));
|
||||||
|
let merkle_path = mk_path.unwrap();
|
||||||
if net {
|
if net {
|
||||||
let mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
|
let mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path);
|
||||||
match mb {
|
match mb {
|
||||||
|
@ -2090,16 +2256,22 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
let val = NoteValue::from_raw(o_in.note.note);
|
let val = NoteValue::from_raw(o_in.note.note);
|
||||||
//println!("o inp: {:?}", val);
|
//println!("o inp: {:?}", val);
|
||||||
let note = Note::from_parts(pay_addr, val, rho, rseed).unwrap();
|
let note = Note::from_parts(pay_addr, val, rho, rseed).unwrap();
|
||||||
let wit_reader = Cursor::new(o_in.iw);
|
let merkle_path = orchard::tree::MerklePath::from_parts(o_in.iw.position, to_array(o_in.iw.path.iter().map(|x|
|
||||||
let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
|
if x.bytes.len() > 1 {
|
||||||
let merkle_path = OrchardMerklePath::from(iw.path().unwrap());
|
MerkleHashOrchard::from_bytes(&to_array(x.bytes.clone())).unwrap()
|
||||||
|
} else {
|
||||||
|
MerkleHashOrchard::empty_leaf()
|
||||||
|
}
|
||||||
|
).collect()));
|
||||||
if net {
|
if net {
|
||||||
let mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
|
let mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
|
||||||
match mb {
|
match mb {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
|
//println!("added orchard inp: {:?}", val);
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Err(_e) => {
|
Err(e) => {
|
||||||
|
//println!("failed orchard inp: {:?}", e);
|
||||||
let x = Hhex {bytes: vec![7]};
|
let x = Hhex {bytes: vec![7]};
|
||||||
marshall_to_haskell_var(&x, out, out_len, RW);
|
marshall_to_haskell_var(&x, out, out_len, RW);
|
||||||
}
|
}
|
||||||
|
@ -2108,9 +2280,11 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
let tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
|
let tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path);
|
||||||
match tb {
|
match tb {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
|
//println!("added orchard inp: {:?}", val);
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Err(_e) => {
|
Err(e) => {
|
||||||
|
//println!("failed orchard inp: {:?}", e);
|
||||||
let x = Hhex {bytes: vec![7]};
|
let x = Hhex {bytes: vec![7]};
|
||||||
marshall_to_haskell_var(&x, out, out_len, RW);
|
marshall_to_haskell_var(&x, out, out_len, RW);
|
||||||
}
|
}
|
||||||
|
@ -2261,6 +2435,7 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
match e {
|
match e {
|
||||||
Error::InsufficientFunds(y) => {
|
Error::InsufficientFunds(y) => {
|
||||||
|
//println!("ins funds: {:?}", y);
|
||||||
let x = Hhex {bytes: vec![0]};
|
let x = Hhex {bytes: vec![0]};
|
||||||
marshall_to_haskell_var(&x, out, out_len, RW);
|
marshall_to_haskell_var(&x, out, out_len, RW);
|
||||||
},
|
},
|
||||||
|
|
|
@ -246,6 +246,51 @@ import ZcashHaskell.Types
|
||||||
-> `()'
|
-> `()'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_read_sapling_node as rustWrapperReadSaplingNode
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_combine_sapling_nodes as rustWrapperCombineSaplingNodes
|
||||||
|
{ `Int8'
|
||||||
|
, toBorshVar* `BS.ByteString'&
|
||||||
|
, toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_get_sapling_root as rustWrapperGetSaplingRootTest
|
||||||
|
{ `Int8'
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_read_sapling_commitment_tree_parts as rustWrapperReadSaplingTreeParts
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer SaplingRawTree'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_read_sapling_tree_anchor as rustWrapperReadSaplingTreeAnchor
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_read_sapling_path_anchor as rustWrapperReadSaplingPathAnchor
|
||||||
|
{ toBorshVar* `MerklePath'&
|
||||||
|
, toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
{# 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'&
|
||||||
|
|
|
@ -18,11 +18,17 @@
|
||||||
module ZcashHaskell.Sapling where
|
module ZcashHaskell.Sapling where
|
||||||
|
|
||||||
import C.Zcash
|
import C.Zcash
|
||||||
( rustWrapperDecodeSaplingAddress
|
( rustWrapperCombineSaplingNodes
|
||||||
|
, rustWrapperDecodeSaplingAddress
|
||||||
|
, rustWrapperGetSaplingRootTest
|
||||||
, rustWrapperIsShielded
|
, rustWrapperIsShielded
|
||||||
, rustWrapperReadSaplingCommitmentTree
|
, rustWrapperReadSaplingCommitmentTree
|
||||||
, rustWrapperReadSaplingFrontier
|
, rustWrapperReadSaplingFrontier
|
||||||
|
, rustWrapperReadSaplingNode
|
||||||
|
, rustWrapperReadSaplingPathAnchor
|
||||||
, rustWrapperReadSaplingPosition
|
, rustWrapperReadSaplingPosition
|
||||||
|
, rustWrapperReadSaplingTreeAnchor
|
||||||
|
, rustWrapperReadSaplingTreeParts
|
||||||
, rustWrapperReadSaplingWitness
|
, rustWrapperReadSaplingWitness
|
||||||
, rustWrapperSaplingCheck
|
, rustWrapperSaplingCheck
|
||||||
, rustWrapperSaplingChgPaymentAddress
|
, rustWrapperSaplingChgPaymentAddress
|
||||||
|
@ -38,6 +44,7 @@ import Data.Aeson
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Char8 as C
|
import qualified Data.ByteString.Char8 as C
|
||||||
import Data.HexString (HexString(..), fromText, hexString, toBytes, toText)
|
import Data.HexString (HexString(..), fromText, hexString, toBytes, toText)
|
||||||
|
import Data.Int (Int8)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Foreign.Rust.Marshall.Variable
|
import Foreign.Rust.Marshall.Variable
|
||||||
|
@ -185,6 +192,56 @@ genSaplingInternalAddress sk =
|
||||||
res =
|
res =
|
||||||
withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk)
|
withPureBorshVarBuffer (rustWrapperSaplingChgPaymentAddress $ getBytes sk)
|
||||||
|
|
||||||
|
getSaplingNodeValue :: BS.ByteString -> Maybe HexString
|
||||||
|
getSaplingNodeValue cmu =
|
||||||
|
if BS.length (hexBytes n) > 1
|
||||||
|
then Just n
|
||||||
|
else Nothing
|
||||||
|
where
|
||||||
|
n = withPureBorshVarBuffer $ rustWrapperReadSaplingNode cmu
|
||||||
|
|
||||||
|
combineSaplingNodes :: Int8 -> HexString -> HexString -> Maybe HexString
|
||||||
|
combineSaplingNodes level n1 n2 =
|
||||||
|
if BS.length (hexBytes r) > 1
|
||||||
|
then Just r
|
||||||
|
else Nothing
|
||||||
|
where
|
||||||
|
r =
|
||||||
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperCombineSaplingNodes level (toBytes n1) (toBytes n2)
|
||||||
|
|
||||||
|
getSaplingRootTest :: Int8 -> HexString
|
||||||
|
getSaplingRootTest 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
|
||||||
|
|
||||||
|
getSaplingTreeAnchor :: SaplingCommitmentTree -> HexString
|
||||||
|
getSaplingTreeAnchor tree =
|
||||||
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperReadSaplingTreeAnchor $ toBytes $ sapTree tree
|
||||||
|
|
||||||
|
getSaplingPathAnchor :: HexString -> MerklePath -> HexString
|
||||||
|
getSaplingPathAnchor hex p =
|
||||||
|
withPureBorshVarBuffer $ rustWrapperReadSaplingPathAnchor p (hexBytes hex)
|
||||||
|
|
||||||
getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier
|
getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier
|
||||||
getSaplingFrontier tree =
|
getSaplingFrontier tree =
|
||||||
if sf_pos updatedTree > 1
|
if sf_pos updatedTree > 1
|
||||||
|
|
|
@ -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
|
||||||
|
{ st_left :: !(Maybe HexString)
|
||||||
|
, st_right :: !(Maybe HexString)
|
||||||
|
, st_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
|
||||||
|
@ -797,7 +812,7 @@ data TransparentTxSpend = TransparentTxSpend
|
||||||
data SaplingTxSpend = SaplingTxSpend
|
data SaplingTxSpend = SaplingTxSpend
|
||||||
{ ss_sk :: !BS.ByteString
|
{ ss_sk :: !BS.ByteString
|
||||||
, ss_note :: !DecodedNote
|
, ss_note :: !DecodedNote
|
||||||
, ss_iw :: !BS.ByteString
|
, ss_iw :: !MerklePath
|
||||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
|
@ -806,7 +821,7 @@ data SaplingTxSpend = SaplingTxSpend
|
||||||
data OrchardTxSpend = OrchardTxSpend
|
data OrchardTxSpend = OrchardTxSpend
|
||||||
{ ss_sk :: !BS.ByteString
|
{ ss_sk :: !BS.ByteString
|
||||||
, ss_note :: !DecodedNote
|
, ss_note :: !DecodedNote
|
||||||
, ss_iw :: !BS.ByteString
|
, ss_iw :: !MerklePath
|
||||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
|
|
|
@ -123,8 +123,8 @@ readZebraTransaction hex =
|
||||||
rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex
|
rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex
|
||||||
|
|
||||||
createTransaction ::
|
createTransaction ::
|
||||||
Maybe SaplingCommitmentTree -- ^ to obtain the Sapling anchor
|
HexString -- ^ to obtain the Sapling anchor
|
||||||
-> Maybe OrchardCommitmentTree -- ^ to obtain the Orchard anchor
|
-> HexString -- ^ to obtain the Orchard anchor
|
||||||
-> [TransparentTxSpend] -- ^ the list of transparent notes to spend
|
-> [TransparentTxSpend] -- ^ the list of transparent notes to spend
|
||||||
-> [SaplingTxSpend] -- ^ the list of Sapling notes to spend
|
-> [SaplingTxSpend] -- ^ the list of Sapling notes to spend
|
||||||
-> [OrchardTxSpend] -- ^ the list of Orchard notes to spend
|
-> [OrchardTxSpend] -- ^ the list of Orchard notes to spend
|
||||||
|
@ -137,12 +137,8 @@ createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing znet bh bui
|
||||||
txResult <-
|
txResult <-
|
||||||
withBorshBufferOfInitSize 51200 $
|
withBorshBufferOfInitSize 51200 $
|
||||||
rustWrapperCreateTx
|
rustWrapperCreateTx
|
||||||
(case sapAnchor of
|
(hexBytes sapAnchor)
|
||||||
Nothing -> "0"
|
(hexBytes orchAnchor)
|
||||||
Just sA -> toBytes $ sapTree sA)
|
|
||||||
(case orchAnchor of
|
|
||||||
Nothing -> "0"
|
|
||||||
Just oA -> toBytes $ orchTree oA)
|
|
||||||
tSpend
|
tSpend
|
||||||
sSpend
|
sSpend
|
||||||
oSpend
|
oSpend
|
||||||
|
|
|
@ -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.4.0
|
version: 0.7.5.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
|
||||||
|
|
Loading…
Reference in a new issue