add(chain): Impl `zcash_protocol::consensus::Parameters` for `Network` (#8425)

* Use full paths for types from `zcash_primitives`

Upcoming commits will use `zcash_protocol::consensus::Parameters`, which
would make names such as `zp_consensus::Parameters` ambiguous since such
a name could stand for both `zcash_primitives...` and
`zcash_protocol...`.

* Impl and use conversion between network kinds

These conversions will make implementing
`zcash_protocol::consensus::Parameters` for `Network` easier.

* Impl conversions between network upgrades

* Impl `zcash_protocol::consensus::Parameters`

* Move `mod address` from under the gbt feature

* Remove a redundant `impl From`

* Impl `From` for a reference type correctly

The previous implementation called `into` on a reference without
dereferencing it. I thought the compiler would implicitly dereference,
but it didn't, which lead to infinite recursion since the fn ended up
calling itself.
This commit is contained in:
Marek 2024-05-02 00:22:37 +00:00 committed by GitHub
parent f14cf315d0
commit d47acd06f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 81 additions and 42 deletions

View File

@ -5898,6 +5898,7 @@ dependencies = [
"zcash_history", "zcash_history",
"zcash_note_encryption", "zcash_note_encryption",
"zcash_primitives", "zcash_primitives",
"zcash_protocol",
"zebra-test", "zebra-test",
] ]

View File

@ -98,6 +98,8 @@ zcash_encoding = "0.2.0"
zcash_history = "0.4.0" zcash_history = "0.4.0"
zcash_note_encryption = "0.4.0" zcash_note_encryption = "0.4.0"
zcash_primitives = { version = "0.13.0", features = ["transparent-inputs"] } zcash_primitives = { version = "0.13.0", features = ["transparent-inputs"] }
zcash_protocol = { version = "0.1.1" }
zcash_address = { version = "0.3.2" }
# Time # Time
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] } chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
@ -131,8 +133,6 @@ serde_json = { version = "1.0.116", optional = true }
# Production feature async-error and testing feature proptest-impl # Production feature async-error and testing feature proptest-impl
tokio = { version = "1.37.0", optional = true } tokio = { version = "1.37.0", optional = true }
zcash_address = { version = "0.3.2" }
# Experimental feature shielded-scan # Experimental feature shielded-scan
zcash_client_backend = { version = "0.10.0-rc.1", optional = true } zcash_client_backend = { version = "0.10.0-rc.1", optional = true }

View File

@ -4,8 +4,6 @@ use std::{fmt, str::FromStr, sync::Arc};
use thiserror::Error; use thiserror::Error;
use zcash_primitives::{consensus as zp_consensus, constants as zp_constants};
use crate::{ use crate::{
block::{self, Height, HeightDiff}, block::{self, Height, HeightDiff},
parameters::NetworkUpgrade, parameters::NetworkUpgrade,
@ -96,8 +94,10 @@ impl NetworkKind {
/// pay-to-public-key-hash payment addresses for the network. /// pay-to-public-key-hash payment addresses for the network.
pub fn b58_pubkey_address_prefix(self) -> [u8; 2] { pub fn b58_pubkey_address_prefix(self) -> [u8; 2] {
match self { match self {
Self::Mainnet => zp_constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX, Self::Mainnet => zcash_primitives::constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => zp_constants::testnet::B58_PUBKEY_ADDRESS_PREFIX, Self::Testnet | Self::Regtest => {
zcash_primitives::constants::testnet::B58_PUBKEY_ADDRESS_PREFIX
}
} }
} }
@ -105,8 +105,10 @@ impl NetworkKind {
/// payment addresses for the network. /// payment addresses for the network.
pub fn b58_script_address_prefix(self) -> [u8; 2] { pub fn b58_script_address_prefix(self) -> [u8; 2] {
match self { match self {
Self::Mainnet => zp_constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX, Self::Mainnet => zcash_primitives::constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX,
Self::Testnet | Self::Regtest => zp_constants::testnet::B58_SCRIPT_ADDRESS_PREFIX, Self::Testnet | Self::Regtest => {
zcash_primitives::constants::testnet::B58_SCRIPT_ADDRESS_PREFIX
}
} }
} }
@ -296,32 +298,23 @@ impl FromStr for Network {
#[error("Invalid network: {0}")] #[error("Invalid network: {0}")]
pub struct InvalidNetworkError(String); pub struct InvalidNetworkError(String);
impl zp_consensus::Parameters for Network { impl zcash_primitives::consensus::Parameters for Network {
fn activation_height( fn activation_height(
&self, &self,
nu: zcash_primitives::consensus::NetworkUpgrade, nu: zcash_primitives::consensus::NetworkUpgrade,
) -> Option<zcash_primitives::consensus::BlockHeight> { ) -> Option<zcash_primitives::consensus::BlockHeight> {
let target_nu = match nu {
zp_consensus::NetworkUpgrade::Overwinter => NetworkUpgrade::Overwinter,
zp_consensus::NetworkUpgrade::Sapling => NetworkUpgrade::Sapling,
zp_consensus::NetworkUpgrade::Blossom => NetworkUpgrade::Blossom,
zp_consensus::NetworkUpgrade::Heartwood => NetworkUpgrade::Heartwood,
zp_consensus::NetworkUpgrade::Canopy => NetworkUpgrade::Canopy,
zp_consensus::NetworkUpgrade::Nu5 => NetworkUpgrade::Nu5,
};
// Heights are hard-coded below Height::MAX or checked when the config is parsed. // Heights are hard-coded below Height::MAX or checked when the config is parsed.
target_nu NetworkUpgrade::from(nu)
.activation_height(self) .activation_height(self)
.map(|Height(h)| zp_consensus::BlockHeight::from_u32(h)) .map(|Height(h)| zcash_primitives::consensus::BlockHeight::from_u32(h))
} }
fn coin_type(&self) -> u32 { fn coin_type(&self) -> u32 {
match self { match self {
Network::Mainnet => zp_constants::mainnet::COIN_TYPE, Network::Mainnet => zcash_primitives::constants::mainnet::COIN_TYPE,
// The regtest cointype reuses the testnet cointype, // The regtest cointype reuses the testnet cointype,
// See <https://github.com/satoshilabs/slips/blob/master/slip-0044.md> // See <https://github.com/satoshilabs/slips/blob/master/slip-0044.md>
Network::Testnet(_) => zp_constants::testnet::COIN_TYPE, Network::Testnet(_) => zcash_primitives::constants::testnet::COIN_TYPE,
} }
} }
@ -335,21 +328,25 @@ impl zp_consensus::Parameters for Network {
fn hrp_sapling_extended_spending_key(&self) -> &str { fn hrp_sapling_extended_spending_key(&self) -> &str {
match self { match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY, Network::Mainnet => {
zcash_primitives::constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY
}
Network::Testnet(params) => params.hrp_sapling_extended_spending_key(), Network::Testnet(params) => params.hrp_sapling_extended_spending_key(),
} }
} }
fn hrp_sapling_extended_full_viewing_key(&self) -> &str { fn hrp_sapling_extended_full_viewing_key(&self) -> &str {
match self { match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, Network::Mainnet => {
zcash_primitives::constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
}
Network::Testnet(params) => params.hrp_sapling_extended_full_viewing_key(), Network::Testnet(params) => params.hrp_sapling_extended_full_viewing_key(),
} }
} }
fn hrp_sapling_payment_address(&self) -> &str { fn hrp_sapling_payment_address(&self) -> &str {
match self { match self {
Network::Mainnet => zp_constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS, Network::Mainnet => zcash_primitives::constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
Network::Testnet(params) => params.hrp_sapling_payment_address(), Network::Testnet(params) => params.hrp_sapling_payment_address(),
} }
} }
@ -362,3 +359,18 @@ impl zp_consensus::Parameters for Network {
self.kind().b58_script_address_prefix() self.kind().b58_script_address_prefix()
} }
} }
impl zcash_protocol::consensus::Parameters for Network {
fn network_type(&self) -> zcash_address::Network {
self.kind().into()
}
fn activation_height(
&self,
nu: zcash_protocol::consensus::NetworkUpgrade,
) -> Option<zcash_protocol::consensus::BlockHeight> {
NetworkUpgrade::from(nu)
.activation_height(self)
.map(|Height(h)| zcash_protocol::consensus::BlockHeight::from_u32(h))
}
}

View File

@ -493,6 +493,32 @@ impl NetworkUpgrade {
} }
} }
impl From<zcash_protocol::consensus::NetworkUpgrade> for NetworkUpgrade {
fn from(nu: zcash_protocol::consensus::NetworkUpgrade) -> Self {
match nu {
zcash_protocol::consensus::NetworkUpgrade::Overwinter => Self::Overwinter,
zcash_protocol::consensus::NetworkUpgrade::Sapling => Self::Sapling,
zcash_protocol::consensus::NetworkUpgrade::Blossom => Self::Blossom,
zcash_protocol::consensus::NetworkUpgrade::Heartwood => Self::Heartwood,
zcash_protocol::consensus::NetworkUpgrade::Canopy => Self::Canopy,
zcash_protocol::consensus::NetworkUpgrade::Nu5 => Self::Nu5,
}
}
}
impl From<zcash_primitives::consensus::NetworkUpgrade> for NetworkUpgrade {
fn from(value: zcash_primitives::consensus::NetworkUpgrade) -> Self {
match value {
zcash_primitives::consensus::NetworkUpgrade::Overwinter => NetworkUpgrade::Overwinter,
zcash_primitives::consensus::NetworkUpgrade::Sapling => NetworkUpgrade::Sapling,
zcash_primitives::consensus::NetworkUpgrade::Blossom => NetworkUpgrade::Blossom,
zcash_primitives::consensus::NetworkUpgrade::Heartwood => NetworkUpgrade::Heartwood,
zcash_primitives::consensus::NetworkUpgrade::Canopy => NetworkUpgrade::Canopy,
zcash_primitives::consensus::NetworkUpgrade::Nu5 => NetworkUpgrade::Nu5,
}
}
}
impl ConsensusBranchId { impl ConsensusBranchId {
/// The value used by `zcashd` RPCs for missing consensus branch IDs. /// The value used by `zcashd` RPCs for missing consensus branch IDs.
/// ///

View File

@ -6,10 +6,8 @@
mod proofs; mod proofs;
#[cfg(feature = "getblocktemplate-rpcs")]
mod address; mod address;
#[cfg(feature = "getblocktemplate-rpcs")]
pub use address::Address; pub use address::Address;
#[cfg(feature = "shielded-scan")] #[cfg(feature = "shielded-scan")]

View File

@ -49,7 +49,7 @@ impl zcash_address::TryFromAddress for Address {
data: [u8; 20], data: [u8; 20],
) -> Result<Self, zcash_address::ConversionError<Self::Error>> { ) -> Result<Self, zcash_address::ConversionError<Self::Error>> {
Ok(Self::Transparent(transparent::Address::from_pub_key_hash( Ok(Self::Transparent(transparent::Address::from_pub_key_hash(
NetworkKind::from_zcash_address(network), network.into(),
data, data,
))) )))
} }
@ -59,7 +59,7 @@ impl zcash_address::TryFromAddress for Address {
data: [u8; 20], data: [u8; 20],
) -> Result<Self, zcash_address::ConversionError<Self::Error>> { ) -> Result<Self, zcash_address::ConversionError<Self::Error>> {
Ok(Self::Transparent(transparent::Address::from_script_hash( Ok(Self::Transparent(transparent::Address::from_script_hash(
NetworkKind::from_zcash_address(network), network.into(),
data, data,
))) )))
} }
@ -68,7 +68,7 @@ impl zcash_address::TryFromAddress for Address {
network: zcash_address::Network, network: zcash_address::Network,
data: [u8; 43], data: [u8; 43],
) -> Result<Self, zcash_address::ConversionError<Self::Error>> { ) -> Result<Self, zcash_address::ConversionError<Self::Error>> {
let network = NetworkKind::from_zcash_address(network); let network = network.into();
sapling::PaymentAddress::from_bytes(&data) sapling::PaymentAddress::from_bytes(&data)
.map(|address| Self::Sapling { address, network }) .map(|address| Self::Sapling { address, network })
.ok_or_else(|| BoxError::from("not a valid sapling address").into()) .ok_or_else(|| BoxError::from("not a valid sapling address").into())
@ -78,7 +78,7 @@ impl zcash_address::TryFromAddress for Address {
network: zcash_address::Network, network: zcash_address::Network,
unified_address: zcash_address::unified::Address, unified_address: zcash_address::unified::Address,
) -> Result<Self, zcash_address::ConversionError<Self::Error>> { ) -> Result<Self, zcash_address::ConversionError<Self::Error>> {
let network = NetworkKind::from_zcash_address(network); let network = network.into();
let mut orchard = None; let mut orchard = None;
let mut sapling = None; let mut sapling = None;
let mut transparent = None; let mut transparent = None;
@ -163,7 +163,7 @@ impl Address {
Self::Transparent(address) => Some(address.to_string()), Self::Transparent(address) => Some(address.to_string()),
Self::Sapling { address, network } => { Self::Sapling { address, network } => {
let data = address.to_bytes(); let data = address.to_bytes();
let address = ZcashAddress::from_sapling(network.to_zcash_address(), data); let address = ZcashAddress::from_sapling(network.into(), data);
Some(address.encode()) Some(address.encode())
} }
Self::Unified { .. } => None, Self::Unified { .. } => None,
@ -171,26 +171,28 @@ impl Address {
} }
} }
impl NetworkKind { impl From<zcash_address::Network> for NetworkKind {
/// Converts a [`zcash_address::Network`] to a [`NetworkKind`]. fn from(network: zcash_address::Network) -> Self {
///
/// This method is meant to be used for decoding Zcash addresses in zebra-rpc methods.
fn from_zcash_address(network: zcash_address::Network) -> Self {
match network { match network {
zcash_address::Network::Main => NetworkKind::Mainnet, zcash_address::Network::Main => NetworkKind::Mainnet,
zcash_address::Network::Test => NetworkKind::Testnet, zcash_address::Network::Test => NetworkKind::Testnet,
zcash_address::Network::Regtest => NetworkKind::Regtest, zcash_address::Network::Regtest => NetworkKind::Regtest,
} }
} }
}
/// Converts a [`zcash_address::Network`] to a [`NetworkKind`]. impl From<NetworkKind> for zcash_address::Network {
/// fn from(network: NetworkKind) -> Self {
/// This method is meant to be used for encoding Zcash addresses in zebra-rpc methods. match network {
fn to_zcash_address(self) -> zcash_address::Network {
match self {
NetworkKind::Mainnet => zcash_address::Network::Main, NetworkKind::Mainnet => zcash_address::Network::Main,
NetworkKind::Testnet => zcash_address::Network::Test, NetworkKind::Testnet => zcash_address::Network::Test,
NetworkKind::Regtest => zcash_address::Network::Regtest, NetworkKind::Regtest => zcash_address::Network::Regtest,
} }
} }
} }
impl From<&NetworkKind> for zcash_address::Network {
fn from(network: &NetworkKind) -> Self {
(*network).into()
}
}