zcash_address: Use `zcash_protocol::consensus::NetworkType`
This inverts the dependency relationship between `zcash_protocol` and `zcash_address`, permitting the network constants (primarily the HRPs) defined in `zcash_protocol` to be used directly in `zcash_address` instead of being duplicated.
This commit is contained in:
parent
64454100c5
commit
4b18426fcd
|
@ -3002,6 +3002,7 @@ dependencies = [
|
||||||
"f4jumble",
|
"f4jumble",
|
||||||
"proptest",
|
"proptest",
|
||||||
"zcash_encoding",
|
"zcash_encoding",
|
||||||
|
"zcash_protocol",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3239,7 +3240,6 @@ dependencies = [
|
||||||
"incrementalmerkletree",
|
"incrementalmerkletree",
|
||||||
"memuse",
|
"memuse",
|
||||||
"proptest",
|
"proptest",
|
||||||
"zcash_address",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -7,6 +7,12 @@ and this library adheres to Rust's notion of
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- `zcash_address::kind::p2pkh` - use constants from `zcash_protocol` instead.
|
||||||
|
- `zcash_address::kind::p2sh` - use constants from `zcash_protocol` instead.
|
||||||
|
- `zcash_address::kind::sapling` - use constants from `zcash_protocol` instead.
|
||||||
|
- `zcash_address::kind::sprout` - use constants from `zcash_protocol` instead.
|
||||||
|
|
||||||
## [0.3.1] - 2024-01-12
|
## [0.3.1] - 2024-01-12
|
||||||
### Fixed
|
### Fixed
|
||||||
- Stubs for `zcash_address::convert` traits that are created by `rust-analyzer`
|
- Stubs for `zcash_address::convert` traits that are created by `rust-analyzer`
|
||||||
|
|
|
@ -22,7 +22,8 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||||
bech32 = "0.9"
|
bech32 = "0.9"
|
||||||
bs58 = { version = "0.5", features = ["check"] }
|
bs58 = { version = "0.5", features = ["check"] }
|
||||||
f4jumble = { version = "0.1", path = "../f4jumble" }
|
f4jumble = { version = "0.1", path = "../f4jumble" }
|
||||||
zcash_encoding = { version = "0.2", path = "../zcash_encoding" }
|
zcash_protocol.workspace = true
|
||||||
|
zcash_encoding.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_matches = "1.3.0"
|
assert_matches = "1.3.0"
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use std::{convert::TryInto, error::Error, fmt, str::FromStr};
|
use std::{convert::TryInto, error::Error, fmt, str::FromStr};
|
||||||
|
|
||||||
use bech32::{self, FromBase32, ToBase32, Variant};
|
use bech32::{self, FromBase32, ToBase32, Variant};
|
||||||
|
use zcash_protocol::consensus::{NetworkConstants, NetworkType};
|
||||||
|
use zcash_protocol::constants::{mainnet, regtest, testnet};
|
||||||
|
|
||||||
use crate::kind::unified::Encoding;
|
use crate::kind::unified::Encoding;
|
||||||
use crate::{kind::*, AddressKind, Network, ZcashAddress};
|
use crate::{kind::*, AddressKind, ZcashAddress};
|
||||||
|
|
||||||
/// An error while attempting to parse a string as a Zcash address.
|
/// An error while attempting to parse a string as a Zcash address.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
@ -68,9 +70,9 @@ impl FromStr for ZcashAddress {
|
||||||
let data = Vec::<u8>::from_base32(&data).map_err(|_| ParseError::InvalidEncoding)?;
|
let data = Vec::<u8>::from_base32(&data).map_err(|_| ParseError::InvalidEncoding)?;
|
||||||
|
|
||||||
let net = match hrp.as_str() {
|
let net = match hrp.as_str() {
|
||||||
sapling::MAINNET => Network::Main,
|
mainnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Main,
|
||||||
sapling::TESTNET => Network::Test,
|
testnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Test,
|
||||||
sapling::REGTEST => Network::Regtest,
|
regtest::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Regtest,
|
||||||
// We will not define new Bech32 address encodings.
|
// We will not define new Bech32 address encodings.
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParseError::NotZcash);
|
return Err(ParseError::NotZcash);
|
||||||
|
@ -86,23 +88,33 @@ impl FromStr for ZcashAddress {
|
||||||
|
|
||||||
// The rest use Base58Check.
|
// The rest use Base58Check.
|
||||||
if let Ok(decoded) = bs58::decode(s).with_check(None).into_vec() {
|
if let Ok(decoded) = bs58::decode(s).with_check(None).into_vec() {
|
||||||
let net = match decoded[..2].try_into().unwrap() {
|
if decoded.len() >= 2 {
|
||||||
sprout::MAINNET | p2pkh::MAINNET | p2sh::MAINNET => Network::Main,
|
let (prefix, net) = match decoded[..2].try_into().unwrap() {
|
||||||
sprout::TESTNET | p2pkh::TESTNET | p2sh::TESTNET => Network::Test,
|
prefix @ (mainnet::B58_PUBKEY_ADDRESS_PREFIX
|
||||||
|
| mainnet::B58_SCRIPT_ADDRESS_PREFIX
|
||||||
|
| mainnet::B58_SPROUT_ADDRESS_PREFIX) => (prefix, NetworkType::Main),
|
||||||
|
prefix @ (testnet::B58_PUBKEY_ADDRESS_PREFIX
|
||||||
|
| testnet::B58_SCRIPT_ADDRESS_PREFIX
|
||||||
|
| testnet::B58_SPROUT_ADDRESS_PREFIX) => (prefix, NetworkType::Test),
|
||||||
// We will not define new Base58Check address encodings.
|
// We will not define new Base58Check address encodings.
|
||||||
_ => return Err(ParseError::NotZcash),
|
_ => return Err(ParseError::NotZcash),
|
||||||
};
|
};
|
||||||
|
|
||||||
return match decoded[..2].try_into().unwrap() {
|
return match prefix {
|
||||||
sprout::MAINNET | sprout::TESTNET => {
|
mainnet::B58_SPROUT_ADDRESS_PREFIX | testnet::B58_SPROUT_ADDRESS_PREFIX => {
|
||||||
decoded[2..].try_into().map(AddressKind::Sprout)
|
decoded[2..].try_into().map(AddressKind::Sprout)
|
||||||
}
|
}
|
||||||
p2pkh::MAINNET | p2pkh::TESTNET => decoded[2..].try_into().map(AddressKind::P2pkh),
|
mainnet::B58_PUBKEY_ADDRESS_PREFIX | testnet::B58_PUBKEY_ADDRESS_PREFIX => {
|
||||||
p2sh::MAINNET | p2sh::TESTNET => decoded[2..].try_into().map(AddressKind::P2sh),
|
decoded[2..].try_into().map(AddressKind::P2pkh)
|
||||||
|
}
|
||||||
|
mainnet::B58_SCRIPT_ADDRESS_PREFIX | testnet::B58_SCRIPT_ADDRESS_PREFIX => {
|
||||||
|
decoded[2..].try_into().map(AddressKind::P2sh)
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
.map_err(|_| ParseError::InvalidEncoding)
|
.map_err(|_| ParseError::InvalidEncoding)
|
||||||
.map(|kind| ZcashAddress { kind, net });
|
.map(|kind| ZcashAddress { kind, net });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If it's not valid Bech32, Bech32m, or Base58Check, it's not a Zcash address.
|
// If it's not valid Bech32, Bech32m, or Base58Check, it's not a Zcash address.
|
||||||
|
@ -124,36 +136,13 @@ fn encode_b58(prefix: [u8; 2], data: &[u8]) -> String {
|
||||||
impl fmt::Display for ZcashAddress {
|
impl fmt::Display for ZcashAddress {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let encoded = match &self.kind {
|
let encoded = match &self.kind {
|
||||||
AddressKind::Sprout(data) => encode_b58(
|
AddressKind::Sprout(data) => encode_b58(self.net.b58_sprout_address_prefix(), data),
|
||||||
match self.net {
|
AddressKind::Sapling(data) => {
|
||||||
Network::Main => sprout::MAINNET,
|
encode_bech32(self.net.hrp_sapling_payment_address(), data)
|
||||||
Network::Test | Network::Regtest => sprout::TESTNET,
|
}
|
||||||
},
|
|
||||||
data,
|
|
||||||
),
|
|
||||||
AddressKind::Sapling(data) => encode_bech32(
|
|
||||||
match self.net {
|
|
||||||
Network::Main => sapling::MAINNET,
|
|
||||||
Network::Test => sapling::TESTNET,
|
|
||||||
Network::Regtest => sapling::REGTEST,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
),
|
|
||||||
AddressKind::Unified(addr) => addr.encode(&self.net),
|
AddressKind::Unified(addr) => addr.encode(&self.net),
|
||||||
AddressKind::P2pkh(data) => encode_b58(
|
AddressKind::P2pkh(data) => encode_b58(self.net.b58_pubkey_address_prefix(), data),
|
||||||
match self.net {
|
AddressKind::P2sh(data) => encode_b58(self.net.b58_script_address_prefix(), data),
|
||||||
Network::Main => p2pkh::MAINNET,
|
|
||||||
Network::Test | Network::Regtest => p2pkh::TESTNET,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
),
|
|
||||||
AddressKind::P2sh(data) => encode_b58(
|
|
||||||
match self.net {
|
|
||||||
Network::Main => p2sh::MAINNET,
|
|
||||||
Network::Test | Network::Regtest => p2sh::TESTNET,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
write!(f, "{}", encoded)
|
write!(f, "{}", encoded)
|
||||||
}
|
}
|
||||||
|
@ -162,7 +151,7 @@ impl fmt::Display for ZcashAddress {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::kind::unified;
|
use crate::{kind::unified, Network};
|
||||||
|
|
||||||
fn encoding(encoded: &str, decoded: ZcashAddress) {
|
fn encoding(encoded: &str, decoded: ZcashAddress) {
|
||||||
assert_eq!(decoded.to_string(), encoded);
|
assert_eq!(decoded.to_string(), encoded);
|
||||||
|
|
|
@ -1,7 +1 @@
|
||||||
pub mod unified;
|
pub mod unified;
|
||||||
|
|
||||||
pub(crate) mod sapling;
|
|
||||||
pub(crate) mod sprout;
|
|
||||||
|
|
||||||
pub(crate) mod p2pkh;
|
|
||||||
pub(crate) mod p2sh;
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
/// The prefix for a Base58Check-encoded mainnet transparent P2PKH address.
|
|
||||||
pub(crate) const MAINNET: [u8; 2] = [0x1c, 0xb8];
|
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded testnet transparent P2PKH address.
|
|
||||||
pub(crate) const TESTNET: [u8; 2] = [0x1d, 0x25];
|
|
|
@ -1,5 +0,0 @@
|
||||||
/// The prefix for a Base58Check-encoded mainnet transparent P2SH address.
|
|
||||||
pub(crate) const MAINNET: [u8; 2] = [0x1c, 0xbd];
|
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded testnet transparent P2SH address.
|
|
||||||
pub(crate) const TESTNET: [u8; 2] = [0x1c, 0xba];
|
|
|
@ -1,20 +0,0 @@
|
||||||
/// The HRP for a Bech32-encoded mainnet Sapling address.
|
|
||||||
///
|
|
||||||
/// Defined in the [Zcash Protocol Specification section 5.6.4][saplingpaymentaddrencoding].
|
|
||||||
///
|
|
||||||
/// [saplingpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#saplingpaymentaddrencoding
|
|
||||||
pub(crate) const MAINNET: &str = "zs";
|
|
||||||
|
|
||||||
/// The HRP for a Bech32-encoded testnet Sapling address.
|
|
||||||
///
|
|
||||||
/// Defined in the [Zcash Protocol Specification section 5.6.4][saplingpaymentaddrencoding].
|
|
||||||
///
|
|
||||||
/// [saplingpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#saplingpaymentaddrencoding
|
|
||||||
pub(crate) const TESTNET: &str = "ztestsapling";
|
|
||||||
|
|
||||||
/// The HRP for a Bech32-encoded regtest Sapling address.
|
|
||||||
///
|
|
||||||
/// It is defined in [the `zcashd` codebase].
|
|
||||||
///
|
|
||||||
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L493
|
|
||||||
pub(crate) const REGTEST: &str = "zregtestsapling";
|
|
|
@ -1,13 +0,0 @@
|
||||||
/// The prefix for a Base58Check-encoded mainnet Sprout address.
|
|
||||||
///
|
|
||||||
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
|
||||||
///
|
|
||||||
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
|
||||||
pub(crate) const MAINNET: [u8; 2] = [0x16, 0x9a];
|
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded testnet Sprout address.
|
|
||||||
///
|
|
||||||
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
|
||||||
///
|
|
||||||
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
|
||||||
pub(crate) const TESTNET: [u8; 2] = [0x16, 0xb6];
|
|
|
@ -141,6 +141,7 @@ pub use convert::{
|
||||||
};
|
};
|
||||||
pub use encoding::ParseError;
|
pub use encoding::ParseError;
|
||||||
pub use kind::unified;
|
pub use kind::unified;
|
||||||
|
pub use zcash_protocol::consensus::NetworkType as Network;
|
||||||
|
|
||||||
/// A Zcash address.
|
/// A Zcash address.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -149,20 +150,6 @@ pub struct ZcashAddress {
|
||||||
kind: AddressKind,
|
kind: AddressKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Zcash network for which an address is encoded.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub enum Network {
|
|
||||||
/// Zcash Mainnet.
|
|
||||||
Main,
|
|
||||||
/// Zcash Testnet.
|
|
||||||
Test,
|
|
||||||
/// Private integration / regression testing, used in `zcashd`.
|
|
||||||
///
|
|
||||||
/// For some address types there is no distinction between test and regtest encodings;
|
|
||||||
/// those will always be parsed as `Network::Test`.
|
|
||||||
Regtest,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Known kinds of Zcash addresses.
|
/// Known kinds of Zcash addresses.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
enum AddressKind {
|
enum AddressKind {
|
||||||
|
|
|
@ -15,6 +15,11 @@ The entries below are relative to the `zcash_primitives` crate as of the tag
|
||||||
- `consensus`
|
- `consensus`
|
||||||
- `constants`
|
- `constants`
|
||||||
- `zcash_protocol::value` replaces `zcash_primitives::transaction::components::amount`
|
- `zcash_protocol::value` replaces `zcash_primitives::transaction::components::amount`
|
||||||
|
- `zcash_protocol::consensus`:
|
||||||
|
- `NetworkConstants` has been extracted from the `Parameters` trait.
|
||||||
|
- `NetworkType`
|
||||||
|
- `Parameters::b58_sprout_address_prefix`
|
||||||
|
- `zcash_protocol::constants::{mainnet, testnet}::B58_SPROUT_ADDRESS_PREFIX`
|
||||||
- Added in `zcash_protocol::value`:
|
- Added in `zcash_protocol::value`:
|
||||||
- `Zatoshis`
|
- `Zatoshis`
|
||||||
- `ZatBalance`
|
- `ZatBalance`
|
||||||
|
@ -35,3 +40,7 @@ The entries below are relative to the `zcash_primitives` crate as of the tag
|
||||||
- `TryFrom<orchard::ValueSum> for Amount`
|
- `TryFrom<orchard::ValueSum> for Amount`
|
||||||
- `From<NonNegativeAmount> for sapling::value::NoteValue>`
|
- `From<NonNegativeAmount> for sapling::value::NoteValue>`
|
||||||
- `TryFrom<sapling::value::NoteValue> for NonNegativeAmount`
|
- `TryFrom<sapling::value::NoteValue> for NonNegativeAmount`
|
||||||
|
- `zcash_protocol::consensus::Parameters` has been split into two traits, with
|
||||||
|
the `NetworkConstants` trait providing all network constant accessors. Also,
|
||||||
|
the `address_network` method has been replaced with a new `network_type`
|
||||||
|
method that serves the same purpose.
|
||||||
|
|
|
@ -20,8 +20,6 @@ all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
zcash_address.workspace = true
|
|
||||||
|
|
||||||
# - Logging and metrics
|
# - Logging and metrics
|
||||||
memuse.workspace = true
|
memuse.workspace = true
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@ use std::cmp::{Ord, Ordering};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, Bound, RangeBounds, Sub};
|
use std::ops::{Add, Bound, RangeBounds, Sub};
|
||||||
use zcash_address;
|
|
||||||
|
|
||||||
use crate::constants;
|
use crate::constants::{mainnet, regtest, testnet};
|
||||||
|
|
||||||
|
#[cfg(feature = "local-consensus")]
|
||||||
|
use crate::local_consensus::LocalNetwork;
|
||||||
|
|
||||||
/// A wrapper type representing blockchain heights.
|
/// A wrapper type representing blockchain heights.
|
||||||
///
|
///
|
||||||
|
@ -136,8 +138,142 @@ impl Sub for BlockHeight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constants associated with a given Zcash network.
|
||||||
|
pub trait NetworkConstants: Clone {
|
||||||
|
/// The coin type for ZEC, as defined by [SLIP 44].
|
||||||
|
///
|
||||||
|
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||||
|
fn coin_type(&self) -> u32;
|
||||||
|
|
||||||
|
/// Returns the human-readable prefix for Bech32-encoded Sapling extended spending keys
|
||||||
|
/// the network to which this NetworkConstants value applies.
|
||||||
|
///
|
||||||
|
/// Defined in [ZIP 32].
|
||||||
|
///
|
||||||
|
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
|
||||||
|
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
|
||||||
|
fn hrp_sapling_extended_spending_key(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// Returns the human-readable prefix for Bech32-encoded Sapling extended full
|
||||||
|
/// viewing keys for the network to which this NetworkConstants value applies.
|
||||||
|
///
|
||||||
|
/// Defined in [ZIP 32].
|
||||||
|
///
|
||||||
|
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
|
||||||
|
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
|
||||||
|
fn hrp_sapling_extended_full_viewing_key(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// Returns the Bech32-encoded human-readable prefix for Sapling payment addresses
|
||||||
|
/// viewing keys for the network to which this NetworkConstants value applies.
|
||||||
|
///
|
||||||
|
/// Defined in section 5.6.4 of the [Zcash Protocol Specification].
|
||||||
|
///
|
||||||
|
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
|
||||||
|
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
||||||
|
fn hrp_sapling_payment_address(&self) -> &'static str;
|
||||||
|
|
||||||
|
/// Returns the human-readable prefix for Base58Check-encoded Sprout
|
||||||
|
/// payment addresses for the network to which this NetworkConstants value
|
||||||
|
/// applies.
|
||||||
|
///
|
||||||
|
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
||||||
|
///
|
||||||
|
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
||||||
|
fn b58_sprout_address_prefix(&self) -> [u8; 2];
|
||||||
|
|
||||||
|
/// Returns the human-readable prefix for Base58Check-encoded transparent
|
||||||
|
/// pay-to-public-key-hash payment addresses for the network to which this NetworkConstants value
|
||||||
|
/// applies.
|
||||||
|
///
|
||||||
|
/// [`TransparentAddress::PublicKey`]: zcash_primitives::legacy::TransparentAddress::PublicKey
|
||||||
|
fn b58_pubkey_address_prefix(&self) -> [u8; 2];
|
||||||
|
|
||||||
|
/// Returns the human-readable prefix for Base58Check-encoded transparent pay-to-script-hash
|
||||||
|
/// payment addresses for the network to which this NetworkConstants value applies.
|
||||||
|
///
|
||||||
|
/// [`TransparentAddress::Script`]: zcash_primitives::legacy::TransparentAddress::Script
|
||||||
|
fn b58_script_address_prefix(&self) -> [u8; 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The enumeration of known Zcash network types.
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub enum NetworkType {
|
||||||
|
/// Zcash Mainnet.
|
||||||
|
Main,
|
||||||
|
/// Zcash Testnet.
|
||||||
|
Test,
|
||||||
|
/// Private integration / regression testing, used in `zcashd`.
|
||||||
|
///
|
||||||
|
/// For some address types there is no distinction between test and regtest encodings;
|
||||||
|
/// those will always be parsed as `Network::Test`.
|
||||||
|
Regtest,
|
||||||
|
}
|
||||||
|
|
||||||
|
memuse::impl_no_dynamic_usage!(NetworkType);
|
||||||
|
|
||||||
|
impl NetworkConstants for NetworkType {
|
||||||
|
fn coin_type(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::COIN_TYPE,
|
||||||
|
NetworkType::Test => testnet::COIN_TYPE,
|
||||||
|
NetworkType::Regtest => regtest::COIN_TYPE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hrp_sapling_extended_spending_key(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
|
||||||
|
NetworkType::Test => testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
|
||||||
|
NetworkType::Regtest => regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hrp_sapling_extended_full_viewing_key(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
|
||||||
|
NetworkType::Test => testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
|
||||||
|
NetworkType::Regtest => regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hrp_sapling_payment_address(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
|
||||||
|
NetworkType::Test => testnet::HRP_SAPLING_PAYMENT_ADDRESS,
|
||||||
|
NetworkType::Regtest => regtest::HRP_SAPLING_PAYMENT_ADDRESS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b58_sprout_address_prefix(&self) -> [u8; 2] {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::B58_SPROUT_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Test => testnet::B58_SPROUT_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Regtest => regtest::B58_SPROUT_ADDRESS_PREFIX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::B58_PUBKEY_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Test => testnet::B58_PUBKEY_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Regtest => regtest::B58_PUBKEY_ADDRESS_PREFIX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
||||||
|
match self {
|
||||||
|
NetworkType::Main => mainnet::B58_SCRIPT_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Test => testnet::B58_SCRIPT_ADDRESS_PREFIX,
|
||||||
|
NetworkType::Regtest => regtest::B58_SCRIPT_ADDRESS_PREFIX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Zcash consensus parameters.
|
/// Zcash consensus parameters.
|
||||||
pub trait Parameters: Clone {
|
pub trait Parameters: Clone {
|
||||||
|
/// Returns the type of network configured by this set of consensus parameters.
|
||||||
|
fn network_type(&self) -> NetworkType;
|
||||||
|
|
||||||
/// Returns the activation height for a particular network upgrade,
|
/// Returns the activation height for a particular network upgrade,
|
||||||
/// if an activation height has been set.
|
/// if an activation height has been set.
|
||||||
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight>;
|
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight>;
|
||||||
|
@ -147,55 +283,36 @@ pub trait Parameters: Clone {
|
||||||
fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool {
|
fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool {
|
||||||
self.activation_height(nu).map_or(false, |h| h <= height)
|
self.activation_height(nu).map_or(false, |h| h <= height)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The coin type for ZEC, as defined by [SLIP 44].
|
impl<P: Parameters> NetworkConstants for P {
|
||||||
///
|
fn coin_type(&self) -> u32 {
|
||||||
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
self.network_type().coin_type()
|
||||||
fn coin_type(&self) -> u32;
|
}
|
||||||
|
|
||||||
/// Returns the standard network constant for address encoding. Returns
|
fn hrp_sapling_extended_spending_key(&self) -> &'static str {
|
||||||
/// 'None' for nonstandard networks.
|
self.network_type().hrp_sapling_extended_spending_key()
|
||||||
fn address_network(&self) -> Option<zcash_address::Network>;
|
}
|
||||||
|
|
||||||
/// Returns the human-readable prefix for Bech32-encoded Sapling extended spending keys
|
fn hrp_sapling_extended_full_viewing_key(&self) -> &'static str {
|
||||||
/// the network to which this Parameters value applies.
|
self.network_type().hrp_sapling_extended_full_viewing_key()
|
||||||
///
|
}
|
||||||
/// Defined in [ZIP 32].
|
|
||||||
///
|
|
||||||
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
|
|
||||||
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str;
|
|
||||||
|
|
||||||
/// Returns the human-readable prefix for Bech32-encoded Sapling extended full
|
fn hrp_sapling_payment_address(&self) -> &'static str {
|
||||||
/// viewing keys for the network to which this Parameters value applies.
|
self.network_type().hrp_sapling_payment_address()
|
||||||
///
|
}
|
||||||
/// Defined in [ZIP 32].
|
|
||||||
///
|
|
||||||
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
|
|
||||||
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str;
|
|
||||||
|
|
||||||
/// Returns the Bech32-encoded human-readable prefix for Sapling payment addresses
|
fn b58_sprout_address_prefix(&self) -> [u8; 2] {
|
||||||
/// viewing keys for the network to which this Parameters value applies.
|
self.network_type().b58_sprout_address_prefix()
|
||||||
///
|
}
|
||||||
/// Defined in section 5.6.4 of the [Zcash Protocol Specification].
|
|
||||||
///
|
|
||||||
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
|
|
||||||
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str;
|
|
||||||
|
|
||||||
/// Returns the human-readable prefix for Base58Check-encoded transparent
|
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
||||||
/// pay-to-public-key-hash payment addresses for the network to which this Parameters value
|
self.network_type().b58_pubkey_address_prefix()
|
||||||
/// applies.
|
}
|
||||||
///
|
|
||||||
/// [`TransparentAddress::PublicKey`]: zcash_primitives::legacy::TransparentAddress::PublicKey
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2];
|
|
||||||
|
|
||||||
/// Returns the human-readable prefix for Base58Check-encoded transparent pay-to-script-hash
|
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
||||||
/// payment addresses for the network to which this Parameters value applies.
|
self.network_type().b58_script_address_prefix()
|
||||||
///
|
}
|
||||||
/// [`TransparentAddress::Script`]: zcash_primitives::legacy::TransparentAddress::Script
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker struct for the production network.
|
/// Marker struct for the production network.
|
||||||
|
@ -208,6 +325,10 @@ memuse::impl_no_dynamic_usage!(MainNetwork);
|
||||||
pub const MAIN_NETWORK: MainNetwork = MainNetwork;
|
pub const MAIN_NETWORK: MainNetwork = MainNetwork;
|
||||||
|
|
||||||
impl Parameters for MainNetwork {
|
impl Parameters for MainNetwork {
|
||||||
|
fn network_type(&self) -> NetworkType {
|
||||||
|
NetworkType::Main
|
||||||
|
}
|
||||||
|
|
||||||
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
||||||
match nu {
|
match nu {
|
||||||
NetworkUpgrade::Overwinter => Some(BlockHeight(347_500)),
|
NetworkUpgrade::Overwinter => Some(BlockHeight(347_500)),
|
||||||
|
@ -222,34 +343,6 @@ impl Parameters for MainNetwork {
|
||||||
NetworkUpgrade::ZFuture => None,
|
NetworkUpgrade::ZFuture => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coin_type(&self) -> u32 {
|
|
||||||
constants::mainnet::COIN_TYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
fn address_network(&self) -> Option<zcash_address::Network> {
|
|
||||||
Some(zcash_address::Network::Main)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str {
|
|
||||||
constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
|
|
||||||
constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str {
|
|
||||||
constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker struct for the test network.
|
/// Marker struct for the test network.
|
||||||
|
@ -262,6 +355,10 @@ memuse::impl_no_dynamic_usage!(TestNetwork);
|
||||||
pub const TEST_NETWORK: TestNetwork = TestNetwork;
|
pub const TEST_NETWORK: TestNetwork = TestNetwork;
|
||||||
|
|
||||||
impl Parameters for TestNetwork {
|
impl Parameters for TestNetwork {
|
||||||
|
fn network_type(&self) -> NetworkType {
|
||||||
|
NetworkType::Test
|
||||||
|
}
|
||||||
|
|
||||||
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
||||||
match nu {
|
match nu {
|
||||||
NetworkUpgrade::Overwinter => Some(BlockHeight(207_500)),
|
NetworkUpgrade::Overwinter => Some(BlockHeight(207_500)),
|
||||||
|
@ -276,99 +373,38 @@ impl Parameters for TestNetwork {
|
||||||
NetworkUpgrade::ZFuture => None,
|
NetworkUpgrade::ZFuture => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coin_type(&self) -> u32 {
|
|
||||||
constants::testnet::COIN_TYPE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_network(&self) -> Option<zcash_address::Network> {
|
/// The enumeration of known Zcash networks.
|
||||||
Some(zcash_address::Network::Test)
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::testnet::B58_PUBKEY_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::testnet::B58_SCRIPT_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Marker enum for the deployed Zcash consensus networks.
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
|
||||||
pub enum Network {
|
pub enum Network {
|
||||||
|
/// Zcash Mainnet.
|
||||||
MainNetwork,
|
MainNetwork,
|
||||||
|
/// Zcash Testnet.
|
||||||
TestNetwork,
|
TestNetwork,
|
||||||
|
/// Private integration / regression testing, used in `zcashd`.
|
||||||
|
#[cfg(feature = "local-consensus")]
|
||||||
|
Regtest(LocalNetwork),
|
||||||
}
|
}
|
||||||
|
|
||||||
memuse::impl_no_dynamic_usage!(Network);
|
memuse::impl_no_dynamic_usage!(Network);
|
||||||
|
|
||||||
impl Parameters for Network {
|
impl Parameters for Network {
|
||||||
|
fn network_type(&self) -> NetworkType {
|
||||||
|
match self {
|
||||||
|
Network::MainNetwork => NetworkType::Main,
|
||||||
|
Network::TestNetwork => NetworkType::Test,
|
||||||
|
#[cfg(feature = "local-consensus")]
|
||||||
|
Network::Regtest(_) => NetworkType::Regtest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
||||||
match self {
|
match self {
|
||||||
Network::MainNetwork => MAIN_NETWORK.activation_height(nu),
|
Network::MainNetwork => MAIN_NETWORK.activation_height(nu),
|
||||||
Network::TestNetwork => TEST_NETWORK.activation_height(nu),
|
Network::TestNetwork => TEST_NETWORK.activation_height(nu),
|
||||||
}
|
#[cfg(feature = "local-consensus")]
|
||||||
}
|
Network::Regtest(network_params) => network_params.activation_height(nu),
|
||||||
|
|
||||||
fn coin_type(&self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.coin_type(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.coin_type(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn address_network(&self) -> Option<zcash_address::Network> {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => Some(zcash_address::Network::Main),
|
|
||||||
Network::TestNetwork => Some(zcash_address::Network::Test),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_spending_key(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.hrp_sapling_extended_spending_key(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_full_viewing_key(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.hrp_sapling_extended_full_viewing_key(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_payment_address(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.hrp_sapling_payment_address(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.b58_pubkey_address_prefix(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.b58_pubkey_address_prefix(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
|
||||||
match self {
|
|
||||||
Network::MainNetwork => MAIN_NETWORK.b58_script_address_prefix(),
|
|
||||||
Network::TestNetwork => TEST_NETWORK.b58_script_address_prefix(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviews";
|
||||||
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
||||||
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zs";
|
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zs";
|
||||||
|
|
||||||
|
/// The prefix for a Base58Check-encoded mainnet Sprout address
|
||||||
|
///
|
||||||
|
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
||||||
|
///
|
||||||
|
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
||||||
|
pub const B58_SPROUT_ADDRESS_PREFIX: [u8; 2] = [0x16, 0x9a];
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded mainnet [`PublicKeyHash`].
|
/// The prefix for a Base58Check-encoded mainnet [`PublicKeyHash`].
|
||||||
///
|
///
|
||||||
/// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html
|
/// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html
|
||||||
|
|
|
@ -33,6 +33,14 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewregtestsapling";
|
||||||
/// [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 Sprout address
|
||||||
|
///
|
||||||
|
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
||||||
|
/// Same as the testnet prefix.
|
||||||
|
///
|
||||||
|
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
||||||
|
pub const B58_SPROUT_ADDRESS_PREFIX: [u8; 2] = [0x16, 0xb6];
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded regtest transparent [`PublicKeyHash`].
|
/// The prefix for a Base58Check-encoded regtest transparent [`PublicKeyHash`].
|
||||||
/// Same as the testnet prefix.
|
/// Same as the testnet prefix.
|
||||||
///
|
///
|
||||||
|
|
|
@ -29,6 +29,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewtestsapling";
|
||||||
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
||||||
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "ztestsapling";
|
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "ztestsapling";
|
||||||
|
|
||||||
|
/// The prefix for a Base58Check-encoded testnet Sprout address
|
||||||
|
///
|
||||||
|
/// Defined in the [Zcash Protocol Specification section 5.6.3][sproutpaymentaddrencoding].
|
||||||
|
///
|
||||||
|
/// [sproutpaymentaddrencoding]: https://zips.z.cash/protocol/protocol.pdf#sproutpaymentaddrencoding
|
||||||
|
pub const B58_SPROUT_ADDRESS_PREFIX: [u8; 2] = [0x16, 0xb6];
|
||||||
|
|
||||||
/// The prefix for a Base58Check-encoded testnet transparent [`PublicKeyHash`].
|
/// The prefix for a Base58Check-encoded testnet transparent [`PublicKeyHash`].
|
||||||
///
|
///
|
||||||
/// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html
|
/// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::consensus::{BlockHeight, NetworkType, NetworkUpgrade, Parameters};
|
||||||
consensus::{BlockHeight, NetworkUpgrade, Parameters},
|
|
||||||
constants,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// a `LocalNetwork` setup should define the activation heights
|
/// a `LocalNetwork` setup should define the activation heights
|
||||||
/// of network upgrades. `None` is considered as "not activated"
|
/// of network upgrades. `None` is considered as "not activated"
|
||||||
|
@ -36,7 +33,7 @@ use crate::{
|
||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)]
|
||||||
pub struct LocalNetwork {
|
pub struct LocalNetwork {
|
||||||
pub overwinter: Option<BlockHeight>,
|
pub overwinter: Option<BlockHeight>,
|
||||||
pub sapling: Option<BlockHeight>,
|
pub sapling: Option<BlockHeight>,
|
||||||
|
@ -44,18 +41,18 @@ pub struct LocalNetwork {
|
||||||
pub heartwood: Option<BlockHeight>,
|
pub heartwood: Option<BlockHeight>,
|
||||||
pub canopy: Option<BlockHeight>,
|
pub canopy: Option<BlockHeight>,
|
||||||
pub nu5: Option<BlockHeight>,
|
pub nu5: Option<BlockHeight>,
|
||||||
|
#[cfg(feature = "unstable-nu6")]
|
||||||
pub nu6: Option<BlockHeight>,
|
pub nu6: Option<BlockHeight>,
|
||||||
#[cfg(feature = "zfuture")]
|
#[cfg(feature = "zfuture")]
|
||||||
pub z_future: Option<BlockHeight>,
|
pub z_future: Option<BlockHeight>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameters default implementation for `LocalNetwork`
|
/// Parameters implementation for `LocalNetwork`
|
||||||
/// Important note:
|
|
||||||
/// The functions `coin_type()`, `address_network()`,
|
|
||||||
/// `hrp_sapling_extended_spending_key()`, `hrp_sapling_extended_full_viewing_key()`,
|
|
||||||
/// `hrp_sapling_payment_address()`, `b58_script_address_prefix()` return
|
|
||||||
/// `constants::regtest` values
|
|
||||||
impl Parameters for LocalNetwork {
|
impl Parameters for LocalNetwork {
|
||||||
|
fn network_type(&self) -> NetworkType {
|
||||||
|
NetworkType::Regtest
|
||||||
|
}
|
||||||
|
|
||||||
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
|
||||||
match nu {
|
match nu {
|
||||||
NetworkUpgrade::Overwinter => self.overwinter,
|
NetworkUpgrade::Overwinter => self.overwinter,
|
||||||
|
@ -70,44 +67,12 @@ impl Parameters for LocalNetwork {
|
||||||
NetworkUpgrade::ZFuture => self.z_future,
|
NetworkUpgrade::ZFuture => self.z_future,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coin_type(&self) -> u32 {
|
|
||||||
constants::regtest::COIN_TYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
fn address_network(&self) -> Option<zcash_address::Network> {
|
|
||||||
Some(zcash_address::Network::Regtest)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str {
|
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
|
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str {
|
|
||||||
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::regtest::B58_SCRIPT_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool {
|
|
||||||
self.activation_height(nu).map_or(false, |h| h <= height)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
consensus::{BlockHeight, NetworkUpgrade, Parameters},
|
consensus::{BlockHeight, NetworkConstants, NetworkUpgrade, Parameters},
|
||||||
constants,
|
constants,
|
||||||
local_consensus::LocalNetwork,
|
local_consensus::LocalNetwork,
|
||||||
};
|
};
|
||||||
|
@ -148,24 +113,6 @@ mod tests {
|
||||||
assert!(regtest.is_nu_active(NetworkUpgrade::Nu6, expected_nu6));
|
assert!(regtest.is_nu_active(NetworkUpgrade::Nu6, expected_nu6));
|
||||||
#[cfg(feature = "zfuture")]
|
#[cfg(feature = "zfuture")]
|
||||||
assert!(!regtest.is_nu_active(NetworkUpgrade::ZFuture, expected_nu5));
|
assert!(!regtest.is_nu_active(NetworkUpgrade::ZFuture, expected_nu5));
|
||||||
|
|
||||||
assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE);
|
|
||||||
assert_eq!(
|
|
||||||
regtest.hrp_sapling_extended_spending_key(),
|
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
regtest.hrp_sapling_extended_full_viewing_key(),
|
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
regtest.hrp_sapling_payment_address(),
|
|
||||||
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
regtest.b58_pubkey_address_prefix(),
|
|
||||||
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -251,25 +198,30 @@ mod tests {
|
||||||
z_future: Some(expected_z_future),
|
z_future: Some(expected_z_future),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
regtest.hrp_sapling_extended_spending_key(),
|
regtest.network_type().coin_type(),
|
||||||
|
constants::regtest::COIN_TYPE
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
regtest.network_type().hrp_sapling_extended_spending_key(),
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
regtest.hrp_sapling_extended_full_viewing_key(),
|
regtest
|
||||||
|
.network_type()
|
||||||
|
.hrp_sapling_extended_full_viewing_key(),
|
||||||
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
regtest.hrp_sapling_payment_address(),
|
regtest.network_type().hrp_sapling_payment_address(),
|
||||||
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
|
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
regtest.b58_pubkey_address_prefix(),
|
regtest.network_type().b58_pubkey_address_prefix(),
|
||||||
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
|
constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
regtest.b58_script_address_prefix(),
|
regtest.network_type().b58_script_address_prefix(),
|
||||||
constants::regtest::B58_SCRIPT_ADDRESS_PREFIX
|
constants::regtest::B58_SCRIPT_ADDRESS_PREFIX
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@ use nom::{
|
||||||
sequence::preceded,
|
sequence::preceded,
|
||||||
};
|
};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus,
|
|
||||||
memo::{self, MemoBytes},
|
memo::{self, MemoBytes},
|
||||||
transaction::components::amount::NonNegativeAmount,
|
transaction::components::amount::NonNegativeAmount,
|
||||||
};
|
};
|
||||||
|
use zcash_protocol::consensus;
|
||||||
|
|
||||||
use crate::address::Address;
|
use crate::address::Address;
|
||||||
|
|
||||||
|
@ -819,10 +819,10 @@ mod tests {
|
||||||
|
|
||||||
use zcash_keys::address::testing::arb_addr;
|
use zcash_keys::address::testing::arb_addr;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{Parameters, TEST_NETWORK},
|
|
||||||
memo::Memo,
|
memo::Memo,
|
||||||
transaction::components::amount::{testing::arb_nonnegative_amount, NonNegativeAmount},
|
transaction::components::amount::{testing::arb_nonnegative_amount, NonNegativeAmount},
|
||||||
};
|
};
|
||||||
|
use zcash_protocol::consensus::{NetworkConstants, NetworkType, TEST_NETWORK};
|
||||||
|
|
||||||
#[cfg(feature = "local-consensus")]
|
#[cfg(feature = "local-consensus")]
|
||||||
use zcash_primitives::{local_consensus::LocalNetwork, BlockHeight};
|
use zcash_primitives::{local_consensus::LocalNetwork, BlockHeight};
|
||||||
|
@ -870,7 +870,7 @@ mod tests {
|
||||||
let expected = TransactionRequest::new(
|
let expected = TransactionRequest::new(
|
||||||
vec![
|
vec![
|
||||||
Payment {
|
Payment {
|
||||||
recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
recipient_address: Address::Sapling(decode_payment_address(NetworkType::Test.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
||||||
amount: NonNegativeAmount::const_from_u64(376876902796286),
|
amount: NonNegativeAmount::const_from_u64(376876902796286),
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -891,7 +891,7 @@ mod tests {
|
||||||
let expected = TransactionRequest::new(
|
let expected = TransactionRequest::new(
|
||||||
vec![
|
vec![
|
||||||
Payment {
|
Payment {
|
||||||
recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
recipient_address: Address::Sapling(decode_payment_address(NetworkType::Test.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
||||||
amount: NonNegativeAmount::ZERO,
|
amount: NonNegativeAmount::ZERO,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -909,7 +909,7 @@ mod tests {
|
||||||
let req = TransactionRequest::new(
|
let req = TransactionRequest::new(
|
||||||
vec![
|
vec![
|
||||||
Payment {
|
Payment {
|
||||||
recipient_address: Address::Sapling(decode_payment_address(TEST_NETWORK.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
recipient_address: Address::Sapling(decode_payment_address(NetworkType::Test.hrp_sapling_payment_address(), "ztestsapling1n65uaftvs2g7075q2x2a04shfk066u3lldzxsrprfrqtzxnhc9ps73v4lhx4l9yfxj46sl0q90k").unwrap()),
|
||||||
amount: NonNegativeAmount::ZERO,
|
amount: NonNegativeAmount::ZERO,
|
||||||
memo: None,
|
memo: None,
|
||||||
label: None,
|
label: None,
|
||||||
|
|
|
@ -1330,6 +1330,8 @@ mod tests {
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
#[test]
|
#[test]
|
||||||
pub(crate) fn fsblockdb_api() {
|
pub(crate) fn fsblockdb_api() {
|
||||||
|
use zcash_primitives::consensus::NetworkConstants;
|
||||||
|
|
||||||
let mut st = TestBuilder::new().with_fs_block_cache().build();
|
let mut st = TestBuilder::new().with_fs_block_cache().build();
|
||||||
|
|
||||||
// The BlockMeta DB starts off empty.
|
// The BlockMeta DB starts off empty.
|
||||||
|
@ -1338,7 +1340,11 @@ mod tests {
|
||||||
// Generate some fake CompactBlocks.
|
// Generate some fake CompactBlocks.
|
||||||
let seed = [0u8; 32];
|
let seed = [0u8; 32];
|
||||||
let account = AccountId::ZERO;
|
let account = AccountId::ZERO;
|
||||||
let extsk = sapling::spending_key(&seed, st.wallet().params.coin_type(), account);
|
let extsk = sapling::spending_key(
|
||||||
|
&seed,
|
||||||
|
st.wallet().params.network_type().coin_type(),
|
||||||
|
account,
|
||||||
|
);
|
||||||
let dfvk = extsk.to_diversifiable_full_viewing_key();
|
let dfvk = extsk.to_diversifiable_full_viewing_key();
|
||||||
let (h1, meta1, _) = st.generate_next_block(
|
let (h1, meta1, _) = st.generate_next_block(
|
||||||
&dfvk,
|
&dfvk,
|
||||||
|
|
|
@ -176,7 +176,9 @@ mod tests {
|
||||||
|
|
||||||
use ::sapling::zip32::ExtendedFullViewingKey;
|
use ::sapling::zip32::ExtendedFullViewingKey;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{self, BlockHeight, BranchId, Network, NetworkUpgrade, Parameters},
|
consensus::{
|
||||||
|
self, BlockHeight, BranchId, Network, NetworkConstants, NetworkUpgrade, Parameters,
|
||||||
|
},
|
||||||
transaction::{TransactionData, TxVersion},
|
transaction::{TransactionData, TxVersion},
|
||||||
zip32::AccountId,
|
zip32::AccountId,
|
||||||
};
|
};
|
||||||
|
@ -698,11 +700,13 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let address = encode_payment_address(
|
let address = encode_payment_address(
|
||||||
wdb.params.hrp_sapling_payment_address(),
|
wdb.params.network_type().hrp_sapling_payment_address(),
|
||||||
&extfvk.default_address().1,
|
&extfvk.default_address().1,
|
||||||
);
|
);
|
||||||
let extfvk = encode_extended_full_viewing_key(
|
let extfvk = encode_extended_full_viewing_key(
|
||||||
wdb.params.hrp_sapling_extended_full_viewing_key(),
|
wdb.params
|
||||||
|
.network_type()
|
||||||
|
.hrp_sapling_extended_full_viewing_key(),
|
||||||
extfvk,
|
extfvk,
|
||||||
);
|
);
|
||||||
wdb.conn.execute(
|
wdb.conn.execute(
|
||||||
|
@ -723,7 +727,8 @@ mod tests {
|
||||||
|
|
||||||
let seed = [0xab; 32];
|
let seed = [0xab; 32];
|
||||||
let account = AccountId::ZERO;
|
let account = AccountId::ZERO;
|
||||||
let secret_key = sapling::spending_key(&seed, db_data.params.coin_type(), account);
|
let secret_key =
|
||||||
|
sapling::spending_key(&seed, db_data.params.network_type().coin_type(), account);
|
||||||
let extfvk = secret_key.to_extended_full_viewing_key();
|
let extfvk = secret_key.to_extended_full_viewing_key();
|
||||||
|
|
||||||
init_0_3_0(&mut db_data, &extfvk, account).unwrap();
|
init_0_3_0(&mut db_data, &extfvk, account).unwrap();
|
||||||
|
@ -835,11 +840,13 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let address = encode_payment_address(
|
let address = encode_payment_address(
|
||||||
wdb.params.hrp_sapling_payment_address(),
|
wdb.params.network_type().hrp_sapling_payment_address(),
|
||||||
&extfvk.default_address().1,
|
&extfvk.default_address().1,
|
||||||
);
|
);
|
||||||
let extfvk = encode_extended_full_viewing_key(
|
let extfvk = encode_extended_full_viewing_key(
|
||||||
wdb.params.hrp_sapling_extended_full_viewing_key(),
|
wdb.params
|
||||||
|
.network_type()
|
||||||
|
.hrp_sapling_extended_full_viewing_key(),
|
||||||
extfvk,
|
extfvk,
|
||||||
);
|
);
|
||||||
wdb.conn.execute(
|
wdb.conn.execute(
|
||||||
|
@ -894,7 +901,8 @@ mod tests {
|
||||||
|
|
||||||
let seed = [0xab; 32];
|
let seed = [0xab; 32];
|
||||||
let account = AccountId::ZERO;
|
let account = AccountId::ZERO;
|
||||||
let secret_key = sapling::spending_key(&seed, db_data.params.coin_type(), account);
|
let secret_key =
|
||||||
|
sapling::spending_key(&seed, db_data.params.network_type().coin_type(), account);
|
||||||
let extfvk = secret_key.to_extended_full_viewing_key();
|
let extfvk = secret_key.to_extended_full_viewing_key();
|
||||||
|
|
||||||
init_autoshielding(&mut db_data, &extfvk, account).unwrap();
|
init_autoshielding(&mut db_data, &extfvk, account).unwrap();
|
||||||
|
|
|
@ -484,8 +484,7 @@ mod tests {
|
||||||
|
|
||||||
use sapling::{zip32::ExtendedSpendingKey, Node, Rseed};
|
use sapling::{zip32::ExtendedSpendingKey, Node, Rseed};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
consensus::{BlockHeight, BranchId, NetworkUpgrade, Parameters},
|
consensus::{BlockHeight, BranchId, NetworkType, NetworkUpgrade, Parameters},
|
||||||
constants,
|
|
||||||
extensions::transparent::{self as tze, Extension, FromPayload, ToPayload},
|
extensions::transparent::{self as tze, Extension, FromPayload, ToPayload},
|
||||||
legacy::TransparentAddress,
|
legacy::TransparentAddress,
|
||||||
transaction::{
|
transaction::{
|
||||||
|
@ -520,34 +519,11 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_network(&self) -> Option<zcash_address::Network> {
|
fn network_type(&self) -> NetworkType {
|
||||||
None
|
NetworkType::Test
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coin_type(&self) -> u32 {
|
|
||||||
constants::testnet::COIN_TYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_spending_key(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hrp_sapling_payment_address(&self) -> &str {
|
|
||||||
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::testnet::B58_PUBKEY_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b58_script_address_prefix(&self) -> [u8; 2] {
|
|
||||||
constants::testnet::B58_SCRIPT_ADDRESS_PREFIX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn demo_hashes(preimage_1: &[u8; 32], preimage_2: &[u8; 32]) -> ([u8; 32], [u8; 32]) {
|
fn demo_hashes(preimage_1: &[u8; 32], preimage_2: &[u8; 32]) -> ([u8; 32], [u8; 32]) {
|
||||||
let hash_2 = {
|
let hash_2 = {
|
||||||
let mut hash = [0; 32];
|
let mut hash = [0; 32];
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
use zcash_address::{
|
use zcash_address::{
|
||||||
unified::{self, Container, Encoding, Typecode},
|
unified::{self, Container, Encoding, Typecode},
|
||||||
ConversionError, Network, ToAddress, TryFromRawAddress, ZcashAddress,
|
ConversionError, ToAddress, TryFromRawAddress, ZcashAddress,
|
||||||
};
|
};
|
||||||
use zcash_primitives::{consensus, legacy::TransparentAddress};
|
use zcash_primitives::legacy::TransparentAddress;
|
||||||
|
use zcash_protocol::consensus::{self, NetworkType};
|
||||||
|
|
||||||
#[cfg(feature = "sapling")]
|
#[cfg(feature = "sapling")]
|
||||||
use sapling::PaymentAddress;
|
use sapling::PaymentAddress;
|
||||||
|
@ -172,7 +173,7 @@ impl UnifiedAddress {
|
||||||
&self.unknown
|
&self.unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_address(&self, net: Network) -> ZcashAddress {
|
fn to_address(&self, net: NetworkType) -> ZcashAddress {
|
||||||
let items = self
|
let items = self
|
||||||
.unknown
|
.unknown
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -209,8 +210,7 @@ impl UnifiedAddress {
|
||||||
|
|
||||||
/// Returns the string encoding of this `UnifiedAddress` for the given network.
|
/// Returns the string encoding of this `UnifiedAddress` for the given network.
|
||||||
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
|
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
|
||||||
self.to_address(params.address_network().expect("Unrecognized network"))
|
self.to_address(params.network_type()).to_string()
|
||||||
.to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of receiver typecodes.
|
/// Returns the set of receiver typecodes.
|
||||||
|
@ -292,12 +292,11 @@ impl TryFromRawAddress for Address {
|
||||||
impl Address {
|
impl Address {
|
||||||
pub fn decode<P: consensus::Parameters>(params: &P, s: &str) -> Option<Self> {
|
pub fn decode<P: consensus::Parameters>(params: &P, s: &str) -> Option<Self> {
|
||||||
let addr = ZcashAddress::try_from_encoded(s).ok()?;
|
let addr = ZcashAddress::try_from_encoded(s).ok()?;
|
||||||
addr.convert_if_network(params.address_network().expect("Unrecognized network"))
|
addr.convert_if_network(params.network_type()).ok()
|
||||||
.ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
|
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
|
||||||
let net = params.address_network().expect("Unrecognized network");
|
let net = params.network_type();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sapling")]
|
#[cfg(feature = "sapling")]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
use crate::address::UnifiedAddress;
|
use crate::address::UnifiedAddress;
|
||||||
use bs58::{self, decode::Error as Bs58Error};
|
use bs58::{self, decode::Error as Bs58Error};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use zcash_primitives::consensus::NetworkConstants;
|
||||||
|
|
||||||
use zcash_address::unified::{self, Encoding};
|
use zcash_address::unified::{self, Encoding};
|
||||||
use zcash_primitives::{consensus, legacy::TransparentAddress};
|
use zcash_primitives::{consensus, legacy::TransparentAddress};
|
||||||
|
@ -130,16 +131,16 @@ impl<P: consensus::Parameters> AddressCodec<P> for TransparentAddress {
|
||||||
|
|
||||||
fn encode(&self, params: &P) -> String {
|
fn encode(&self, params: &P) -> String {
|
||||||
encode_transparent_address(
|
encode_transparent_address(
|
||||||
¶ms.b58_pubkey_address_prefix(),
|
¶ms.network_type().b58_pubkey_address_prefix(),
|
||||||
¶ms.b58_script_address_prefix(),
|
¶ms.network_type().b58_script_address_prefix(),
|
||||||
self,
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(params: &P, address: &str) -> Result<TransparentAddress, TransparentCodecError> {
|
fn decode(params: &P, address: &str) -> Result<TransparentAddress, TransparentCodecError> {
|
||||||
decode_transparent_address(
|
decode_transparent_address(
|
||||||
¶ms.b58_pubkey_address_prefix(),
|
¶ms.network_type().b58_pubkey_address_prefix(),
|
||||||
¶ms.b58_script_address_prefix(),
|
¶ms.network_type().b58_script_address_prefix(),
|
||||||
address,
|
address,
|
||||||
)
|
)
|
||||||
.map_err(TransparentCodecError::Base58)
|
.map_err(TransparentCodecError::Base58)
|
||||||
|
@ -154,11 +155,11 @@ impl<P: consensus::Parameters> AddressCodec<P> for sapling::PaymentAddress {
|
||||||
type Error = Bech32DecodeError;
|
type Error = Bech32DecodeError;
|
||||||
|
|
||||||
fn encode(&self, params: &P) -> String {
|
fn encode(&self, params: &P) -> String {
|
||||||
encode_payment_address(params.hrp_sapling_payment_address(), self)
|
encode_payment_address(params.network_type().hrp_sapling_payment_address(), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(params: &P, address: &str) -> Result<Self, Bech32DecodeError> {
|
fn decode(params: &P, address: &str) -> Result<Self, Bech32DecodeError> {
|
||||||
decode_payment_address(params.hrp_sapling_payment_address(), address)
|
decode_payment_address(params.network_type().hrp_sapling_payment_address(), address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ impl<P: consensus::Parameters> AddressCodec<P> for UnifiedAddress {
|
||||||
unified::Address::decode(address)
|
unified::Address::decode(address)
|
||||||
.map_err(|e| format!("{}", e))
|
.map_err(|e| format!("{}", e))
|
||||||
.and_then(|(network, addr)| {
|
.and_then(|(network, addr)| {
|
||||||
if params.address_network() == Some(network) {
|
if params.network_type() == network {
|
||||||
UnifiedAddress::try_from(addr).map_err(|e| e.to_owned())
|
UnifiedAddress::try_from(addr).map_err(|e| e.to_owned())
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
|
@ -298,7 +299,7 @@ pub fn encode_payment_address_p<P: consensus::Parameters>(
|
||||||
params: &P,
|
params: &P,
|
||||||
addr: &sapling::PaymentAddress,
|
addr: &sapling::PaymentAddress,
|
||||||
) -> String {
|
) -> String {
|
||||||
encode_payment_address(params.hrp_sapling_payment_address(), addr)
|
encode_payment_address(params.network_type().hrp_sapling_payment_address(), addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes a [`PaymentAddress`] from a Bech32-encoded string.
|
/// Decodes a [`PaymentAddress`] from a Bech32-encoded string.
|
||||||
|
@ -312,7 +313,7 @@ pub fn encode_payment_address_p<P: consensus::Parameters>(
|
||||||
/// encoding::decode_payment_address,
|
/// encoding::decode_payment_address,
|
||||||
/// };
|
/// };
|
||||||
/// use zcash_primitives::{
|
/// use zcash_primitives::{
|
||||||
/// consensus::{TEST_NETWORK, Parameters},
|
/// consensus::{TEST_NETWORK, NetworkConstants, Parameters},
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// let pa = PaymentAddress::from_bytes(&[
|
/// let pa = PaymentAddress::from_bytes(&[
|
||||||
|
@ -325,7 +326,7 @@ pub fn encode_payment_address_p<P: consensus::Parameters>(
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// decode_payment_address(
|
/// decode_payment_address(
|
||||||
/// TEST_NETWORK.hrp_sapling_payment_address(),
|
/// TEST_NETWORK.network_type().hrp_sapling_payment_address(),
|
||||||
/// "ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk",
|
/// "ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk",
|
||||||
/// ),
|
/// ),
|
||||||
/// Ok(pa),
|
/// Ok(pa),
|
||||||
|
@ -357,14 +358,14 @@ pub fn decode_payment_address(
|
||||||
/// encoding::encode_transparent_address,
|
/// encoding::encode_transparent_address,
|
||||||
/// };
|
/// };
|
||||||
/// use zcash_primitives::{
|
/// use zcash_primitives::{
|
||||||
/// consensus::{TEST_NETWORK, Parameters},
|
/// consensus::{TEST_NETWORK, NetworkConstants, Parameters},
|
||||||
/// legacy::TransparentAddress,
|
/// legacy::TransparentAddress,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// encode_transparent_address(
|
/// encode_transparent_address(
|
||||||
/// &TEST_NETWORK.b58_pubkey_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(),
|
||||||
/// &TEST_NETWORK.b58_script_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_script_address_prefix(),
|
||||||
/// &TransparentAddress::PublicKeyHash([0; 20]),
|
/// &TransparentAddress::PublicKeyHash([0; 20]),
|
||||||
/// ),
|
/// ),
|
||||||
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
||||||
|
@ -372,8 +373,8 @@ pub fn decode_payment_address(
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// encode_transparent_address(
|
/// encode_transparent_address(
|
||||||
/// &TEST_NETWORK.b58_pubkey_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(),
|
||||||
/// &TEST_NETWORK.b58_script_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_script_address_prefix(),
|
||||||
/// &TransparentAddress::ScriptHash([0; 20]),
|
/// &TransparentAddress::ScriptHash([0; 20]),
|
||||||
/// ),
|
/// ),
|
||||||
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
||||||
|
@ -410,8 +411,8 @@ pub fn encode_transparent_address_p<P: consensus::Parameters>(
|
||||||
addr: &TransparentAddress,
|
addr: &TransparentAddress,
|
||||||
) -> String {
|
) -> String {
|
||||||
encode_transparent_address(
|
encode_transparent_address(
|
||||||
¶ms.b58_pubkey_address_prefix(),
|
¶ms.network_type().b58_pubkey_address_prefix(),
|
||||||
¶ms.b58_script_address_prefix(),
|
¶ms.network_type().b58_script_address_prefix(),
|
||||||
addr,
|
addr,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -422,17 +423,17 @@ pub fn encode_transparent_address_p<P: consensus::Parameters>(
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use zcash_primitives::{
|
/// use zcash_primitives::{
|
||||||
/// consensus::{TEST_NETWORK, Parameters},
|
/// consensus::{TEST_NETWORK, NetworkConstants, Parameters},
|
||||||
|
/// legacy::TransparentAddress,
|
||||||
/// };
|
/// };
|
||||||
/// use zcash_keys::{
|
/// use zcash_keys::{
|
||||||
/// encoding::decode_transparent_address,
|
/// encoding::decode_transparent_address,
|
||||||
/// };
|
/// };
|
||||||
/// use zcash_primitives::legacy::TransparentAddress;
|
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// decode_transparent_address(
|
/// decode_transparent_address(
|
||||||
/// &TEST_NETWORK.b58_pubkey_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(),
|
||||||
/// &TEST_NETWORK.b58_script_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_script_address_prefix(),
|
||||||
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
||||||
/// ),
|
/// ),
|
||||||
/// Ok(Some(TransparentAddress::PublicKeyHash([0; 20]))),
|
/// Ok(Some(TransparentAddress::PublicKeyHash([0; 20]))),
|
||||||
|
@ -440,8 +441,8 @@ pub fn encode_transparent_address_p<P: consensus::Parameters>(
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// decode_transparent_address(
|
/// decode_transparent_address(
|
||||||
/// &TEST_NETWORK.b58_pubkey_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(),
|
||||||
/// &TEST_NETWORK.b58_script_address_prefix(),
|
/// &TEST_NETWORK.network_type().b58_script_address_prefix(),
|
||||||
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
||||||
/// ),
|
/// ),
|
||||||
/// Ok(Some(TransparentAddress::ScriptHash([0; 20]))),
|
/// Ok(Some(TransparentAddress::ScriptHash([0; 20]))),
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
//! Helper functions for managing light client key material.
|
//! Helper functions for managing light client key material.
|
||||||
use zcash_address::unified::{self, Container, Encoding, Typecode};
|
use zcash_address::unified::{self, Container, Encoding, Typecode};
|
||||||
use zcash_primitives::{
|
use zcash_protocol::consensus::{self, NetworkConstants};
|
||||||
consensus,
|
use zip32::{AccountId, DiversifierIndex};
|
||||||
zip32::{AccountId, DiversifierIndex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::address::UnifiedAddress;
|
use crate::address::UnifiedAddress;
|
||||||
|
|
||||||
|
@ -190,11 +188,11 @@ impl UnifiedSpendingKey {
|
||||||
transparent: legacy::AccountPrivKey::from_seed(_params, seed, _account)
|
transparent: legacy::AccountPrivKey::from_seed(_params, seed, _account)
|
||||||
.map_err(DerivationError::Transparent)?,
|
.map_err(DerivationError::Transparent)?,
|
||||||
#[cfg(feature = "sapling")]
|
#[cfg(feature = "sapling")]
|
||||||
sapling: sapling::spending_key(seed, _params.coin_type(), _account),
|
sapling: sapling::spending_key(seed, _params.network_type().coin_type(), _account),
|
||||||
#[cfg(feature = "orchard")]
|
#[cfg(feature = "orchard")]
|
||||||
orchard: orchard::keys::SpendingKey::from_zip32_seed(
|
orchard: orchard::keys::SpendingKey::from_zip32_seed(
|
||||||
seed,
|
seed,
|
||||||
_params.coin_type(),
|
_params.network_type().coin_type(),
|
||||||
_account,
|
_account,
|
||||||
)
|
)
|
||||||
.map_err(DerivationError::Orchard)?,
|
.map_err(DerivationError::Orchard)?,
|
||||||
|
@ -554,7 +552,7 @@ impl UnifiedFullViewingKey {
|
||||||
/// [ZIP 316]: https://zips.z.cash/zip-0316
|
/// [ZIP 316]: https://zips.z.cash/zip-0316
|
||||||
pub fn decode<P: consensus::Parameters>(params: &P, encoding: &str) -> Result<Self, String> {
|
pub fn decode<P: consensus::Parameters>(params: &P, encoding: &str) -> Result<Self, String> {
|
||||||
let (net, ufvk) = unified::Ufvk::decode(encoding).map_err(|e| e.to_string())?;
|
let (net, ufvk) = unified::Ufvk::decode(encoding).map_err(|e| e.to_string())?;
|
||||||
let expected_net = params.address_network().expect("Unrecognized network");
|
let expected_net = params.network_type();
|
||||||
if net != expected_net {
|
if net != expected_net {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"UFVK is for network {:?} but we expected {:?}",
|
"UFVK is for network {:?} but we expected {:?}",
|
||||||
|
@ -663,7 +661,7 @@ impl UnifiedFullViewingKey {
|
||||||
|
|
||||||
let ufvk = unified::Ufvk::try_from_items(items.collect())
|
let ufvk = unified::Ufvk::try_from_items(items.collect())
|
||||||
.expect("UnifiedFullViewingKey should only be constructed safely");
|
.expect("UnifiedFullViewingKey should only be constructed safely");
|
||||||
ufvk.encode(¶ms.address_network().expect("Unrecognized network"))
|
ufvk.encode(¶ms.network_type())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transparent component of the unified key at the
|
/// Returns the transparent component of the unified key at the
|
||||||
|
|
|
@ -7,9 +7,10 @@ use hdwallet::{
|
||||||
use secp256k1::PublicKey;
|
use secp256k1::PublicKey;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use subtle::{Choice, ConstantTimeEq};
|
use subtle::{Choice, ConstantTimeEq};
|
||||||
use zcash_spec::PrfExpand;
|
|
||||||
|
|
||||||
use crate::{consensus, zip32::AccountId};
|
use zcash_protocol::consensus::{self, NetworkConstants};
|
||||||
|
use zcash_spec::PrfExpand;
|
||||||
|
use zip32::AccountId;
|
||||||
|
|
||||||
use super::TransparentAddress;
|
use super::TransparentAddress;
|
||||||
|
|
||||||
|
@ -119,7 +120,9 @@ impl AccountPrivKey {
|
||||||
) -> Result<AccountPrivKey, hdwallet::error::Error> {
|
) -> Result<AccountPrivKey, hdwallet::error::Error> {
|
||||||
ExtendedPrivKey::with_seed(seed)?
|
ExtendedPrivKey::with_seed(seed)?
|
||||||
.derive_private_key(KeyIndex::hardened_from_normalize_index(44)?)?
|
.derive_private_key(KeyIndex::hardened_from_normalize_index(44)?)?
|
||||||
.derive_private_key(KeyIndex::hardened_from_normalize_index(params.coin_type())?)?
|
.derive_private_key(KeyIndex::hardened_from_normalize_index(
|
||||||
|
params.network_type().coin_type(),
|
||||||
|
)?)?
|
||||||
.derive_private_key(KeyIndex::hardened_from_normalize_index(account.into())?)
|
.derive_private_key(KeyIndex::hardened_from_normalize_index(account.into())?)
|
||||||
.map(AccountPrivKey)
|
.map(AccountPrivKey)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue