Merge pull request #361 from str4d/release-0.5-prep
Release 0.5 preparations
This commit is contained in:
commit
44e3176d5a
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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`].
|
||||||
|
|
|
@ -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]>,
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue