Merge pull request #361 from str4d/release-0.5-prep

Release 0.5 preparations
This commit is contained in:
str4d 2021-03-26 14:45:26 +13:00 committed by GitHub
commit 44e3176d5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 97 additions and 48 deletions

View File

@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
bech32 = "0.7" bech32 = "0.8"
bls12_381 = "0.3.1" bls12_381 = "0.3.1"
bs58 = { version = "0.4", features = ["check"] } bs58 = { version = "0.4", features = ["check"] }
base64 = "0.13" base64 = "0.13"

View File

@ -187,11 +187,21 @@ pub struct PrunedBlock<'a> {
pub transactions: &'a Vec<WalletTx<Nullifier>>, pub transactions: &'a Vec<WalletTx<Nullifier>>,
} }
/// A transaction that was detected during scanning of the blockchain,
/// including its decrypted Sapling outputs.
///
/// The purpose of this struct is to permit atomic updates of the
/// wallet database when transactions are successfully decrypted.
pub struct ReceivedTransaction<'a> { pub struct ReceivedTransaction<'a> {
pub tx: &'a Transaction, pub tx: &'a Transaction,
pub outputs: &'a Vec<DecryptedOutput>, pub outputs: &'a Vec<DecryptedOutput>,
} }
/// A transaction that was constructed and sent by the wallet.
///
/// The purpose of this struct is to permit atomic updates of the
/// wallet database when transactions are created and submitted
/// to the network.
pub struct SentTransaction<'a> { pub struct SentTransaction<'a> {
pub tx: &'a Transaction, pub tx: &'a Transaction,
pub created: time::OffsetDateTime, pub created: time::OffsetDateTime,

View File

@ -192,8 +192,9 @@ where
/// caller is handling rollbacks. /// caller is handling rollbacks.
/// ///
/// For brand-new light client databases, this function starts scanning from the Sapling /// For brand-new light client databases, this function starts scanning from the Sapling
/// activation height. This height can be fast-forwarded to a more recent block by calling /// activation height. This height can be fast-forwarded to a more recent block by
/// [`init_blocks_table`] before this function. /// initializing the client database with a starting block (for example, calling
/// `init_blocks_table` before this function if using `zcash_client_sqlite`).
/// ///
/// Scanned blocks are required to be height-sequential. If a block is missing from the /// Scanned blocks are required to be height-sequential. If a block is missing from the
/// cache, an error will be returned with kind [`ChainInvalid::BlockHeightDiscontinuity`]. /// cache, an error will be returned with kind [`ChainInvalid::BlockHeightDiscontinuity`].
@ -235,8 +236,6 @@ where
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
///
/// [`init_blocks_table`]: crate::init::init_blocks_table
pub fn scan_cached_blocks<E, N, P, C, D>( pub fn scan_cached_blocks<E, N, P, C, D>(
params: &P, params: &P,
cache: &C, cache: &C,

View File

@ -1,11 +1,11 @@
//! Encoding and decoding functions for Zcash key and address structs. //! Encoding and decoding functions for Zcash key and address structs.
//! //!
//! Human-Readable Prefixes (HRPs) for Bech32 encodings are located in the [`zcash_primitives::constants`] //! Human-Readable Prefixes (HRPs) for Bech32 encodings are located in the
//! module. //! [zcash_primitives::constants][constants] module.
//! //!
//! [`constants`]: zcash_primitives::constants //! [constants]: zcash_primitives::constants
use bech32::{self, Error, FromBase32, ToBase32}; use bech32::{self, Error, FromBase32, ToBase32, Variant};
use bs58::{self, decode::Error as Bs58Error}; use bs58::{self, decode::Error as Bs58Error};
use std::convert::TryInto; use std::convert::TryInto;
use std::io::{self, Write}; use std::io::{self, Write};
@ -21,18 +21,18 @@ where
{ {
let mut data: Vec<u8> = vec![]; let mut data: Vec<u8> = vec![];
write(&mut data).expect("Should be able to write to a Vec"); write(&mut data).expect("Should be able to write to a Vec");
bech32::encode(hrp, data.to_base32()).expect("hrp is invalid") bech32::encode(hrp, data.to_base32(), Variant::Bech32).expect("hrp is invalid")
} }
fn bech32_decode<T, F>(hrp: &str, s: &str, read: F) -> Result<Option<T>, Error> fn bech32_decode<T, F>(hrp: &str, s: &str, read: F) -> Result<Option<T>, Error>
where where
F: Fn(Vec<u8>) -> Option<T>, F: Fn(Vec<u8>) -> Option<T>,
{ {
let (decoded_hrp, data) = bech32::decode(s)?; match bech32::decode(s)? {
if decoded_hrp == hrp { (decoded_hrp, data, Variant::Bech32) if decoded_hrp == hrp => {
Vec::<u8>::from_base32(&data).map(|data| read(data)) Vec::<u8>::from_base32(&data).map(|data| read(data))
} else { }
Ok(None) _ => Ok(None),
} }
} }
@ -52,11 +52,14 @@ where
/// let extsk = spending_key(&[0; 32][..], COIN_TYPE, 0); /// let extsk = spending_key(&[0; 32][..], COIN_TYPE, 0);
/// let encoded = encode_extended_spending_key(HRP_SAPLING_EXTENDED_SPENDING_KEY, &extsk); /// let encoded = encode_extended_spending_key(HRP_SAPLING_EXTENDED_SPENDING_KEY, &extsk);
/// ``` /// ```
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
pub fn encode_extended_spending_key(hrp: &str, extsk: &ExtendedSpendingKey) -> String { pub fn encode_extended_spending_key(hrp: &str, extsk: &ExtendedSpendingKey) -> String {
bech32_encode(hrp, |w| extsk.write(w)) bech32_encode(hrp, |w| extsk.write(w))
} }
/// Decodes an [`ExtendedSpendingKey`] from a Bech32-encoded string. /// Decodes an [`ExtendedSpendingKey`] from a Bech32-encoded string.
///
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
pub fn decode_extended_spending_key( pub fn decode_extended_spending_key(
hrp: &str, hrp: &str,
s: &str, s: &str,
@ -82,11 +85,14 @@ pub fn decode_extended_spending_key(
/// let extfvk = ExtendedFullViewingKey::from(&extsk); /// let extfvk = ExtendedFullViewingKey::from(&extsk);
/// let encoded = encode_extended_full_viewing_key(HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, &extfvk); /// let encoded = encode_extended_full_viewing_key(HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, &extfvk);
/// ``` /// ```
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
pub fn encode_extended_full_viewing_key(hrp: &str, extfvk: &ExtendedFullViewingKey) -> String { pub fn encode_extended_full_viewing_key(hrp: &str, extfvk: &ExtendedFullViewingKey) -> String {
bech32_encode(hrp, |w| extfvk.write(w)) bech32_encode(hrp, |w| extfvk.write(w))
} }
/// Decodes an [`ExtendedFullViewingKey`] from a Bech32-encoded string. /// Decodes an [`ExtendedFullViewingKey`] from a Bech32-encoded string.
///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
pub fn decode_extended_full_viewing_key( pub fn decode_extended_full_viewing_key(
hrp: &str, hrp: &str,
s: &str, s: &str,
@ -127,6 +133,7 @@ pub fn decode_extended_full_viewing_key(
/// "ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk", /// "ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk",
/// ); /// );
/// ``` /// ```
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress) -> String { pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress) -> String {
bech32_encode(hrp, |w| w.write_all(&addr.to_bytes())) bech32_encode(hrp, |w| w.write_all(&addr.to_bytes()))
} }
@ -167,6 +174,7 @@ pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress) -> String {
/// Ok(Some(pa)), /// Ok(Some(pa)),
/// ); /// );
/// ``` /// ```
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddress>, Error> { pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddress>, Error> {
bech32_decode(hrp, s, |data| { bech32_decode(hrp, s, |data| {
if data.len() != 43 { if data.len() != 43 {
@ -210,6 +218,7 @@ pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddres
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2", /// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
/// ); /// );
/// ``` /// ```
/// [`TransparentAddress`]: zcash_primitives::legacy::TransparentAddress
pub fn encode_transparent_address( pub fn encode_transparent_address(
pubkey_version: &[u8], pubkey_version: &[u8],
script_version: &[u8], script_version: &[u8],
@ -263,6 +272,7 @@ pub fn encode_transparent_address(
/// Ok(Some(TransparentAddress::Script([0; 20]))), /// Ok(Some(TransparentAddress::Script([0; 20]))),
/// ); /// );
/// ``` /// ```
/// [`TransparentAddress`]: zcash_primitives::legacy::TransparentAddress
pub fn decode_transparent_address( pub fn decode_transparent_address(
pubkey_version: &[u8], pubkey_version: &[u8],
script_version: &[u8], script_version: &[u8],

View File

@ -17,6 +17,7 @@ use zcash_primitives::zip32::{ChildIndex, ExtendedSpendingKey};
/// ///
/// let extsk = spending_key(&[0; 32][..], COIN_TYPE, 0); /// let extsk = spending_key(&[0; 32][..], COIN_TYPE, 0);
/// ``` /// ```
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
pub fn spending_key(seed: &[u8], coin_type: u32, account: u32) -> ExtendedSpendingKey { pub fn spending_key(seed: &[u8], coin_type: u32, account: u32) -> ExtendedSpendingKey {
if seed.len() < 32 { if seed.len() < 32 {
panic!("ZIP 32 seeds MUST be at least 32 bytes"); panic!("ZIP 32 seeds MUST be at least 32 bytes");

View File

@ -63,6 +63,8 @@ pub struct WalletShieldedOutput<N> {
pub nf: N, pub nf: N,
} }
/// Information about a note that is tracked by the wallet that is available for spending,
/// with sufficient information for use in note selection.
pub struct SpendableNote { pub struct SpendableNote {
pub diversifier: Diversifier, pub diversifier: Diversifier,
pub note_value: Amount, pub note_value: Amount,

View File

@ -23,6 +23,8 @@ use crate::wallet::{AccountId, WalletShieldedOutput, WalletShieldedSpend, Wallet
/// ///
/// The given [`CommitmentTree`] and existing [`IncrementalWitness`]es are incremented /// The given [`CommitmentTree`] and existing [`IncrementalWitness`]es are incremented
/// with this output's commitment. /// with this output's commitment.
///
/// [`ScanningKey`]: crate::welding_rig::ScanningKey
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn scan_output<P: consensus::Parameters, K: ScanningKey>( fn scan_output<P: consensus::Parameters, K: ScanningKey>(
params: &P, params: &P,
@ -88,10 +90,23 @@ fn scan_output<P: consensus::Parameters, K: ScanningKey>(
/// A key that can be used to perform trial decryption and nullifier /// A key that can be used to perform trial decryption and nullifier
/// computation for a Sapling [`CompactOutput`] /// computation for a Sapling [`CompactOutput`]
/// ///
/// The purpose of this trait is to enable [`scan_block`]
/// and related methods to be used with either incoming viewing keys
/// or full viewing keys, with the data returned from trial decryption
/// being dependent upon the type of key used. In the case that an
/// incoming viewing key is used, only the note and payment address
/// will be returned; in the case of a full viewing key, the
/// nullifier for the note can also be obtained.
///
/// [`CompactOutput`]: crate::proto::compact_formats::CompactOutput /// [`CompactOutput`]: crate::proto::compact_formats::CompactOutput
/// [`scan_block`]: crate::welding_rig::scan_block
pub trait ScanningKey { pub trait ScanningKey {
/// The type of nullifier extracted when a note is successfully
/// obtained by trial decryption.
type Nf; type Nf;
/// Attempts to decrypt a Sapling note and payment address
/// from the specified ciphertext using this scanning key.
fn try_decryption<P: consensus::Parameters>( fn try_decryption<P: consensus::Parameters>(
&self, &self,
params: &P, params: &P,
@ -101,9 +116,18 @@ pub trait ScanningKey {
ct: &[u8], ct: &[u8],
) -> Option<(Note, PaymentAddress)>; ) -> Option<(Note, PaymentAddress)>;
/// Produces the nullifier for the specified note and witness, if possible.
///
/// IVK-based implementations of this trait cannot successfully derive
/// nullifiers, in which case `Self::Nf` should be set to the unit type
/// and this function is a no-op.
fn nf(&self, note: &Note, witness: &IncrementalWitness<Node>) -> Self::Nf; fn nf(&self, note: &Note, witness: &IncrementalWitness<Node>) -> Self::Nf;
} }
/// The [`ScanningKey`] implementation for [`ExtendedFullViewingKey`]s.
/// Nullifiers may be derived when scanning with these keys.
///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
impl ScanningKey for ExtendedFullViewingKey { impl ScanningKey for ExtendedFullViewingKey {
type Nf = Nullifier; type Nf = Nullifier;
@ -123,6 +147,10 @@ impl ScanningKey for ExtendedFullViewingKey {
} }
} }
/// The [`ScanningKey`] implementation for [`SaplingIvk`]s.
/// Nullifiers cannot be derived when scanning with these keys.
///
/// [`SaplingIvk`]: zcash_primitives::primitives::SaplingIvk
impl ScanningKey for SaplingIvk { impl ScanningKey for SaplingIvk {
type Nf = (); type Nf = ();
@ -152,16 +180,17 @@ impl ScanningKey for SaplingIvk {
/// The implementation of [`ScanningKey`] may either support or omit the computation of /// The implementation of [`ScanningKey`] may either support or omit the computation of
/// the nullifiers for received notes; the implementation for [`ExtendedFullViewingKey`] /// the nullifiers for received notes; the implementation for [`ExtendedFullViewingKey`]
/// will derive the nullifiers for received notes and return them as part of the resulting /// will derive the nullifiers for received notes and return them as part of the resulting
/// [`WalletShieldedOutput`]s, whereas since the implementation for [`SaplingIvk`] cannot /// [`WalletShieldedOutput`]s, whereas the implementation for [`SaplingIvk`] cannot
/// do so and it will return the unit value in those outputs instead. /// do so and will return the unit value in those outputs instead.
/// ///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey /// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
/// [`SaplingIvk`]: zcash_primitives::SaplingIvk /// [`SaplingIvk`]: zcash_primitives::primitives::SaplingIvk
/// [`CompactBlock`]: crate::proto::compact_formats::CompactBlock /// [`CompactBlock`]: crate::proto::compact_formats::CompactBlock
/// [`ScanningKey`]: self::ScanningKey /// [`ScanningKey`]: crate::welding_rig::ScanningKey
/// [`CommitmentTree`]: zcash_primitives::merkle_tree::CommitmentTree /// [`CommitmentTree`]: zcash_primitives::merkle_tree::CommitmentTree
/// [`IncrementalWitness`]: zcash_primitives::merkle_tree::IncrementalWitness /// [`IncrementalWitness`]: zcash_primitives::merkle_tree::IncrementalWitness
/// [`WalletShieldedOutput`]: crate::wallet::WalletShieldedOutput /// [`WalletShieldedOutput`]: crate::wallet::WalletShieldedOutput
/// [`WalletTx`]: crate::wallet::WalletTx
pub fn scan_block<P: consensus::Parameters, K: ScanningKey>( pub fn scan_block<P: consensus::Parameters, K: ScanningKey>(
params: &P, params: &P,
block: CompactBlock, block: CompactBlock,

View File

@ -462,7 +462,7 @@ mod parse {
Ok(payment) Ok(payment)
} }
/// Parser that consumes the leading "zcash:[address]" from /// Parser that consumes the leading "zcash:\[address\]" from
/// a ZIP 321 URI. /// a ZIP 321 URI.
pub fn lead_addr<'a, P: consensus::Parameters>( pub fn lead_addr<'a, P: consensus::Parameters>(
params: &'a P, params: &'a P,

View File

@ -29,6 +29,13 @@ same as before, but have been reorganized.
### Removed ### Removed
- `zcash_client_sqlite::address` module (moved to `zcash_client_backend`). - `zcash_client_sqlite::address` module (moved to `zcash_client_backend`).
### Fixed
- Shielded transactions created by the wallet that have no change output (fully
spending their input notes) are now correctly detected as mined when scanning
compact blocks.
- Unshielding transactions created by the wallet (with a transparent recipient
address) that have no change output no longer cause a panic.
## [0.2.1] - 2020-10-24 ## [0.2.1] - 2020-10-24
### Fixed ### Fixed
- `transact::create_to_address` now correctly reconstructs notes from the data - `transact::create_to_address` now correctly reconstructs notes from the data

View File

@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
bech32 = "0.7" bech32 = "0.8"
bs58 = { version = "0.4", features = ["check"] } bs58 = { version = "0.4", features = ["check"] }
ff = "0.8" ff = "0.8"
group = "0.8" group = "0.8"

View File

@ -477,14 +477,13 @@ pub fn get_nullifiers<P>(
wdb: &WalletDB<P>, wdb: &WalletDB<P>,
) -> Result<Vec<(AccountId, Nullifier)>, SqliteClientError> { ) -> Result<Vec<(AccountId, Nullifier)>, SqliteClientError> {
// Get the nullifiers for the notes we are tracking // Get the nullifiers for the notes we are tracking
let mut stmt_fetch_nullifiers = wdb let mut stmt_fetch_nullifiers = wdb.conn.prepare(
.conn
.prepare(
"SELECT rn.id_note, rn.account, rn.nf, tx.block as block "SELECT rn.id_note, rn.account, rn.nf, tx.block as block
FROM received_notes rn FROM received_notes rn
LEFT OUTER JOIN transactions tx LEFT OUTER JOIN transactions tx
ON tx.id_tx = rn.spent ON tx.id_tx = rn.spent
WHERE block IS NULL")?; WHERE block IS NULL",
)?;
let nullifiers = stmt_fetch_nullifiers.query_map(NO_PARAMS, |row| { let nullifiers = stmt_fetch_nullifiers.query_map(NO_PARAMS, |row| {
let account = AccountId(row.get(1)?); let account = AccountId(row.get(1)?);
let nf_bytes: Vec<u8> = row.get(2)?; let nf_bytes: Vec<u8> = row.get(2)?;

View File

@ -687,7 +687,7 @@ mod tests {
let (cb, _) = fake_compact_block( let (cb, _) = fake_compact_block(
sapling_activation_height(), sapling_activation_height(),
BlockHash([0; 32]), BlockHash([0; 32]),
extfvk.clone(), extfvk,
value, value,
); );
insert_into_cache(&db_cache, &cb); insert_into_cache(&db_cache, &cb);

View File

@ -3,7 +3,8 @@
//! `regtest` is a `zcashd`-specific environment used for local testing. They mostly reuse //! `regtest` is a `zcashd`-specific environment used for local testing. They mostly reuse
//! the testnet constants. //! the testnet constants.
//! These constants are defined in [the `zcashd` codebase]. //! These constants are defined in [the `zcashd` codebase].
//! [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L482-L496 //!
//! [the `zcashd` codebase]: <https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L482-L496>
/// The regtest cointype reuses the testnet cointype /// The regtest cointype reuses the testnet cointype
pub const COIN_TYPE: u32 = 1; pub const COIN_TYPE: u32 = 1;
@ -13,7 +14,7 @@ pub const COIN_TYPE: u32 = 1;
/// It is defined in [the `zcashd` codebase]. /// It is defined in [the `zcashd` codebase].
/// ///
/// [`ExtendedSpendingKey`]: crate::zip32::ExtendedSpendingKey /// [`ExtendedSpendingKey`]: crate::zip32::ExtendedSpendingKey
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L496 /// [the `zcashd` codebase]: <https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L496>
pub const HRP_SAPLING_EXTENDED_SPENDING_KEY: &str = "secret-extended-key-regtest"; pub const HRP_SAPLING_EXTENDED_SPENDING_KEY: &str = "secret-extended-key-regtest";
/// The HRP for a Bech32-encoded regtest [`ExtendedFullViewingKey`]. /// The HRP for a Bech32-encoded regtest [`ExtendedFullViewingKey`].
@ -21,7 +22,7 @@ pub const HRP_SAPLING_EXTENDED_SPENDING_KEY: &str = "secret-extended-key-regtest
/// It is defined in [the `zcashd` codebase]. /// It is defined in [the `zcashd` codebase].
/// ///
/// [`ExtendedFullViewingKey`]: crate::zip32::ExtendedFullViewingKey /// [`ExtendedFullViewingKey`]: crate::zip32::ExtendedFullViewingKey
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L494 /// [the `zcashd` codebase]: <https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L494>
pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewregtestsapling"; pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewregtestsapling";
/// The HRP for a Bech32-encoded regtest [`PaymentAddress`]. /// The HRP for a Bech32-encoded regtest [`PaymentAddress`].
@ -29,7 +30,7 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewregtestsapling";
/// It is defined in [the `zcashd` codebase]. /// It is defined in [the `zcashd` codebase].
/// ///
/// [`PaymentAddress`]: crate::primitives::PaymentAddress /// [`PaymentAddress`]: crate::primitives::PaymentAddress
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L493 /// [the `zcashd` codebase]: <https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L493>
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zregtestsapling"; pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zregtestsapling";
/// The prefix for a Base58Check-encoded regtest [`TransparentAddress::PublicKey`]. /// The prefix for a Base58Check-encoded regtest [`TransparentAddress::PublicKey`].

View File

@ -9,8 +9,8 @@ use std::str;
/// Format a byte array as a colon-delimited hex string. /// Format a byte array as a colon-delimited hex string.
/// ///
/// Source: https://github.com/tendermint/signatory /// - Source: <https://github.com/tendermint/signatory>
/// License: MIT / Apache 2.0 /// - License: MIT / Apache 2.0
fn fmt_colon_delimited_hex<B>(f: &mut fmt::Formatter<'_>, bytes: B) -> fmt::Result fn fmt_colon_delimited_hex<B>(f: &mut fmt::Formatter<'_>, bytes: B) -> fmt::Result
where where
B: AsRef<[u8]>, B: AsRef<[u8]>,

View File

@ -49,7 +49,7 @@ use crate::prover::mock::MockTxProver;
const DEFAULT_TX_EXPIRY_DELTA: u32 = 20; const DEFAULT_TX_EXPIRY_DELTA: u32 = 20;
/// If there are any shielded inputs, always have at least two shielded outputs, padding /// If there are any shielded inputs, always have at least two shielded outputs, padding
/// with dummy outputs if necessary. See https://github.com/zcash/zcash/issues/3615 /// with dummy outputs if necessary. See <https://github.com/zcash/zcash/issues/3615>.
const MIN_SHIELDED_OUTPUTS: usize = 2; const MIN_SHIELDED_OUTPUTS: usize = 2;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]

View File

@ -142,9 +142,9 @@ pub struct TzeIn {
pub witness: tze::Witness, pub witness: tze::Witness,
} }
/// Transaction encoding and decoding functions conforming to ZIP-222 /// Transaction encoding and decoding functions conforming to [ZIP 222].
/// ///
/// https://zips.z.cash/zip-0222#encoding-in-transactions /// [ZIP 222]: https://zips.z.cash/zip-0222#encoding-in-transactions
#[cfg(feature = "zfuture")] #[cfg(feature = "zfuture")]
impl TzeIn { impl TzeIn {
/// Convenience constructor /// Convenience constructor

View File

@ -64,25 +64,16 @@ macro_rules! update_hash {
} }
fn has_overwinter_components(version: &TxVersion) -> bool { fn has_overwinter_components(version: &TxVersion) -> bool {
match version { !matches!(version, TxVersion::Sprout(_))
TxVersion::Sprout(_) => false,
_ => true,
}
} }
fn has_sapling_components(version: &TxVersion) -> bool { fn has_sapling_components(version: &TxVersion) -> bool {
match version { !matches!(version, TxVersion::Sprout(_) | TxVersion::Overwinter)
TxVersion::Sprout(_) | TxVersion::Overwinter => false,
_ => true,
}
} }
#[cfg(feature = "zfuture")] #[cfg(feature = "zfuture")]
fn has_tze_components(version: &TxVersion) -> bool { fn has_tze_components(version: &TxVersion) -> bool {
match version { matches!(version, TxVersion::ZFuture)
TxVersion::ZFuture => true,
_ => false,
}
} }
fn prevout_hash(vin: &[TxIn]) -> Blake2bHash { fn prevout_hash(vin: &[TxIn]) -> Blake2bHash {