Return the network type for encoding addresses as part of the network parameters.

This commit is contained in:
Kris Nuttycombe 2022-06-27 14:23:33 -06:00
parent 86b1db169c
commit 94c8d8e7ef
6 changed files with 35 additions and 17 deletions

View File

@ -6,17 +6,7 @@ use zcash_address::{
unified::{self, Container, Encoding}, unified::{self, Container, Encoding},
ConversionError, Network, ToAddress, TryFromRawAddress, ZcashAddress, ConversionError, Network, ToAddress, TryFromRawAddress, ZcashAddress,
}; };
use zcash_primitives::{consensus, constants, legacy::TransparentAddress, sapling::PaymentAddress}; use zcash_primitives::{consensus, legacy::TransparentAddress, sapling::PaymentAddress};
pub(crate) fn params_to_network<P: consensus::Parameters>(params: &P) -> Network {
// Use the Sapling HRP as an indicator of network.
match params.hrp_sapling_payment_address() {
constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS => Network::Main,
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS => Network::Test,
constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS => Network::Regtest,
_ => panic!("Unsupported network kind"),
}
}
/// A Unified Address. /// A Unified Address.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -145,7 +135,8 @@ 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_to_network(params)).to_string() self.to_address(params.address_network().expect("Unrecognized network"))
.to_string()
} }
} }
@ -206,11 +197,12 @@ impl TryFromRawAddress for RecipientAddress {
impl RecipientAddress { impl RecipientAddress {
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_to_network(params)).ok() addr.convert_if_network(params.address_network().expect("Unrecognized network"))
.ok()
} }
pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String { pub fn encode<P: consensus::Parameters>(&self, params: &P) -> String {
let net = params_to_network(params); let net = params.address_network().expect("Unrecognized network");
match self { match self {
RecipientAddress::Shielded(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()), RecipientAddress::Shielded(pa) => ZcashAddress::from_sapling(net, pa.to_bytes()),

View File

@ -6,7 +6,7 @@ use zcash_primitives::{
zip32::{AccountId, DiversifierIndex}, zip32::{AccountId, DiversifierIndex},
}; };
use crate::address::{params_to_network, UnifiedAddress}; use crate::address::UnifiedAddress;
#[cfg(feature = "transparent-inputs")] #[cfg(feature = "transparent-inputs")]
use std::convert::TryInto; use std::convert::TryInto;
@ -175,7 +175,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_to_network(params); let expected_net = params.address_network().expect("Unrecognized network");
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 {:?}",
@ -268,7 +268,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_to_network(params)) ufvk.encode(&params.address_network().expect("Unrecognized network"))
} }
/// Returns the transparent component of the unified key at the /// Returns the transparent component of the unified key at the

View File

@ -16,6 +16,7 @@ zcash_primitives = { version = "0.7", path = "../zcash_primitives", features = [
ff = "0.12" ff = "0.12"
jubjub = "0.9" jubjub = "0.9"
rand_core = "0.6" rand_core = "0.6"
zcash_address = { version = "0.1", path = "../components/zcash_address" }
zcash_proofs = { version = "0.7", path = "../zcash_proofs" } zcash_proofs = { version = "0.7", path = "../zcash_proofs" }
[features] [features]

View File

@ -520,6 +520,10 @@ mod tests {
} }
} }
fn address_network(&self) -> Option<zcash_address::Network> {
None
}
fn coin_type(&self) -> u32 { fn coin_type(&self) -> u32 {
constants::testnet::COIN_TYPE constants::testnet::COIN_TYPE
} }

View File

@ -45,6 +45,7 @@ ripemd = { version = "0.1", optional = true }
secp256k1 = { version = "0.21", optional = true } secp256k1 = { version = "0.21", optional = true }
sha2 = "0.9" sha2 = "0.9"
subtle = "2.2.3" subtle = "2.2.3"
zcash_address = { version = "0.1", path = "../components/zcash_address" }
zcash_encoding = { version = "0.1", path = "../components/zcash_encoding" } zcash_encoding = { version = "0.1", path = "../components/zcash_encoding" }
[dependencies.zcash_note_encryption] [dependencies.zcash_note_encryption]

View File

@ -4,6 +4,7 @@ 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;
@ -140,6 +141,10 @@ pub trait Parameters: Clone {
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md /// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
fn coin_type(&self) -> u32; fn coin_type(&self) -> u32;
/// Returns the standard network constant for address encoding. Returns
/// 'None' for nonstandard networks.
fn address_network(&self) -> Option<zcash_address::Network>;
/// Returns the human-readable prefix for Bech32-encoded Sapling extended spending keys /// 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 Parameters value applies.
/// ///
@ -205,6 +210,10 @@ impl Parameters for MainNetwork {
constants::mainnet::COIN_TYPE 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 { fn hrp_sapling_extended_spending_key(&self) -> &str {
constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
} }
@ -250,6 +259,10 @@ impl Parameters for TestNetwork {
constants::testnet::COIN_TYPE 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 { fn hrp_sapling_extended_spending_key(&self) -> &str {
constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
} }
@ -292,6 +305,13 @@ impl Parameters for Network {
} }
} }
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 { fn hrp_sapling_extended_spending_key(&self) -> &str {
match self { match self {
Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_spending_key(), Network::MainNetwork => MAIN_NETWORK.hrp_sapling_extended_spending_key(),