Adds an empty NetworkParameters struct to Network::Testnet variant, updates production code.

This commit is contained in:
Arya 2024-03-20 03:26:07 -04:00
parent 9db4762751
commit 4b86bd6952
19 changed files with 241 additions and 69 deletions

View File

@ -12,6 +12,7 @@
//! Typically, consensus parameters are accessed via a function that takes a
//! `Network` and `block::Height`.
mod error;
mod genesis;
mod network;
mod network_upgrade;
@ -20,6 +21,7 @@ mod transaction;
#[cfg(any(test, feature = "proptest-impl"))]
pub mod arbitrary;
pub use error::*;
pub use genesis::*;
pub use network::Network;
pub use network_upgrade::*;

View File

@ -0,0 +1,15 @@
//! Error types for zebra-chain parameters
use std::fmt;
/// An error indicating that Zebra network is not supported in type conversions.
#[derive(Debug)]
pub struct UnsupportedNetwork;
impl fmt::Display for UnsupportedNetwork {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "unsupported Zcash network parameters")
}
}
impl std::error::Error for UnsupportedNetwork {}

View File

@ -1,9 +1,12 @@
//! Consensus parameters for each Zcash network.
use std::{fmt, str::FromStr};
use std::{fmt, str::FromStr, sync::Arc};
use serde::{Deserialize, Deserializer};
use thiserror::Error;
use zcash_primitives::consensus::{Network as ZcashPrimitivesNetwork, Parameters as _};
use crate::{
block::{self, Height, HeightDiff},
parameters::NetworkUpgrade::Canopy,
@ -51,30 +54,77 @@ mod tests;
/// after the grace period.
const ZIP_212_GRACE_PERIOD_DURATION: HeightDiff = 32_256;
/// An enum describing the possible network choices.
/// Network consensus parameters for test networks such as Regtest and the default Testnet.
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct NetworkParameters {}
impl NetworkParameters {
/// Returns true if the instance of [`NetworkParameters`] represents the default public Testnet.
pub fn is_default_testnet(&self) -> bool {
self == &Self::default()
}
}
/// An enum describing the possible network choices.
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Serialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub enum Network {
/// The production mainnet.
#[default]
Mainnet,
/// The oldest public test network.
Testnet,
Testnet(Arc<NetworkParameters>),
}
impl<'de> Deserialize<'de> for Network {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
enum DNetwork {
#[default]
Mainnet,
#[serde(alias = "Testnet")]
DefaultTestnet,
Regtest,
#[serde(untagged)]
ConfiguredTestnet(NetworkParameters),
}
let network = match DNetwork::deserialize(deserializer)? {
DNetwork::Mainnet => Network::Mainnet,
DNetwork::DefaultTestnet => Network::new_default_testnet(),
DNetwork::Regtest => unimplemented!("Regtest is not yet implemented"),
DNetwork::ConfiguredTestnet(params) => Network::Testnet(Arc::new(params)),
};
Ok(network)
}
}
use zcash_primitives::consensus::{Network as ZcashPrimitivesNetwork, Parameters as _};
impl Network {
/// Returns the human-readable prefix for Base58Check-encoded transparent
/// pay-to-public-key-hash payment addresses for the network.
pub fn b58_pubkey_address_prefix(&self) -> [u8; 2] {
<ZcashPrimitivesNetwork>::from(self).b58_pubkey_address_prefix()
<ZcashPrimitivesNetwork>::try_from(self)
// This prefix is the same for Testnet and Regtest in zcashd.
// TODO: Use the constants directly when implementing `Parameters` for `Network` (#8365)
.unwrap_or(ZcashPrimitivesNetwork::TestNetwork)
.b58_pubkey_address_prefix()
}
/// Returns the human-readable prefix for Base58Check-encoded transparent pay-to-script-hash
/// payment addresses for the network.
pub fn b58_script_address_prefix(&self) -> [u8; 2] {
<ZcashPrimitivesNetwork>::from(self).b58_script_address_prefix()
<ZcashPrimitivesNetwork>::try_from(self)
// This prefix is the same for Testnet and Regtest in zcashd.
// TODO: Use the constants directly when implementing `Parameters` for `Network` (#8365)
.unwrap_or(ZcashPrimitivesNetwork::TestNetwork)
.b58_script_address_prefix()
}
/// Returns true if the maximum block time rule is active for `network` and `height`.
///
@ -87,7 +137,8 @@ impl Network {
pub fn is_max_block_time_enforced(&self, height: block::Height) -> bool {
match self {
Network::Mainnet => true,
Network::Testnet => height >= super::TESTNET_MAX_TIME_START_HEIGHT,
// TODO: Move `TESTNET_MAX_TIME_START_HEIGHT` to a field on NetworkParameters (#8364)
Network::Testnet(_params) => height >= super::TESTNET_MAX_TIME_START_HEIGHT,
}
}
}
@ -96,7 +147,12 @@ impl From<&Network> for &'static str {
fn from(network: &Network) -> &'static str {
match network {
Network::Mainnet => "Mainnet",
Network::Testnet => "Testnet",
// TODO:
// - Add a `name` field to use here instead of checking `is_default_testnet()`
// - Find out what zcashd calls the regtest cache dir for the `Network::new_regtest()` method, or
// if it always uses an ephemeral db, and do the same for Regtest in Zebra (#8327).
Network::Testnet(params) if params.is_default_testnet() => "Testnet",
Network::Testnet(_params) => "UnknownTestnet",
}
}
}
@ -108,17 +164,32 @@ impl fmt::Display for Network {
}
impl Network {
/// Creates a new [`Network::Testnet`] with the default Testnet network parameters.
pub fn new_default_testnet() -> Self {
Self::Testnet(Arc::new(NetworkParameters::default()))
}
/// Returns true if the network is the default Testnet, or false otherwise.
pub fn is_default_testnet(&self) -> bool {
if let Self::Testnet(params) = self {
params.is_default_testnet()
} else {
false
}
}
/// Returns an iterator over [`Network`] variants.
pub fn iter() -> impl Iterator<Item = Self> {
// TODO: Use default values of `Testnet` variant when adding fields for #7845.
[Self::Mainnet, Self::Testnet].into_iter()
[Self::Mainnet, Self::new_default_testnet()].into_iter()
}
/// Get the default port associated to this network.
pub fn default_port(&self) -> u16 {
match self {
Network::Mainnet => 8233,
Network::Testnet => 18233,
// TODO: Add a `default_port` field to `NetworkParameters` to return here.
Network::Testnet(_params) => 18233,
}
}
@ -145,7 +216,7 @@ impl Network {
pub fn bip70_network_name(&self) -> String {
match self {
Network::Mainnet => "main".to_string(),
Network::Testnet => "test".to_string(),
Network::Testnet(_params) => "test".to_string(),
}
}
@ -173,7 +244,7 @@ impl FromStr for Network {
fn from_str(string: &str) -> Result<Self, Self::Err> {
match string.to_lowercase().as_str() {
"mainnet" => Ok(Network::Mainnet),
"testnet" => Ok(Network::Testnet),
"testnet" => Ok(Network::new_default_testnet()),
_ => Err(InvalidNetworkError(string.to_owned())),
}
}

View File

@ -271,7 +271,8 @@ impl Network {
};
match self {
Mainnet => mainnet_heights,
Testnet => testnet_heights,
// TODO: Add an `activation_heights` field to `NetworkParameters` to return here. (#7970)
Testnet(_params) => testnet_heights,
}
.iter()
.cloned()
@ -394,9 +395,14 @@ impl NetworkUpgrade {
height: block::Height,
) -> Option<Duration> {
match (network, height) {
(Network::Testnet, height) if height < TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT => None,
// TODO: Move `TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT` to a field on NetworkParameters (#8364)
(Network::Testnet(_params), height)
if height < TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT =>
{
None
}
(Network::Mainnet, _) => None,
(Network::Testnet, _) => {
(Network::Testnet(_params), _) => {
let network_upgrade = NetworkUpgrade::current(network, height);
Some(network_upgrade.target_spacing() * TESTNET_MINIMUM_DIFFICULTY_GAP_MULTIPLIER)
}

View File

@ -5,7 +5,10 @@
use zcash_address::unified::{self, Container};
use zcash_primitives::sapling;
use crate::{parameters::Network, transparent, BoxError};
use crate::{
parameters::{Network, UnsupportedNetwork},
transparent, BoxError,
};
/// Zcash address variants
pub enum Address {
@ -47,17 +50,25 @@ impl TryFrom<zcash_address::Network> for Network {
fn try_from(network: zcash_address::Network) -> Result<Self, Self::Error> {
match network {
zcash_address::Network::Main => Ok(Network::Mainnet),
zcash_address::Network::Test => Ok(Network::Testnet),
zcash_address::Network::Test => Ok(Network::new_default_testnet()),
zcash_address::Network::Regtest => Err("unsupported Zcash network parameters".into()),
}
}
}
impl From<&Network> for zcash_address::Network {
fn from(network: &Network) -> Self {
impl TryFrom<&Network> for zcash_address::Network {
type Error = UnsupportedNetwork;
fn try_from(network: &Network) -> Result<Self, Self::Error> {
match network {
Network::Mainnet => zcash_address::Network::Main,
Network::Testnet => zcash_address::Network::Test,
Network::Mainnet => Ok(zcash_address::Network::Main),
Network::Testnet(_params) if network.is_default_testnet() => {
Ok(zcash_address::Network::Test)
}
// TODO: If the network parameters match `Regtest` parameters, convert to
// `zcash_address::Network::Regtest instead of returning `UnsupportedAddress` error.
// (#7119, #7839)
Network::Testnet(_params) => Err(UnsupportedNetwork),
}
}
}
@ -185,7 +196,14 @@ impl Address {
Self::Transparent(address) => Some(address.to_string()),
Self::Sapling { address, network } => {
let data = address.to_bytes();
let address = ZcashAddress::from_sapling(network.into(), data);
let network = network
.try_into()
.map_err(|err| {
warn!(?err, "could not convert address network to zcash network")
})
.ok()?;
let address = ZcashAddress::from_sapling(network, data);
Some(address.encode())
}
Self::Unified { .. } => None,

View File

@ -26,7 +26,9 @@ pub fn decrypts_successfully(transaction: &Transaction, network: &Network, heigh
if let Some(bundle) = alt_tx.sapling_bundle() {
for output in bundle.shielded_outputs().iter() {
let recovery = zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&<zcash_primitives::consensus::Network>::from(network),
// TODO: Implement `Parameters` trait for `Network` and pass network here without conversion (#8365)
&<zcash_primitives::consensus::Network>::try_from(network)
.expect("network must match zcash_primitives network"),
alt_height,
&null_sapling_ovk,
output,

View File

@ -7,7 +7,7 @@ use zcash_primitives::transaction as zp_tx;
use crate::{
amount::{Amount, NonNegative},
parameters::{Network, NetworkUpgrade},
parameters::{Network, NetworkUpgrade, UnsupportedNetwork},
serialization::ZcashSerialize,
transaction::{AuthDigest, HashType, SigHash, Transaction},
transparent::{self, Script},
@ -337,11 +337,21 @@ pub(crate) fn transparent_output_address(
}
}
impl From<&Network> for zcash_primitives::consensus::Network {
fn from(network: &Network) -> Self {
impl TryFrom<&Network> for zcash_primitives::consensus::Network {
type Error = UnsupportedNetwork;
fn try_from(network: &Network) -> Result<Self, Self::Error> {
match network {
Network::Mainnet => zcash_primitives::consensus::Network::MainNetwork,
Network::Testnet => zcash_primitives::consensus::Network::TestNetwork,
Network::Mainnet => Ok(zcash_primitives::consensus::Network::MainNetwork),
// Note: There are differences between the `TestNetwork` parameters and those returned by
// `CRegTestParams()` in zcashd, so this function can't return `TestNetwork` unless
// Zebra is using the default public Testnet.
// TODO: Try to remove this conversion, if possible, by implementing `zcash_primitives::consensus::Parameters`
// on `Network` (#8365).
Network::Testnet(_params) if network.is_default_testnet() => {
Ok(zcash_primitives::consensus::Network::TestNetwork)
}
Network::Testnet(_params) => Err(UnsupportedNetwork),
}
}
}
@ -350,7 +360,7 @@ impl From<zcash_primitives::consensus::Network> for Network {
fn from(network: zcash_primitives::consensus::Network) -> Self {
match network {
zcash_primitives::consensus::Network::MainNetwork => Network::Mainnet,
zcash_primitives::consensus::Network::TestNetwork => Network::Testnet,
zcash_primitives::consensus::Network::TestNetwork => Network::new_default_testnet(),
}
}
}

View File

@ -137,7 +137,8 @@ impl ZcashDeserialize for Address {
}
zcash_primitives::constants::testnet::B58_SCRIPT_ADDRESS_PREFIX => {
Ok(Address::PayToScriptHash {
network: Network::Testnet,
// TODO: Replace `network` field on `Address` with the prefix and a method for checking if it's the mainnet prefix.
network: Network::new_default_testnet(),
script_hash: hash_bytes,
})
}
@ -149,7 +150,8 @@ impl ZcashDeserialize for Address {
}
zcash_primitives::constants::testnet::B58_PUBKEY_ADDRESS_PREFIX => {
Ok(Address::PayToPublicKeyHash {
network: Network::Testnet,
// TODO: Replace `network` field on `Address` with the prefix and a method for checking if it's the mainnet prefix.
network: Network::new_default_testnet(),
pub_key_hash: hash_bytes,
})
}

View File

@ -699,7 +699,8 @@ impl ParameterDifficulty for Network {
/* 2^243 - 1 */
Network::Mainnet => (U256::one() << 243) - 1,
/* 2^251 - 1 */
Network::Testnet => (U256::one() << 251) - 1,
// TODO: Add a `target_difficulty_limit` field to `NetworkParameters` to return here.
Network::Testnet(_params) => (U256::one() << 251) - 1,
};
// `zcashd` converts the PoWLimit into a compact representation before

View File

@ -29,7 +29,9 @@ pub fn funding_stream_values(
let mut results = HashMap::new();
if height >= canopy_height {
let range = FUNDING_STREAM_HEIGHT_RANGES.get(network).unwrap();
let range = FUNDING_STREAM_HEIGHT_RANGES
.get(&network.bip70_network_name())
.unwrap();
if range.contains(&height) {
let block_subsidy = block_subsidy(height, network)?;
for (&receiver, &numerator) in FUNDING_STREAM_RECEIVER_NUMERATORS.iter() {
@ -83,7 +85,10 @@ fn funding_stream_address_index(height: Height, network: &Network) -> usize {
.checked_add(funding_stream_address_period(height, network))
.expect("no overflow should happen in this sum")
.checked_sub(funding_stream_address_period(
FUNDING_STREAM_HEIGHT_RANGES.get(network).unwrap().start,
FUNDING_STREAM_HEIGHT_RANGES
.get(&network.bip70_network_name())
.unwrap()
.start,
network,
))
.expect("no overflow should happen in this sub") as usize;
@ -105,7 +110,7 @@ pub fn funding_stream_address(
) -> transparent::Address {
let index = funding_stream_address_index(height, network);
let address = &FUNDING_STREAM_ADDRESSES
.get(network)
.get(&network.bip70_network_name())
.expect("there is always another hash map as value for a given valid network")
.get(&receiver)
.expect("in the inner hash map there is always a vector of strings with addresses")[index];

View File

@ -44,7 +44,9 @@ fn test_funding_stream_values() -> Result<(), Report> {
);
// funding stream period is ending
let range = FUNDING_STREAM_HEIGHT_RANGES.get(network).unwrap();
let range = FUNDING_STREAM_HEIGHT_RANGES
.get(&network.bip70_network_name())
.unwrap();
let end = range.end;
let last = end - 1;

View File

@ -57,7 +57,10 @@ impl ParameterCheckpoint for Network {
// zcash-cli getblockhash 0
Network::Mainnet => "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
// zcash-cli -testnet getblockhash 0
Network::Testnet => "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
// TODO: Add a `genesis_hash` field to `NetworkParameters` and return it here (#8366)
Network::Testnet(_params) => {
"05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38"
}
}
.parse()
.expect("hard-coded hash parses")
@ -65,11 +68,15 @@ impl ParameterCheckpoint for Network {
fn checkpoint_list(&self) -> CheckpointList {
// parse calls CheckpointList::from_list
// TODO:
// - Add a `genesis_hash` field to `NetworkParameters` and return it here (#8366)
// - Consider adding a `CUSTOM_TESTNET_CHECKPOINTS` constant to enable building with another checkpoints list
// when using a configured testnet?
let checkpoint_list: CheckpointList = match self {
Network::Mainnet => MAINNET_CHECKPOINTS
.parse()
.expect("Hard-coded Mainnet checkpoint list parses and validates"),
Network::Testnet => TESTNET_CHECKPOINTS
Network::Testnet(_params) => TESTNET_CHECKPOINTS
.parse()
.expect("Hard-coded Testnet checkpoint list parses and validates"),
};
@ -142,9 +149,11 @@ impl CheckpointList {
// Check that the list starts with the correct genesis block
match checkpoints.iter().next() {
// TODO: Move this check to `<Network as ParameterCheckpoint>::checkpoint_list(&network)` method above (#8366),
// See <https://github.com/ZcashFoundation/zebra/pull/7924#discussion_r1385865347>
Some((block::Height(0), hash))
if (hash == &Network::Mainnet.genesis_hash()
|| hash == &Network::Testnet.genesis_hash()) => {}
|| hash == &Network::new_default_testnet().genesis_hash()) => {}
Some((block::Height(0), _)) => {
Err("the genesis checkpoint does not match the Mainnet or Testnet genesis hash")?
}

View File

@ -104,15 +104,17 @@ lazy_static! {
/// as described in [protocol specification §7.10.1][7.10.1].
///
/// [7.10.1]: https://zips.z.cash/protocol/protocol.pdf#zip214fundingstreams
pub static ref FUNDING_STREAM_HEIGHT_RANGES: HashMap<Network, std::ops::Range<Height>> = {
// TODO: Move the value here to a field on `NetworkParameters` (#8367)
pub static ref FUNDING_STREAM_HEIGHT_RANGES: HashMap<String, std::ops::Range<Height>> = {
let mut hash_map = HashMap::new();
hash_map.insert(Network::Mainnet, Height(1_046_400)..Height(2_726_400));
hash_map.insert(Network::Testnet, Height(1_028_500)..Height(2_796_000));
hash_map.insert(Network::Mainnet.bip70_network_name(), Height(1_046_400)..Height(2_726_400));
hash_map.insert(Network::new_default_testnet().bip70_network_name(), Height(1_028_500)..Height(2_796_000));
hash_map
};
/// Convenient storage for all addresses, for all receivers and networks
pub static ref FUNDING_STREAM_ADDRESSES: HashMap<Network, HashMap<FundingStreamReceiver, Vec<String>>> = {
// TODO: Move the value here to a field on `NetworkParameters` (#8367)
pub static ref FUNDING_STREAM_ADDRESSES: HashMap<String, HashMap<FundingStreamReceiver, Vec<String>>> = {
let mut addresses_by_network = HashMap::with_capacity(2);
// Mainnet addresses
@ -120,14 +122,14 @@ lazy_static! {
mainnet_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
mainnet_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
mainnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_MAINNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(Network::Mainnet, mainnet_addresses);
addresses_by_network.insert(Network::Mainnet.bip70_network_name(), mainnet_addresses);
// Testnet addresses
let mut testnet_addresses = HashMap::with_capacity(3);
testnet_addresses.insert(FundingStreamReceiver::Ecc, FUNDING_STREAM_ECC_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
testnet_addresses.insert(FundingStreamReceiver::ZcashFoundation, FUNDING_STREAM_ZF_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
testnet_addresses.insert(FundingStreamReceiver::MajorGrants, FUNDING_STREAM_MG_ADDRESSES_TESTNET.iter().map(|a| a.to_string()).collect());
addresses_by_network.insert(Network::Testnet, testnet_addresses);
addresses_by_network.insert(Network::new_default_testnet().bip70_network_name(), testnet_addresses);
addresses_by_network
};
@ -215,9 +217,11 @@ impl ParameterSubsidy for Network {
fn num_funding_streams(&self) -> usize {
match self {
Network::Mainnet => FUNDING_STREAMS_NUM_ADDRESSES_MAINNET,
Network::Testnet => FUNDING_STREAMS_NUM_ADDRESSES_TESTNET,
// TODO: Check what zcashd does here, consider adding a field to `NetworkParamters` to make this configurable.
Network::Testnet(_params) => FUNDING_STREAMS_NUM_ADDRESSES_TESTNET,
}
}
fn height_for_first_halving(&self) -> Height {
// First halving on Mainnet is at Canopy
// while in Testnet is at block constant height of `1_116_000`
@ -226,7 +230,9 @@ impl ParameterSubsidy for Network {
Network::Mainnet => NetworkUpgrade::Canopy
.activation_height(self)
.expect("canopy activation height should be available"),
Network::Testnet => FIRST_HALVING_TESTNET,
// TODO: Check what zcashd does here, consider adding a field to `NetworkParamters` to make this configurable.
Network::Testnet(_params) => FIRST_HALVING_TESTNET,
}
}
}

View File

@ -15,6 +15,8 @@ use tempfile::NamedTempFile;
use tokio::{fs, io::AsyncWriteExt};
use tracing::Span;
use lazy_static::lazy_static;
use zebra_chain::parameters::Network;
use crate::{
@ -176,6 +178,10 @@ pub struct Config {
pub max_connections_per_ip: usize,
}
lazy_static! {
static ref EMPTY_INITIAL_REGTEST_PEERS: IndexSet<String> = IndexSet::new();
}
impl Config {
/// The maximum number of outbound connections that Zebra will open at the same time.
/// When this limit is reached, Zebra stops opening outbound connections.
@ -223,9 +229,13 @@ impl Config {
/// Returns the initial seed peer hostnames for the configured network.
pub fn initial_peer_hostnames(&self) -> &IndexSet<String> {
match self.network {
match &self.network {
Network::Mainnet => &self.initial_mainnet_peers,
Network::Testnet => &self.initial_testnet_peers,
Network::Testnet(params) if params.is_default_testnet() => &self.initial_testnet_peers,
// TODO: Check if the network is an incompatible custom testnet (_not_ Regtest), then panic if `initial_testnet_peers`
// contains any of the default testnet peers, or return `initial_testnet_peers` otherwise. See:
// <https://github.com/ZcashFoundation/zebra/pull/7924#discussion_r1385881828>
Network::Testnet(_params) => &EMPTY_INITIAL_REGTEST_PEERS,
}
}

View File

@ -392,11 +392,12 @@ lazy_static! {
///
/// The minimum network protocol version typically changes after Mainnet and
/// Testnet network upgrades.
pub static ref INITIAL_MIN_NETWORK_PROTOCOL_VERSION: HashMap<Network, Version> = {
// TODO: Move the value here to a field on `NetworkParameters` (#8367)
pub static ref INITIAL_MIN_NETWORK_PROTOCOL_VERSION: HashMap<String, Version> = {
let mut hash_map = HashMap::new();
hash_map.insert(Mainnet, Version::min_specified_for_upgrade(&Mainnet, Nu5));
hash_map.insert(Testnet, Version::min_specified_for_upgrade(&Testnet, Nu5));
hash_map.insert(Mainnet.bip70_network_name(), Version::min_specified_for_upgrade(&Mainnet, Nu5));
hash_map.insert(Network::new_default_testnet().bip70_network_name(), Version::min_specified_for_upgrade(&Network::new_default_testnet(), Nu5));
hash_map
};

View File

@ -8,7 +8,7 @@ use zebra_chain::{
},
};
use crate::constants::{self, magics};
use crate::constants::{self, magics, CURRENT_NETWORK_PROTOCOL_VERSION};
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
@ -31,7 +31,8 @@ impl ParameterMagic for Network {
fn magic_value(&self) -> Magic {
match self {
Network::Mainnet => magics::MAINNET,
Network::Testnet => magics::TESTNET,
// TODO: Move `Magic` struct definition to `zebra-chain`, add it as a field in `NetworkParameters`, and return it here.
Network::Testnet(_params) => magics::TESTNET,
}
}
}
@ -80,7 +81,7 @@ impl Version {
/// - after Zebra's local network is slow or shut down.
fn initial_min_for_network(network: &Network) -> Version {
*constants::INITIAL_MIN_NETWORK_PROTOCOL_VERSION
.get(network)
.get(&network.bip70_network_name())
.expect("We always have a value for testnet or mainnet")
}
@ -103,17 +104,22 @@ impl Version {
// sync? zcashd accepts 170_002 or later during its initial sync.
Version(match (network, network_upgrade) {
(_, Genesis) | (_, BeforeOverwinter) => 170_002,
(Testnet, Overwinter) => 170_003,
(Testnet(params), Overwinter) if params.is_default_testnet() => 170_003,
(Mainnet, Overwinter) => 170_005,
// TODO: Use 170_006 for (Testnet(params), Sapling) if params.is_regtest() (`Regtest` in zcashd uses
// version 170_006 for Sapling, and the same values as Testnet for other network upgrades.)
(_, Sapling) => 170_007,
(Testnet, Blossom) => 170_008,
(Testnet(params), Blossom) if params.is_default_testnet() => 170_008,
(Mainnet, Blossom) => 170_009,
(Testnet, Heartwood) => 170_010,
(Testnet(params), Heartwood) if params.is_default_testnet() => 170_010,
(Mainnet, Heartwood) => 170_011,
(Testnet, Canopy) => 170_012,
(Testnet(params), Canopy) if params.is_default_testnet() => 170_012,
(Mainnet, Canopy) => 170_013,
(Testnet, Nu5) => 170_050,
(Testnet(params), Nu5) if params.is_default_testnet() => 170_050,
(Mainnet, Nu5) => 170_100,
// It should be fine to reject peers with earlier network protocol versions on custom testnets for now.
(Testnet(_params), _) => CURRENT_NETWORK_PROTOCOL_VERSION.0,
})
}
}

View File

@ -384,7 +384,10 @@ pub fn scan_block<K: ScanningKey>(
// TODO: Implement a check that returns early when the block height is below the Sapling
// activation height.
let network: zcash_primitives::consensus::Network = network.into();
// TODO: Implement `zcash_primitives::consensus::Parameters` for `Network` and remove this conversion (#8365)
let network: zcash_primitives::consensus::Network = network
.try_into()
.expect("must match zcash_primitives network");
let chain_metadata = ChainMetadata {
sapling_commitment_tree_size: sapling_tree_size,

View File

@ -183,10 +183,9 @@ impl AdjustedDifficulty {
self.candidate_time,
self.relevant_times[0],
) {
assert_eq!(
self.network,
Network::Testnet,
"invalid network: the minimum difficulty rule only applies on testnet"
assert!(
self.network.is_a_test_network(),
"invalid network: the minimum difficulty rule only applies on test networks"
);
self.network.target_difficulty_limit().to_compact()
} else {

View File

@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use zebra_chain::{
amount::{self, Amount, NonNegative},
block::Height,
parameters::Network::*,
parameters::Network::{self, *},
serialization::{ZcashDeserializeInto, ZcashSerialize},
transparent::{self, Address::*},
};
@ -504,8 +504,11 @@ fn address_variant(address: &transparent::Address) -> u8 {
match (address.network(), address) {
(Mainnet, PayToPublicKeyHash { .. }) => 0,
(Mainnet, PayToScriptHash { .. }) => 1,
(Testnet, PayToPublicKeyHash { .. }) => 2,
(Testnet, PayToScriptHash { .. }) => 3,
(Testnet(params), PayToPublicKeyHash { .. }) if params.is_default_testnet() => 2,
(Testnet(params), PayToScriptHash { .. }) if params.is_default_testnet() => 3,
// TODO: Use 4 and 5 for `Regtest` (#7839)
(Testnet(_params), PayToPublicKeyHash { .. }) => 6,
(Testnet(_params), PayToScriptHash { .. }) => 7,
}
}
@ -531,7 +534,8 @@ impl FromDisk for transparent::Address {
let network = if address_variant < 2 {
Mainnet
} else {
Testnet
// TODO: Replace `network` field on `Address` with the prefix and a method for checking if it's the mainnet prefix.
Network::new_default_testnet()
};
if address_variant % 2 == 0 {