Add witness update functionality
This commit is contained in:
parent
b74cd5f354
commit
af9806d72d
6 changed files with 127 additions and 23 deletions
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -5,14 +5,21 @@ 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.5.5.4]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Functions to update Sapling witnesses.
|
||||||
|
- Functions to update Orchard witnesses.
|
||||||
|
|
||||||
## [0.5.5.3]
|
## [0.5.5.3]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added unction to generate an ExchangeAddress in Human Readable Format Using a TransparentAddress in HRF
|
- Added function to generate an `ExchangeAddress` in Human Readable Format Using a `TransparentAddress` in HRF
|
||||||
`encodeExchangeAddress` a function to create a ExchangeAddress in HRF
|
- `encodeExchangeAddress` a function to create a `ExchangeAddress` in HRF
|
||||||
`decodeExchangeAddress` a function to obtaina a TransparentAddress object from an ExchangeAddress in HRF
|
- `decodeExchangeAddress` a function to obtain a `TransparentAddress` object from an `ExchangeAddress` in HRF
|
||||||
- Added new type ExchangeAddress
|
- Added new type `ExchangeAddress`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -1251,6 +1251,40 @@ pub extern "C" fn rust_wrapper_read_sapling_position(
|
||||||
return u64::from(pos);
|
return u64::from(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_update_sapling_witness(
|
||||||
|
wit: *const u8,
|
||||||
|
wit_len: usize,
|
||||||
|
cmus: *const u8,
|
||||||
|
cmus_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
) {
|
||||||
|
let wit_in: Vec<u8> = marshall_from_haskell_var(wit, wit_len, RW);
|
||||||
|
let wit_reader = Cursor::new(wit_in);
|
||||||
|
let mut iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(wit_reader).unwrap();
|
||||||
|
let cmu: Vec<Vec<u8>> = marshall_from_haskell_var(cmus, cmus_len, RW);
|
||||||
|
for c in cmu {
|
||||||
|
let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(c));
|
||||||
|
if sap_note_comm.is_some().into() {
|
||||||
|
let n = Node::from_cmu(&sap_note_comm.unwrap());
|
||||||
|
iw.append(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut out_bytes: Vec<u8> = Vec::new();
|
||||||
|
let result = write_incremental_witness(&iw, &mut out_bytes);
|
||||||
|
match result {
|
||||||
|
Ok(()) => {
|
||||||
|
let h = Hhex { bytes: out_bytes};
|
||||||
|
marshall_to_haskell_var(&h, 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_commitment_tree(
|
pub extern "C" fn rust_wrapper_read_orchard_commitment_tree(
|
||||||
tree: *const u8,
|
tree: *const u8,
|
||||||
|
@ -1340,6 +1374,40 @@ pub extern "C" fn rust_wrapper_read_orchard_position(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_wrapper_update_orchard_witness(
|
||||||
|
wit: *const u8,
|
||||||
|
wit_len: usize,
|
||||||
|
cm: *const u8,
|
||||||
|
cm_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize
|
||||||
|
) {
|
||||||
|
let wit_in: Vec<u8> = marshall_from_haskell_var(wit, wit_len, RW);
|
||||||
|
let wit_reader = Cursor::new(wit_in);
|
||||||
|
let mut iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
|
||||||
|
let cmu: Vec<Vec<u8>> = marshall_from_haskell_var(cm, cm_len, RW);
|
||||||
|
for c in cmu {
|
||||||
|
let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(c));
|
||||||
|
if orchard_note_comm.is_some().into() {
|
||||||
|
let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap());
|
||||||
|
iw.append(n);
|
||||||
|
}
|
||||||
|
let mut out_bytes: Vec<u8> = Vec::new();
|
||||||
|
let result = write_incremental_witness(&iw, &mut out_bytes);
|
||||||
|
match result {
|
||||||
|
Ok(()) => {
|
||||||
|
let h = Hhex { bytes: out_bytes};
|
||||||
|
marshall_to_haskell_var(&h, 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_decode_sapling_address(
|
pub extern "C" fn rust_wrapper_decode_sapling_address(
|
||||||
sapling: *const u8,
|
sapling: *const u8,
|
||||||
|
|
|
@ -259,3 +259,19 @@ import ZcashHaskell.Types
|
||||||
}
|
}
|
||||||
-> `Word64'
|
-> `Word64'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_update_sapling_witness as rustWrapperUpdateSaplingWitness
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, toBorshVar* `[BS.ByteString]'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
||||||
|
{# fun unsafe rust_wrapper_update_orchard_witness as rustWrapperUpdateOrchardWitness
|
||||||
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, toBorshVar* `[BS.ByteString]'&
|
||||||
|
, getVarBuffer `Buffer HexString'&
|
||||||
|
}
|
||||||
|
-> `()'
|
||||||
|
#}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import C.Zcash
|
||||||
, rustWrapperReadOrchardWitness
|
, rustWrapperReadOrchardWitness
|
||||||
, rustWrapperUADecode
|
, rustWrapperUADecode
|
||||||
, rustWrapperUfvkDecode
|
, rustWrapperUfvkDecode
|
||||||
|
, rustWrapperUpdateOrchardWitness
|
||||||
)
|
)
|
||||||
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
|
||||||
|
@ -219,3 +220,9 @@ getOrchardWitness tree =
|
||||||
getOrchardNotePosition :: OrchardWitness -> Integer
|
getOrchardNotePosition :: OrchardWitness -> Integer
|
||||||
getOrchardNotePosition =
|
getOrchardNotePosition =
|
||||||
fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit
|
fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit
|
||||||
|
|
||||||
|
updateOrchardWitness :: OrchardWitness -> [HexString] -> OrchardWitness
|
||||||
|
updateOrchardWitness wit cmus =
|
||||||
|
OrchardWitness $
|
||||||
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperUpdateOrchardWitness (toBytes $ orchWit wit) (map toBytes cmus)
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
module ZcashHaskell.Sapling where
|
module ZcashHaskell.Sapling where
|
||||||
|
|
||||||
import C.Zcash
|
import C.Zcash
|
||||||
( rustWrapperIsShielded
|
( rustWrapperDecodeSaplingAddress
|
||||||
|
, rustWrapperIsShielded
|
||||||
, rustWrapperReadSaplingCommitmentTree
|
, rustWrapperReadSaplingCommitmentTree
|
||||||
, rustWrapperReadSaplingPosition
|
, rustWrapperReadSaplingPosition
|
||||||
, rustWrapperReadSaplingWitness
|
, rustWrapperReadSaplingWitness
|
||||||
, rustWrapperDecodeSaplingAddress
|
|
||||||
, rustWrapperSaplingCheck
|
, rustWrapperSaplingCheck
|
||||||
, rustWrapperSaplingChgPaymentAddress
|
, rustWrapperSaplingChgPaymentAddress
|
||||||
, rustWrapperSaplingDecodeEsk
|
, rustWrapperSaplingDecodeEsk
|
||||||
|
@ -31,18 +31,19 @@ import C.Zcash
|
||||||
, rustWrapperSaplingSpendingkey
|
, rustWrapperSaplingSpendingkey
|
||||||
, rustWrapperSaplingVkDecode
|
, rustWrapperSaplingVkDecode
|
||||||
, rustWrapperTxParse
|
, rustWrapperTxParse
|
||||||
|
, rustWrapperUpdateSaplingWitness
|
||||||
)
|
)
|
||||||
import Data.Aeson
|
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 qualified Data.Text as T
|
|
||||||
import Data.HexString (HexString(..), fromText, hexString, toBytes, toText)
|
import Data.HexString (HexString(..), fromText, hexString, toBytes, toText)
|
||||||
|
import qualified Data.Text as T
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Foreign.Rust.Marshall.Variable
|
import Foreign.Rust.Marshall.Variable
|
||||||
( withPureBorshVarBuffer
|
( withPureBorshVarBuffer
|
||||||
, withPureBorshVarBuffer
|
, withPureBorshVarBuffer
|
||||||
)
|
)
|
||||||
import ZcashHaskell.Types
|
import ZcashHaskell.Types
|
||||||
import ZcashHaskell.Utils (decodeBech32, encodeBech32, encodeBech32m)
|
import ZcashHaskell.Utils (decodeBech32, encodeBech32, encodeBech32m)
|
||||||
|
|
||||||
-- | Check if given bytesting is a valid encoded shielded address
|
-- | Check if given bytesting is a valid encoded shielded address
|
||||||
|
@ -192,32 +193,37 @@ getSaplingNotePosition :: SaplingWitness -> Integer
|
||||||
getSaplingNotePosition =
|
getSaplingNotePosition =
|
||||||
fromIntegral . rustWrapperReadSaplingPosition . hexBytes . sapWit
|
fromIntegral . rustWrapperReadSaplingPosition . hexBytes . sapWit
|
||||||
|
|
||||||
|
updateSaplingWitness :: SaplingWitness -> [HexString] -> SaplingWitness
|
||||||
|
updateSaplingWitness wit cmus =
|
||||||
|
SaplingWitness $
|
||||||
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperUpdateSaplingWitness (toBytes $ sapWit wit) (map toBytes cmus)
|
||||||
|
|
||||||
-- | Encode a SaplingReceiver into HRF text
|
-- | Encode a SaplingReceiver into HRF text
|
||||||
encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text
|
encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text
|
||||||
encodeSaplingAddress net sr = do
|
encodeSaplingAddress net sr = do
|
||||||
case net of
|
case net of
|
||||||
MainNet ->
|
MainNet -> Just $ encodeBech32 (C.pack sapPaymentAddressHrp) (getBytes sr)
|
||||||
Just $ encodeBech32 (C.pack sapPaymentAddressHrp) (getBytes sr)
|
|
||||||
TestNet ->
|
TestNet ->
|
||||||
Just $ encodeBech32 (C.pack sapTestPaymentAddressHrp) (getBytes sr)
|
Just $ encodeBech32 (C.pack sapTestPaymentAddressHrp) (getBytes sr)
|
||||||
|
|
||||||
-- | Helper to get de Nework Id from FFI response
|
-- | Helper to get de Nework Id from FFI response
|
||||||
getNetId:: [Word8] -> ZcashNet
|
getNetId :: [Word8] -> ZcashNet
|
||||||
getNetId [x] = do
|
getNetId [x] = do
|
||||||
case x of
|
case x of
|
||||||
1 -> MainNet
|
1 -> MainNet
|
||||||
2 -> TestNet
|
2 -> TestNet
|
||||||
|
|
||||||
-- | decode a Sapling address
|
-- | decode a Sapling address
|
||||||
decodeSaplingAddress :: BS.ByteString -> Maybe SaplingAddress
|
decodeSaplingAddress :: BS.ByteString -> Maybe SaplingAddress
|
||||||
decodeSaplingAddress sapling_address = do
|
decodeSaplingAddress sapling_address = do
|
||||||
if BS.length sa > 1
|
if BS.length sa > 1
|
||||||
then do
|
then do
|
||||||
let sa0 = BS.unpack sa
|
let sa0 = BS.unpack sa
|
||||||
Just $ SaplingAddress (getNetId (take 1 sa0))
|
Just $
|
||||||
$ SaplingReceiver (BS.pack (drop 1 sa0))
|
SaplingAddress (getNetId (take 1 sa0)) $
|
||||||
|
SaplingReceiver (BS.pack (drop 1 sa0))
|
||||||
else Nothing
|
else Nothing
|
||||||
where
|
where
|
||||||
sa =
|
sa =
|
||||||
withPureBorshVarBuffer $
|
withPureBorshVarBuffer $ rustWrapperDecodeSaplingAddress sapling_address
|
||||||
rustWrapperDecodeSaplingAddress sapling_address
|
|
||||||
|
|
|
@ -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.5.5.3
|
version: 0.5.5.4
|
||||||
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