From d47acd06f6d5cfe68e1a92026b1d414e853f4b3b Mon Sep 17 00:00:00 2001 From: Marek Date: Thu, 2 May 2024 00:22:37 +0000 Subject: [PATCH] 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. --- Cargo.lock | 1 + zebra-chain/Cargo.toml | 4 +- zebra-chain/src/parameters/network.rs | 58 +++++++++++-------- zebra-chain/src/parameters/network_upgrade.rs | 26 +++++++++ zebra-chain/src/primitives.rs | 2 - zebra-chain/src/primitives/address.rs | 32 +++++----- 6 files changed, 81 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42b459b21..609cf4056 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5898,6 +5898,7 @@ dependencies = [ "zcash_history", "zcash_note_encryption", "zcash_primitives", + "zcash_protocol", "zebra-test", ] diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index 2e189afd8..14eee4c8a 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -98,6 +98,8 @@ zcash_encoding = "0.2.0" zcash_history = "0.4.0" zcash_note_encryption = "0.4.0" zcash_primitives = { version = "0.13.0", features = ["transparent-inputs"] } +zcash_protocol = { version = "0.1.1" } +zcash_address = { version = "0.3.2" } # Time 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 tokio = { version = "1.37.0", optional = true } -zcash_address = { version = "0.3.2" } - # Experimental feature shielded-scan zcash_client_backend = { version = "0.10.0-rc.1", optional = true } diff --git a/zebra-chain/src/parameters/network.rs b/zebra-chain/src/parameters/network.rs index 1f8865499..b29097a17 100644 --- a/zebra-chain/src/parameters/network.rs +++ b/zebra-chain/src/parameters/network.rs @@ -4,8 +4,6 @@ use std::{fmt, str::FromStr, sync::Arc}; use thiserror::Error; -use zcash_primitives::{consensus as zp_consensus, constants as zp_constants}; - use crate::{ block::{self, Height, HeightDiff}, parameters::NetworkUpgrade, @@ -96,8 +94,10 @@ impl NetworkKind { /// pay-to-public-key-hash payment addresses for the network. pub fn b58_pubkey_address_prefix(self) -> [u8; 2] { match self { - Self::Mainnet => zp_constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX, - Self::Testnet | Self::Regtest => zp_constants::testnet::B58_PUBKEY_ADDRESS_PREFIX, + Self::Mainnet => zcash_primitives::constants::mainnet::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. pub fn b58_script_address_prefix(self) -> [u8; 2] { match self { - Self::Mainnet => zp_constants::mainnet::B58_SCRIPT_ADDRESS_PREFIX, - Self::Testnet | Self::Regtest => zp_constants::testnet::B58_SCRIPT_ADDRESS_PREFIX, + Self::Mainnet => zcash_primitives::constants::mainnet::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}")] pub struct InvalidNetworkError(String); -impl zp_consensus::Parameters for Network { +impl zcash_primitives::consensus::Parameters for Network { fn activation_height( &self, nu: zcash_primitives::consensus::NetworkUpgrade, ) -> Option { - 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. - target_nu + NetworkUpgrade::from(nu) .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 { match self { - Network::Mainnet => zp_constants::mainnet::COIN_TYPE, + Network::Mainnet => zcash_primitives::constants::mainnet::COIN_TYPE, // The regtest cointype reuses the testnet cointype, // See - 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 { 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(), } } fn hrp_sapling_extended_full_viewing_key(&self) -> &str { 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(), } } fn hrp_sapling_payment_address(&self) -> &str { 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(), } } @@ -362,3 +359,18 @@ impl zp_consensus::Parameters for Network { 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 { + NetworkUpgrade::from(nu) + .activation_height(self) + .map(|Height(h)| zcash_protocol::consensus::BlockHeight::from_u32(h)) + } +} diff --git a/zebra-chain/src/parameters/network_upgrade.rs b/zebra-chain/src/parameters/network_upgrade.rs index de546e3b4..2fbd62010 100644 --- a/zebra-chain/src/parameters/network_upgrade.rs +++ b/zebra-chain/src/parameters/network_upgrade.rs @@ -493,6 +493,32 @@ impl NetworkUpgrade { } } +impl From 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 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 { /// The value used by `zcashd` RPCs for missing consensus branch IDs. /// diff --git a/zebra-chain/src/primitives.rs b/zebra-chain/src/primitives.rs index f5b14f8ce..fcaa78360 100644 --- a/zebra-chain/src/primitives.rs +++ b/zebra-chain/src/primitives.rs @@ -6,10 +6,8 @@ mod proofs; -#[cfg(feature = "getblocktemplate-rpcs")] mod address; -#[cfg(feature = "getblocktemplate-rpcs")] pub use address::Address; #[cfg(feature = "shielded-scan")] diff --git a/zebra-chain/src/primitives/address.rs b/zebra-chain/src/primitives/address.rs index 7e5f76138..86d524b8d 100644 --- a/zebra-chain/src/primitives/address.rs +++ b/zebra-chain/src/primitives/address.rs @@ -49,7 +49,7 @@ impl zcash_address::TryFromAddress for Address { data: [u8; 20], ) -> Result> { Ok(Self::Transparent(transparent::Address::from_pub_key_hash( - NetworkKind::from_zcash_address(network), + network.into(), data, ))) } @@ -59,7 +59,7 @@ impl zcash_address::TryFromAddress for Address { data: [u8; 20], ) -> Result> { Ok(Self::Transparent(transparent::Address::from_script_hash( - NetworkKind::from_zcash_address(network), + network.into(), data, ))) } @@ -68,7 +68,7 @@ impl zcash_address::TryFromAddress for Address { network: zcash_address::Network, data: [u8; 43], ) -> Result> { - let network = NetworkKind::from_zcash_address(network); + let network = network.into(); sapling::PaymentAddress::from_bytes(&data) .map(|address| Self::Sapling { address, network }) .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, unified_address: zcash_address::unified::Address, ) -> Result> { - let network = NetworkKind::from_zcash_address(network); + let network = network.into(); let mut orchard = None; let mut sapling = None; let mut transparent = None; @@ -163,7 +163,7 @@ impl Address { Self::Transparent(address) => Some(address.to_string()), Self::Sapling { address, network } => { 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()) } Self::Unified { .. } => None, @@ -171,26 +171,28 @@ impl Address { } } -impl NetworkKind { - /// Converts a [`zcash_address::Network`] to a [`NetworkKind`]. - /// - /// This method is meant to be used for decoding Zcash addresses in zebra-rpc methods. - fn from_zcash_address(network: zcash_address::Network) -> Self { +impl From for NetworkKind { + fn from(network: zcash_address::Network) -> Self { match network { zcash_address::Network::Main => NetworkKind::Mainnet, zcash_address::Network::Test => NetworkKind::Testnet, zcash_address::Network::Regtest => NetworkKind::Regtest, } } +} - /// Converts a [`zcash_address::Network`] to a [`NetworkKind`]. - /// - /// This method is meant to be used for encoding Zcash addresses in zebra-rpc methods. - fn to_zcash_address(self) -> zcash_address::Network { - match self { +impl From for zcash_address::Network { + fn from(network: NetworkKind) -> Self { + match network { NetworkKind::Mainnet => zcash_address::Network::Main, NetworkKind::Testnet => zcash_address::Network::Test, NetworkKind::Regtest => zcash_address::Network::Regtest, } } } + +impl From<&NetworkKind> for zcash_address::Network { + fn from(network: &NetworkKind) -> Self { + (*network).into() + } +}