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:
Kris Nuttycombe 2024-02-02 17:28:14 -07:00
parent 64454100c5
commit 4b18426fcd
25 changed files with 359 additions and 417 deletions

2
Cargo.lock generated
View File

@ -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]]

View File

@ -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`

View File

@ -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"

View File

@ -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
// We will not define new Base58Check address encodings. | mainnet::B58_SCRIPT_ADDRESS_PREFIX
_ => return Err(ParseError::NotZcash), | 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.
_ => 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)
}
mainnet::B58_PUBKEY_ADDRESS_PREFIX | testnet::B58_PUBKEY_ADDRESS_PREFIX => {
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!(),
} }
p2pkh::MAINNET | p2pkh::TESTNET => decoded[2..].try_into().map(AddressKind::P2pkh), .map_err(|_| ParseError::InvalidEncoding)
p2sh::MAINNET | p2sh::TESTNET => decoded[2..].try_into().map(AddressKind::P2sh), .map(|kind| ZcashAddress { kind, net });
_ => unreachable!(),
} }
.map_err(|_| ParseError::InvalidEncoding)
.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);

View File

@ -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;

View File

@ -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];

View File

@ -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];

View File

@ -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";

View File

@ -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];

View File

@ -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 {

View File

@ -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.

View File

@ -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

View File

@ -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> {
Some(zcash_address::Network::Test)
}
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. /// The enumeration of known Zcash networks.
#[derive(PartialEq, Eq, Copy, Clone, Debug)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
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(),
} }
} }
} }

View File

@ -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

View File

@ -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.
/// ///

View File

@ -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

View File

@ -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
); );
} }

View File

@ -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,

View File

@ -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,

View File

@ -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();

View File

@ -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];

View File

@ -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")]

View File

@ -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(
&params.b58_pubkey_address_prefix(), &params.network_type().b58_pubkey_address_prefix(),
&params.b58_script_address_prefix(), &params.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(
&params.b58_pubkey_address_prefix(), &params.network_type().b58_pubkey_address_prefix(),
&params.b58_script_address_prefix(), &params.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(
&params.b58_pubkey_address_prefix(), &params.network_type().b58_pubkey_address_prefix(),
&params.b58_script_address_prefix(), &params.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]))),

View File

@ -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(&params.address_network().expect("Unrecognized network")) ufvk.encode(&params.network_type())
} }
/// Returns the transparent component of the unified key at the /// Returns the transparent component of the unified key at the

View File

@ -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)
} }