diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cbfed3..c817ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.7.5.0] + +### Added + +- Sapling commitment node functions + ## [0.7.4.0] ### Added diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index feeb16c..8170650 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -1561,6 +1561,47 @@ pub extern "C" fn rust_wrapper_read_sapling_node( } } +#[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 = marshall_from_haskell_var(left, left_len, RW); + let right_in: Vec = 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_read_orchard_frontier( tree: *const u8, diff --git a/src/C/Zcash.chs b/src/C/Zcash.chs index 48e3189..06b486a 100644 --- a/src/C/Zcash.chs +++ b/src/C/Zcash.chs @@ -253,6 +253,15 @@ import ZcashHaskell.Types -> `()' #} +{# fun unsafe rust_wrapper_combine_sapling_nodes as rustWrapperCombineSaplingNodes + { `Int8' + , toBorshVar* `BS.ByteString'& + , toBorshVar* `BS.ByteString'& + , getVarBuffer `Buffer HexString'& + } + -> `()' +#} + {# fun unsafe rust_wrapper_read_orchard_node as rustWrapperReadOrchardNode { toBorshVar* `BS.ByteString'& , getVarBuffer `Buffer HexString'& diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index 8cbe12c..c7fe8e2 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -18,7 +18,8 @@ module ZcashHaskell.Sapling where import C.Zcash - ( rustWrapperDecodeSaplingAddress + ( rustWrapperCombineSaplingNodes + , rustWrapperDecodeSaplingAddress , rustWrapperIsShielded , rustWrapperReadSaplingCommitmentTree , rustWrapperReadSaplingFrontier @@ -39,6 +40,7 @@ import Data.Aeson import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as C import Data.HexString (HexString(..), fromText, hexString, toBytes, toText) +import Data.Int (Int8) import qualified Data.Text as T import Data.Word import Foreign.Rust.Marshall.Variable @@ -194,6 +196,16 @@ getSaplingNodeValue cmu = 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) + getSaplingFrontier :: SaplingCommitmentTree -> Maybe SaplingFrontier getSaplingFrontier tree = if sf_pos updatedTree > 1 diff --git a/zcash-haskell.cabal b/zcash-haskell.cabal index 3216af8..c1d1d82 100644 --- a/zcash-haskell.cabal +++ b/zcash-haskell.cabal @@ -5,7 +5,7 @@ cabal-version: 3.0 -- see: https://github.com/sol/hpack name: zcash-haskell -version: 0.7.4.0 +version: 0.7.5.0 synopsis: Utilities to interact with the Zcash blockchain description: Please see the README on the repo at category: Blockchain