diff --git a/Cargo.lock b/Cargo.lock index 03d631410b..559ea78657 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3002,6 +3002,7 @@ dependencies = [ "f4jumble", "proptest", "zcash_encoding", + "zcash_protocol", ] [[package]] @@ -3145,6 +3146,7 @@ dependencies = [ "zcash_address", "zcash_encoding", "zcash_primitives", + "zcash_protocol", "zip32", ] @@ -3236,7 +3238,6 @@ dependencies = [ "incrementalmerkletree", "memuse", "proptest", - "zcash_address", ] [[package]] diff --git a/components/zcash_address/Cargo.toml b/components/zcash_address/Cargo.toml index b797ae22d8..0613472842 100644 --- a/components/zcash_address/Cargo.toml +++ b/components/zcash_address/Cargo.toml @@ -22,7 +22,8 @@ rustdoc-args = ["--cfg", "docsrs"] bech32 = "0.9" bs58 = { version = "0.5", features = ["check"] } f4jumble = { version = "0.1", path = "../f4jumble" } -zcash_encoding = { version = "0.2", path = "../zcash_encoding" } +zcash_protocol.workspace = true +zcash_encoding.workspace = true [dev-dependencies] assert_matches = "1.3.0" @@ -30,6 +31,7 @@ proptest = "1" [features] test-dependencies = [] +regtest = ["zcash_protocol/local-consensus"] [lib] bench = false diff --git a/components/zcash_address/src/encoding.rs b/components/zcash_address/src/encoding.rs index 9e5e422ce6..0f4464ccf9 100644 --- a/components/zcash_address/src/encoding.rs +++ b/components/zcash_address/src/encoding.rs @@ -1,9 +1,11 @@ use std::{convert::TryInto, error::Error, fmt, str::FromStr}; 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::*, AddressKind, Network, ZcashAddress}; +use crate::{kind::*, AddressKind, ZcashAddress}; /// An error while attempting to parse a string as a Zcash address. #[derive(Debug, PartialEq, Eq)] @@ -68,9 +70,9 @@ impl FromStr for ZcashAddress { let data = Vec::::from_base32(&data).map_err(|_| ParseError::InvalidEncoding)?; let net = match hrp.as_str() { - sapling::MAINNET => Network::Main, - sapling::TESTNET => Network::Test, - sapling::REGTEST => Network::Regtest, + mainnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Main, + testnet::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Test, + regtest::HRP_SAPLING_PAYMENT_ADDRESS => NetworkType::Regtest, // We will not define new Bech32 address encodings. _ => { return Err(ParseError::NotZcash); @@ -87,18 +89,26 @@ impl FromStr for ZcashAddress { // The rest use Base58Check. if let Ok(decoded) = bs58::decode(s).with_check(None).into_vec() { let net = match decoded[..2].try_into().unwrap() { - sprout::MAINNET | p2pkh::MAINNET | p2sh::MAINNET => Network::Main, - sprout::TESTNET | p2pkh::TESTNET | p2sh::TESTNET => Network::Test, + mainnet::B58_PUBKEY_ADDRESS_PREFIX + | mainnet::B58_SCRIPT_ADDRESS_PREFIX + | mainnet::B58_SPROUT_ADDRESS_PREFIX => NetworkType::Main, + testnet::B58_PUBKEY_ADDRESS_PREFIX + | testnet::B58_SCRIPT_ADDRESS_PREFIX + | testnet::B58_SPROUT_ADDRESS_PREFIX => NetworkType::Test, // We will not define new Base58Check address encodings. _ => return Err(ParseError::NotZcash), }; return match decoded[..2].try_into().unwrap() { - sprout::MAINNET | sprout::TESTNET => { + mainnet::B58_SPROUT_ADDRESS_PREFIX | testnet::B58_SPROUT_ADDRESS_PREFIX => { decoded[2..].try_into().map(AddressKind::Sprout) } - p2pkh::MAINNET | p2pkh::TESTNET => decoded[2..].try_into().map(AddressKind::P2pkh), - p2sh::MAINNET | p2sh::TESTNET => decoded[2..].try_into().map(AddressKind::P2sh), + 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!(), } .map_err(|_| ParseError::InvalidEncoding) @@ -124,36 +134,13 @@ fn encode_b58(prefix: [u8; 2], data: &[u8]) -> String { impl fmt::Display for ZcashAddress { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let encoded = match &self.kind { - AddressKind::Sprout(data) => encode_b58( - match self.net { - Network::Main => sprout::MAINNET, - 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::Sprout(data) => encode_b58(self.net.b58_sprout_address_prefix(), data), + AddressKind::Sapling(data) => { + encode_bech32(self.net.hrp_sapling_payment_address(), data) + } AddressKind::Unified(addr) => addr.encode(&self.net), - AddressKind::P2pkh(data) => encode_b58( - match self.net { - 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, - ), + AddressKind::P2pkh(data) => encode_b58(self.net.b58_pubkey_address_prefix(), data), + AddressKind::P2sh(data) => encode_b58(self.net.b58_script_address_prefix(), data), }; write!(f, "{}", encoded) } @@ -162,7 +149,7 @@ impl fmt::Display for ZcashAddress { #[cfg(test)] mod tests { use super::*; - use crate::kind::unified; + use crate::{kind::unified, Network}; fn encoding(encoded: &str, decoded: ZcashAddress) { assert_eq!(decoded.to_string(), encoded); diff --git a/components/zcash_address/src/kind.rs b/components/zcash_address/src/kind.rs index 5397c027f8..38b4557a6e 100644 --- a/components/zcash_address/src/kind.rs +++ b/components/zcash_address/src/kind.rs @@ -1,7 +1 @@ pub mod unified; - -pub(crate) mod sapling; -pub(crate) mod sprout; - -pub(crate) mod p2pkh; -pub(crate) mod p2sh; diff --git a/components/zcash_address/src/kind/p2pkh.rs b/components/zcash_address/src/kind/p2pkh.rs deleted file mode 100644 index a37377d3c5..0000000000 --- a/components/zcash_address/src/kind/p2pkh.rs +++ /dev/null @@ -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]; diff --git a/components/zcash_address/src/kind/p2sh.rs b/components/zcash_address/src/kind/p2sh.rs deleted file mode 100644 index 1ebef52ab1..0000000000 --- a/components/zcash_address/src/kind/p2sh.rs +++ /dev/null @@ -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]; diff --git a/components/zcash_address/src/kind/sapling.rs b/components/zcash_address/src/kind/sapling.rs deleted file mode 100644 index 6f2e945b94..0000000000 --- a/components/zcash_address/src/kind/sapling.rs +++ /dev/null @@ -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"; diff --git a/components/zcash_address/src/kind/sprout.rs b/components/zcash_address/src/kind/sprout.rs deleted file mode 100644 index 06a8a03c79..0000000000 --- a/components/zcash_address/src/kind/sprout.rs +++ /dev/null @@ -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]; diff --git a/components/zcash_address/src/lib.rs b/components/zcash_address/src/lib.rs index a16281943e..6f516a941e 100644 --- a/components/zcash_address/src/lib.rs +++ b/components/zcash_address/src/lib.rs @@ -141,6 +141,7 @@ pub use convert::{ }; pub use encoding::ParseError; pub use kind::unified; +pub use zcash_protocol::consensus::NetworkType as Network; /// A Zcash address. #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -149,20 +150,6 @@ pub struct ZcashAddress { 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. #[derive(Clone, Debug, PartialEq, Eq, Hash)] enum AddressKind { diff --git a/components/zcash_protocol/Cargo.toml b/components/zcash_protocol/Cargo.toml index 03cc53b3b8..b5c8f651d4 100644 --- a/components/zcash_protocol/Cargo.toml +++ b/components/zcash_protocol/Cargo.toml @@ -20,8 +20,6 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -zcash_address.workspace = true - # - Logging and metrics memuse.workspace = true diff --git a/components/zcash_protocol/src/consensus.rs b/components/zcash_protocol/src/consensus.rs index c060b68f87..3d9e203b9e 100644 --- a/components/zcash_protocol/src/consensus.rs +++ b/components/zcash_protocol/src/consensus.rs @@ -5,9 +5,11 @@ use std::cmp::{Ord, Ordering}; use std::convert::TryFrom; use std::fmt; use std::ops::{Add, Bound, RangeBounds, Sub}; -use zcash_address; -use crate::constants; +use crate::constants::{self, mainnet, regtest, testnet}; + +#[cfg(feature = "local-consensus")] +use crate::local_consensus::LocalNetwork; /// A wrapper type representing blockchain heights. /// @@ -136,29 +138,15 @@ impl Sub for BlockHeight { } } -/// Zcash consensus parameters. -pub trait Parameters: Clone { - /// Returns the activation height for a particular network upgrade, - /// if an activation height has been set. - fn activation_height(&self, nu: NetworkUpgrade) -> Option; - - /// Determines whether the specified network upgrade is active as of the - /// provided block height on the network to which this Parameters value applies. - fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool { - self.activation_height(nu).map_or(false, |h| h <= height) - } - +/// 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 standard network constant for address encoding. Returns - /// 'None' for nonstandard networks. - fn address_network(&self) -> Option; - /// Returns the human-readable prefix for Bech32-encoded Sapling extended spending keys - /// the network to which this Parameters value applies. + /// the network to which this NetworkConstants value applies. /// /// Defined in [ZIP 32]. /// @@ -167,7 +155,7 @@ pub trait Parameters: Clone { fn hrp_sapling_extended_spending_key(&self) -> &str; /// Returns the human-readable prefix for Bech32-encoded Sapling extended full - /// viewing keys for the network to which this Parameters value applies. + /// viewing keys for the network to which this NetworkConstants value applies. /// /// Defined in [ZIP 32]. /// @@ -176,7 +164,7 @@ pub trait Parameters: Clone { fn hrp_sapling_extended_full_viewing_key(&self) -> &str; /// Returns the Bech32-encoded human-readable prefix for Sapling payment addresses - /// viewing keys for the network to which this Parameters value applies. + /// viewing keys for the network to which this NetworkConstants value applies. /// /// Defined in section 5.6.4 of the [Zcash Protocol Specification]. /// @@ -184,20 +172,119 @@ pub trait Parameters: Clone { /// [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 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 Parameters value + /// 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 Parameters value applies. + /// 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 => testnet::COIN_TYPE, + } + } + + fn hrp_sapling_extended_spending_key(&self) -> &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) -> &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) -> &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 => constants::mainnet::B58_SPROUT_ADDRESS_PREFIX, + NetworkType::Test => constants::testnet::B58_SPROUT_ADDRESS_PREFIX, + NetworkType::Regtest => testnet::B58_SPROUT_ADDRESS_PREFIX, + } + } + + fn b58_pubkey_address_prefix(&self) -> [u8; 2] { + match self { + NetworkType::Main => constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX, + NetworkType::Test => constants::testnet::B58_PUBKEY_ADDRESS_PREFIX, + NetworkType::Regtest => regtest::B58_PUBKEY_ADDRESS_PREFIX, + } + } + + fn b58_script_address_prefix(&self) -> [u8; 2] { + match self { + NetworkType::Main => constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX, + NetworkType::Test => constants::testnet::B58_SCRIPT_ADDRESS_PREFIX, + NetworkType::Regtest => regtest::B58_SCRIPT_ADDRESS_PREFIX, + } + } +} + +/// Zcash consensus parameters. +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, + /// if an activation height has been set. + fn activation_height(&self, nu: NetworkUpgrade) -> Option; + + /// Determines whether the specified network upgrade is active as of the + /// provided block height on the network to which this Parameters value applies. + fn is_nu_active(&self, nu: NetworkUpgrade, height: BlockHeight) -> bool { + self.activation_height(nu).map_or(false, |h| h <= height) + } +} + /// Marker struct for the production network. #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub struct MainNetwork; @@ -208,6 +295,10 @@ memuse::impl_no_dynamic_usage!(MainNetwork); pub const MAIN_NETWORK: MainNetwork = MainNetwork; impl Parameters for MainNetwork { + fn network_type(&self) -> NetworkType { + NetworkType::Main + } + fn activation_height(&self, nu: NetworkUpgrade) -> Option { match nu { NetworkUpgrade::Overwinter => Some(BlockHeight(347_500)), @@ -222,34 +313,6 @@ impl Parameters for MainNetwork { NetworkUpgrade::ZFuture => None, } } - - fn coin_type(&self) -> u32 { - constants::mainnet::COIN_TYPE - } - - fn address_network(&self) -> Option { - 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. @@ -262,6 +325,10 @@ memuse::impl_no_dynamic_usage!(TestNetwork); pub const TEST_NETWORK: TestNetwork = TestNetwork; impl Parameters for TestNetwork { + fn network_type(&self) -> NetworkType { + NetworkType::Main + } + fn activation_height(&self, nu: NetworkUpgrade) -> Option { match nu { NetworkUpgrade::Overwinter => Some(BlockHeight(207_500)), @@ -276,99 +343,38 @@ impl Parameters for TestNetwork { NetworkUpgrade::ZFuture => None, } } - - fn coin_type(&self) -> u32 { - constants::testnet::COIN_TYPE - } - - fn address_network(&self) -> Option { - 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. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] +/// The enumeration of known Zcash networks. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Network { + /// Zcash Mainnet. MainNetwork, + /// Zcash Testnet. TestNetwork, + /// Private integration / regression testing, used in `zcashd`. + #[cfg(feature = "local-consensus")] + Regtest(LocalNetwork), } memuse::impl_no_dynamic_usage!(Network); impl Parameters for Network { - fn activation_height(&self, nu: NetworkUpgrade) -> Option { - match self { - Network::MainNetwork => MAIN_NETWORK.activation_height(nu), - Network::TestNetwork => TEST_NETWORK.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 { - match self { - Network::MainNetwork => Some(zcash_address::Network::Main), - Network::TestNetwork => Some(zcash_address::Network::Test), - } - } - - fn hrp_sapling_extended_spending_key(&self) -> &str { + fn network_type(&self) -> NetworkType { match self { - Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_spending_key(), - Network::TestNetwork => TEST_NETWORK.hrp_sapling_extended_spending_key(), + Network::MainNetwork => NetworkType::Main, + Network::TestNetwork => NetworkType::Test, + #[cfg(feature = "local-consensus")] + Network::Regtest(_) => NetworkType::Regtest, } } - 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] { + fn activation_height(&self, nu: NetworkUpgrade) -> Option { match self { - Network::MainNetwork => MAIN_NETWORK.b58_script_address_prefix(), - Network::TestNetwork => TEST_NETWORK.b58_script_address_prefix(), + Network::MainNetwork => MAIN_NETWORK.activation_height(nu), + Network::TestNetwork => TEST_NETWORK.activation_height(nu), + #[cfg(feature = "local-consensus")] + Network::Regtest(network_params) => network_params.activation_height(nu), } } } diff --git a/components/zcash_protocol/src/constants/mainnet.rs b/components/zcash_protocol/src/constants/mainnet.rs index bd31a895eb..467f22df5a 100644 --- a/components/zcash_protocol/src/constants/mainnet.rs +++ b/components/zcash_protocol/src/constants/mainnet.rs @@ -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 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`]. /// /// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html diff --git a/components/zcash_protocol/src/constants/testnet.rs b/components/zcash_protocol/src/constants/testnet.rs index dba86bb9c7..7bf3309691 100644 --- a/components/zcash_protocol/src/constants/testnet.rs +++ b/components/zcash_protocol/src/constants/testnet.rs @@ -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 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`]. /// /// [`PublicKeyHash`]: https://docs.rs/zcash_primitives/latest/zcash_primitives/legacy/enum.TransparentAddress.html diff --git a/components/zcash_protocol/src/local_consensus.rs b/components/zcash_protocol/src/local_consensus.rs index 8c4b647cc1..cf4dffe606 100644 --- a/components/zcash_protocol/src/local_consensus.rs +++ b/components/zcash_protocol/src/local_consensus.rs @@ -1,7 +1,4 @@ -use crate::{ - consensus::{BlockHeight, NetworkUpgrade, Parameters}, - constants, -}; +use crate::consensus::{BlockHeight, NetworkType, NetworkUpgrade, Parameters}; /// a `LocalNetwork` setup should define the activation heights /// 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 overwinter: Option, pub sapling: Option, @@ -44,18 +41,18 @@ pub struct LocalNetwork { pub heartwood: Option, pub canopy: Option, pub nu5: Option, + #[cfg(feature = "unstable-nu6")] pub nu6: Option, #[cfg(feature = "zfuture")] pub z_future: Option, } -/// Parameters default 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 +/// Parameters implementation for `LocalNetwork` impl Parameters for LocalNetwork { + fn network_type(&self) -> NetworkType { + NetworkType::Regtest + } + fn activation_height(&self, nu: NetworkUpgrade) -> Option { match nu { NetworkUpgrade::Overwinter => self.overwinter, @@ -70,44 +67,12 @@ impl Parameters for LocalNetwork { NetworkUpgrade::ZFuture => self.z_future, } } - - fn coin_type(&self) -> u32 { - constants::regtest::COIN_TYPE - } - - fn address_network(&self) -> Option { - 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)] mod tests { use crate::{ - consensus::{BlockHeight, NetworkUpgrade, Parameters}, + consensus::{BlockHeight, NetworkConstants, NetworkUpgrade, Parameters}, constants, local_consensus::LocalNetwork, }; @@ -148,24 +113,6 @@ mod tests { assert!(regtest.is_nu_active(NetworkUpgrade::Nu6, expected_nu6)); #[cfg(feature = "zfuture")] 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] @@ -251,25 +198,30 @@ mod tests { z_future: Some(expected_z_future), }; - assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE); 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 ); 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 ); assert_eq!( - regtest.hrp_sapling_payment_address(), + regtest.network_type().hrp_sapling_payment_address(), constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS ); assert_eq!( - regtest.b58_pubkey_address_prefix(), + regtest.network_type().b58_pubkey_address_prefix(), constants::regtest::B58_PUBKEY_ADDRESS_PREFIX ); assert_eq!( - regtest.b58_script_address_prefix(), + regtest.network_type().b58_script_address_prefix(), constants::regtest::B58_SCRIPT_ADDRESS_PREFIX ); } diff --git a/zcash_client_backend/src/lib.rs b/zcash_client_backend/src/lib.rs index 0b5f44c7ee..7c1e2b9123 100644 --- a/zcash_client_backend/src/lib.rs +++ b/zcash_client_backend/src/lib.rs @@ -77,7 +77,7 @@ pub mod zip321; pub mod serialization; pub use decrypt::{decrypt_transaction, DecryptedOutput, TransferType}; -pub use zcash_protocol::{ShieldedProtocol, PoolType}; +pub use zcash_protocol::{PoolType, ShieldedProtocol}; #[cfg(test)] #[macro_use] diff --git a/zcash_client_backend/src/zip321.rs b/zcash_client_backend/src/zip321.rs index f3d859a2cd..cb0943eaa5 100644 --- a/zcash_client_backend/src/zip321.rs +++ b/zcash_client_backend/src/zip321.rs @@ -16,10 +16,10 @@ use nom::{ sequence::preceded, }; use zcash_primitives::{ - consensus, memo::{self, MemoBytes}, transaction::components::amount::NonNegativeAmount, }; +use zcash_protocol::consensus; #[cfg(any(test, feature = "test-dependencies"))] use std::cmp::Ordering; @@ -804,11 +804,8 @@ pub mod testing { mod tests { use std::str::FromStr; use zcash_keys::{address::testing::arb_addr, keys::UnifiedAddressRequest}; - use zcash_primitives::{ - consensus::{Parameters, TEST_NETWORK}, - memo::Memo, - transaction::components::amount::NonNegativeAmount, - }; + use zcash_primitives::{memo::Memo, transaction::components::amount::NonNegativeAmount}; + use zcash_protocol::consensus::{NetworkConstants, NetworkType, TEST_NETWORK}; #[cfg(feature = "local-consensus")] use zcash_primitives::{local_consensus::LocalNetwork, BlockHeight}; @@ -868,7 +865,7 @@ mod tests { let expected = TransactionRequest { payments: vec![ 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), memo: None, label: None, @@ -889,7 +886,7 @@ mod tests { let expected = TransactionRequest { payments: vec![ 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, memo: None, label: None, @@ -907,7 +904,7 @@ mod tests { let req = TransactionRequest { payments: vec![ 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, memo: None, label: None, diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index ea488cf291..baede4d0f0 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -1187,6 +1187,8 @@ mod tests { #[cfg(feature = "unstable")] #[test] pub(crate) fn fsblockdb_api() { + use zcash_primitives::consensus::NetworkConstants; + let mut st = TestBuilder::new().with_fs_block_cache().build(); // The BlockMeta DB starts off empty. @@ -1195,7 +1197,11 @@ mod tests { // Generate some fake CompactBlocks. let seed = [0u8; 32]; 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 (h1, meta1, _) = st.generate_next_block( &dfvk, diff --git a/zcash_client_sqlite/src/wallet/init.rs b/zcash_client_sqlite/src/wallet/init.rs index 14bf46d30f..9493149593 100644 --- a/zcash_client_sqlite/src/wallet/init.rs +++ b/zcash_client_sqlite/src/wallet/init.rs @@ -176,7 +176,9 @@ mod tests { use ::sapling::zip32::ExtendedFullViewingKey; use zcash_primitives::{ - consensus::{self, BlockHeight, BranchId, Network, NetworkUpgrade, Parameters}, + consensus::{ + self, BlockHeight, BranchId, Network, NetworkConstants, NetworkUpgrade, Parameters, + }, transaction::{TransactionData, TxVersion}, zip32::AccountId, }; @@ -698,11 +700,13 @@ mod tests { )?; let address = encode_payment_address( - wdb.params.hrp_sapling_payment_address(), + wdb.params.network_type().hrp_sapling_payment_address(), &extfvk.default_address().1, ); 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, ); wdb.conn.execute( @@ -723,7 +727,8 @@ mod tests { let seed = [0xab; 32]; 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(); init_0_3_0(&mut db_data, &extfvk, account).unwrap(); @@ -835,11 +840,13 @@ mod tests { )?; let address = encode_payment_address( - wdb.params.hrp_sapling_payment_address(), + wdb.params.network_type().hrp_sapling_payment_address(), &extfvk.default_address().1, ); 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, ); wdb.conn.execute( @@ -894,7 +901,8 @@ mod tests { let seed = [0xab; 32]; 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(); init_autoshielding(&mut db_data, &extfvk, account).unwrap(); diff --git a/zcash_extensions/src/transparent/demo.rs b/zcash_extensions/src/transparent/demo.rs index 96f2d9f6fa..6f26629932 100644 --- a/zcash_extensions/src/transparent/demo.rs +++ b/zcash_extensions/src/transparent/demo.rs @@ -484,8 +484,7 @@ mod tests { use sapling::{zip32::ExtendedSpendingKey, Node, Rseed}; use zcash_primitives::{ - consensus::{BlockHeight, BranchId, NetworkUpgrade, Parameters}, - constants, + consensus::{BlockHeight, BranchId, NetworkType, NetworkUpgrade, Parameters}, extensions::transparent::{self as tze, Extension, FromPayload, ToPayload}, legacy::TransparentAddress, transaction::{ @@ -520,34 +519,11 @@ mod tests { } } - fn address_network(&self) -> Option { - None - } - - 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 network_type(&self) -> NetworkType { + NetworkType::Test } } + fn demo_hashes(preimage_1: &[u8; 32], preimage_2: &[u8; 32]) -> ([u8; 32], [u8; 32]) { let hash_2 = { let mut hash = [0; 32]; diff --git a/zcash_keys/Cargo.toml b/zcash_keys/Cargo.toml index 8a121d2b32..c5701b360d 100644 --- a/zcash_keys/Cargo.toml +++ b/zcash_keys/Cargo.toml @@ -22,6 +22,7 @@ rustdoc-args = ["--cfg", "docsrs"] zcash_address.workspace = true zcash_encoding.workspace = true zcash_primitives.workspace = true +zcash_protocol.workspace = true zip32.workspace = true # Dependencies exposed in a public API: diff --git a/zcash_keys/src/address.rs b/zcash_keys/src/address.rs index 54c0358e62..ccd32f91e7 100644 --- a/zcash_keys/src/address.rs +++ b/zcash_keys/src/address.rs @@ -5,13 +5,14 @@ use std::convert::TryFrom; use sapling::PaymentAddress; use zcash_address::{ unified::{self, Container, Encoding}, - ConversionError, Network, ToAddress, TryFromRawAddress, ZcashAddress, + ConversionError, ToAddress, TryFromRawAddress, ZcashAddress, }; use zcash_primitives::{ consensus, legacy::TransparentAddress, zip32::{AccountId, DiversifierIndex}, }; +use zcash_protocol::consensus::NetworkType; pub struct AddressMetadata { account: AccountId, @@ -155,7 +156,7 @@ impl UnifiedAddress { &self.unknown } - fn to_address(&self, net: Network) -> ZcashAddress { + fn to_address(&self, network: NetworkType) -> ZcashAddress { #[cfg(feature = "orchard")] let orchard_receiver = self .orchard @@ -186,13 +187,12 @@ impl UnifiedAddress { .collect(), ) .expect("UnifiedAddress should only be constructed safely"); - ZcashAddress::from_unified(net, ua) + ZcashAddress::from_unified(network, ua) } /// Returns the string encoding of this `UnifiedAddress` for the given network. pub fn encode(&self, params: &P) -> String { - self.to_address(params.address_network().expect("Unrecognized network")) - .to_string() + self.to_address(params.network_type()).to_string() } } @@ -252,12 +252,11 @@ impl TryFromRawAddress for Address { impl Address { pub fn decode(params: &P, s: &str) -> Option { let addr = ZcashAddress::try_from_encoded(s).ok()?; - addr.convert_if_network(params.address_network().expect("Unrecognized network")) - .ok() + addr.convert_if_network(params.network_type()).ok() } pub fn encode(&self, params: &P) -> String { - let net = params.address_network().expect("Unrecognized network"); + let net = params.network_type(); match self { Address::Sapling(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()), diff --git a/zcash_keys/src/encoding.rs b/zcash_keys/src/encoding.rs index 0dad6bd623..8311d94f4b 100644 --- a/zcash_keys/src/encoding.rs +++ b/zcash_keys/src/encoding.rs @@ -8,6 +8,7 @@ use bech32::{self, Error, FromBase32, ToBase32, Variant}; use bs58::{self, decode::Error as Bs58Error}; use std::fmt; use std::io::{self, Write}; +use zcash_primitives::consensus::NetworkConstants; use sapling::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}; use zcash_address::unified::{self, Encoding}; @@ -121,16 +122,16 @@ impl AddressCodec

for TransparentAddress { fn encode(&self, params: &P) -> String { encode_transparent_address( - ¶ms.b58_pubkey_address_prefix(), - ¶ms.b58_script_address_prefix(), + ¶ms.network_type().b58_pubkey_address_prefix(), + ¶ms.network_type().b58_script_address_prefix(), self, ) } fn decode(params: &P, address: &str) -> Result { decode_transparent_address( - ¶ms.b58_pubkey_address_prefix(), - ¶ms.b58_script_address_prefix(), + ¶ms.network_type().b58_pubkey_address_prefix(), + ¶ms.network_type().b58_script_address_prefix(), address, ) .map_err(TransparentCodecError::Base58) @@ -144,11 +145,11 @@ impl AddressCodec

for sapling::PaymentAddress { type Error = Bech32DecodeError; 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 { - decode_payment_address(params.hrp_sapling_payment_address(), address) + decode_payment_address(params.network_type().hrp_sapling_payment_address(), address) } } @@ -163,7 +164,7 @@ impl AddressCodec

for UnifiedAddress { unified::Address::decode(address) .map_err(|e| format!("{}", e)) .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()) } else { Err(format!( @@ -282,7 +283,7 @@ pub fn encode_payment_address_p( params: &P, addr: &sapling::PaymentAddress, ) -> 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. @@ -309,7 +310,7 @@ pub fn encode_payment_address_p( /// /// assert_eq!( /// decode_payment_address( -/// TEST_NETWORK.hrp_sapling_payment_address(), +/// TEST_NETWORK.network_type().hrp_sapling_payment_address(), /// "ztestsapling1qqqqqqqqqqqqqqqqqqcguyvaw2vjk4sdyeg0lc970u659lvhqq7t0np6hlup5lusxle75ss7jnk", /// ), /// Ok(pa), @@ -346,8 +347,8 @@ pub fn decode_payment_address( /// /// assert_eq!( /// encode_transparent_address( -/// &TEST_NETWORK.b58_pubkey_address_prefix(), -/// &TEST_NETWORK.b58_script_address_prefix(), +/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(), +/// &TEST_NETWORK.network_type().b58_script_address_prefix(), /// &TransparentAddress::PublicKeyHash([0; 20]), /// ), /// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma", @@ -355,8 +356,8 @@ pub fn decode_payment_address( /// /// assert_eq!( /// encode_transparent_address( -/// &TEST_NETWORK.b58_pubkey_address_prefix(), -/// &TEST_NETWORK.b58_script_address_prefix(), +/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(), +/// &TEST_NETWORK.network_type().b58_script_address_prefix(), /// &TransparentAddress::ScriptHash([0; 20]), /// ), /// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2", @@ -393,8 +394,8 @@ pub fn encode_transparent_address_p( addr: &TransparentAddress, ) -> String { encode_transparent_address( - ¶ms.b58_pubkey_address_prefix(), - ¶ms.b58_script_address_prefix(), + ¶ms.network_type().b58_pubkey_address_prefix(), + ¶ms.network_type().b58_script_address_prefix(), addr, ) } @@ -414,8 +415,8 @@ pub fn encode_transparent_address_p( /// /// assert_eq!( /// decode_transparent_address( -/// &TEST_NETWORK.b58_pubkey_address_prefix(), -/// &TEST_NETWORK.b58_script_address_prefix(), +/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(), +/// &TEST_NETWORK.network_type().b58_script_address_prefix(), /// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma", /// ), /// Ok(Some(TransparentAddress::PublicKeyHash([0; 20]))), @@ -423,8 +424,8 @@ pub fn encode_transparent_address_p( /// /// assert_eq!( /// decode_transparent_address( -/// &TEST_NETWORK.b58_pubkey_address_prefix(), -/// &TEST_NETWORK.b58_script_address_prefix(), +/// &TEST_NETWORK.network_type().b58_pubkey_address_prefix(), +/// &TEST_NETWORK.network_type().b58_script_address_prefix(), /// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2", /// ), /// Ok(Some(TransparentAddress::ScriptHash([0; 20]))), diff --git a/zcash_keys/src/keys.rs b/zcash_keys/src/keys.rs index 1693a780d2..4f50695ebb 100644 --- a/zcash_keys/src/keys.rs +++ b/zcash_keys/src/keys.rs @@ -1,7 +1,7 @@ //! Helper functions for managing light client key material. use zcash_address::unified::{self, Container, Encoding, Typecode}; use zcash_primitives::{ - consensus, + consensus::{self, NetworkConstants}, zip32::{AccountId, DiversifierIndex}, }; @@ -181,9 +181,12 @@ impl UnifiedSpendingKey { } #[cfg(feature = "orchard")] - let orchard = - orchard::keys::SpendingKey::from_zip32_seed(seed, params.coin_type(), account) - .map_err(DerivationError::Orchard)?; + let orchard = orchard::keys::SpendingKey::from_zip32_seed( + seed, + params.network_type().coin_type(), + account, + ) + .map_err(DerivationError::Orchard)?; #[cfg(feature = "transparent-inputs")] let transparent = legacy::AccountPrivKey::from_seed(params, seed, account) @@ -192,7 +195,7 @@ impl UnifiedSpendingKey { Ok(UnifiedSpendingKey { #[cfg(feature = "transparent-inputs")] transparent, - sapling: sapling::spending_key(seed, params.coin_type(), account), + sapling: sapling::spending_key(seed, params.network_type().coin_type(), account), #[cfg(feature = "orchard")] orchard, }) @@ -497,7 +500,7 @@ impl UnifiedFullViewingKey { /// [ZIP 316]: https://zips.z.cash/zip-0316 pub fn decode(params: &P, encoding: &str) -> Result { 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 { return Err(format!( "UFVK is for network {:?} but we expected {:?}", @@ -598,7 +601,7 @@ impl UnifiedFullViewingKey { let ufvk = unified::Ufvk::try_from_items(items.collect()) .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 diff --git a/zcash_primitives/src/legacy/keys.rs b/zcash_primitives/src/legacy/keys.rs index 7bbc2f1064..cf6a9f98fd 100644 --- a/zcash_primitives/src/legacy/keys.rs +++ b/zcash_primitives/src/legacy/keys.rs @@ -6,6 +6,7 @@ use hdwallet::{ }; use secp256k1::PublicKey; use sha2::{Digest, Sha256}; +use zcash_protocol::consensus::NetworkConstants; use zcash_spec::PrfExpand; use crate::{consensus, zip32::AccountId}; @@ -33,7 +34,9 @@ impl AccountPrivKey { ) -> Result { ExtendedPrivKey::with_seed(seed)? .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())?) .map(AccountPrivKey) }