-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add(consensus): Add
activation_heights
field to NetworkParameters
…
… and implement `Parameters` for `Network` (#8383) * minor cleanup and rename * Adds an empty NetworkParameters struct to Network::Testnet variant, updates production code. * Updates tests * Adds `NetworkKind` and uses it instead of `Network` in `HistoryTreeParts` and `transparent::Address` * Adds a [network.testnet_parameters] section to the config, uses `NetworkKind` as zebra_network::Config::network field type, and converts 'Network' to `NetworkKind` before serializing * Applies some suggestions from code review * Applies suggestions from code review * returns b58 prefix constants directly to remove From<NetworkKind> impl for zcash_primitives::consensus::Network * Applies more suggestions from code review. * moves conversions to zcash_primitives::consensus::Network to where they're used. * Apply suggestions from code review Co-authored-by: Marek <[email protected]> * rename `network` variables and method names typed as NetworkKind to `network_kind` * use only test block heights for the network associated with them * Applies more suggestions from code review. * Rename `NetworkParameters` to `Parameters` and move it a new `testnet` module * adds activation heights field * updates stored test config, adds a quicker test for checking that stored configs can be parsed, adds an intermediate representation of activation heights * implement Parameters for Network * Passes &Network directly instead of converting to zp_consensus::Network where there were conversions * fixes a bad merge (removes a network conversion in zcash_note_encryption) * Adds a test for the Parameters impl for zebra_chain::Network * fixes doc links * - Makes the `activation_heights` config field optional by adding a #[serde(default)] - Panics if a non-zero activation height is provided for the `Genesis` network upgrade - Always sets the `Genesis` and `BeforeOverwinter` network upgrade activation heights to 0 and 1, `BeforeOverwinter` could be overwritten by a later network upgrade - Makes the `activation_heights` field on `Parameters` private, adds/uses an accessor method instead, and adds a builder struct and `build()` method * small refactor of activation_heights() method * check that activation heights are in the right order * Updates `NetworkUpgrade::activation_height()` to return the height of the next NetworkUpgrade if it doesn't find the activation height of `&self` * checks that the miner address is of TestnetKind on Regtest and update assertion message * Adds a DNetworkUpgradeActivationHeights struct for better control over how activation heights can be configured * moves all ordered network upgrades to a constant, adds a no_duplicates test, moves struct with activation heights outside deserialization impl and accepts it in `ParametersBuilder::activation_heights()` instead of a Vec * panics if any network upgrades are configured to activate at Height(0) because it's reserved for Genesis * Simplifies the `ParametersBuilder::activation_heights()` method and removes an unnecessary test. * Adds Sapling HRPs as fields on testnet params. (#8398) * Applies suggestions from code review. * Update zebra-chain/src/parameters/network_upgrade.rs Co-authored-by: Marek <[email protected]> --------- Co-authored-by: Marek <[email protected]>
- Loading branch information
Showing
13 changed files
with
587 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,220 @@ | ||
//! Types and implementation for Testnet consensus parameters | ||
use std::collections::BTreeMap; | ||
|
||
#[cfg(any(test, feature = "proptest-impl"))] | ||
use proptest_derive::Arbitrary; | ||
use zcash_primitives::constants as zp_constants; | ||
|
||
use crate::{ | ||
block::Height, | ||
parameters::{ | ||
network_upgrade::TESTNET_ACTIVATION_HEIGHTS, Network, NetworkUpgrade, | ||
NETWORK_UPGRADES_IN_ORDER, | ||
}, | ||
}; | ||
|
||
/// Configurable activation heights for Regtest and configured Testnets. | ||
#[derive(Deserialize, Default)] | ||
#[serde(rename_all = "PascalCase")] | ||
pub struct ConfiguredActivationHeights { | ||
/// Activation height for `BeforeOverwinter` network upgrade. | ||
pub before_overwinter: Option<u32>, | ||
/// Activation height for `Overwinter` network upgrade. | ||
pub overwinter: Option<u32>, | ||
/// Activation height for `Sapling` network upgrade. | ||
pub sapling: Option<u32>, | ||
/// Activation height for `Blossom` network upgrade. | ||
pub blossom: Option<u32>, | ||
/// Activation height for `Heartwood` network upgrade. | ||
pub heartwood: Option<u32>, | ||
/// Activation height for `Canopy` network upgrade. | ||
pub canopy: Option<u32>, | ||
/// Activation height for `NU5` network upgrade. | ||
#[serde(rename = "NU5")] | ||
pub nu5: Option<u32>, | ||
} | ||
|
||
/// Builder for the [`Parameters`] struct. | ||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] | ||
pub struct ParametersBuilder { | ||
/// The network upgrade activation heights for this network, see [`Parameters::activation_heights`] for more details. | ||
activation_heights: BTreeMap<Height, NetworkUpgrade>, | ||
/// Sapling extended spending key human-readable prefix for this network | ||
hrp_sapling_extended_spending_key: String, | ||
/// Sapling extended full viewing key human-readable prefix for this network | ||
hrp_sapling_extended_full_viewing_key: String, | ||
/// Sapling payment address human-readable prefix for this network | ||
hrp_sapling_payment_address: String, | ||
} | ||
|
||
impl Default for ParametersBuilder { | ||
fn default() -> Self { | ||
Self { | ||
// # Correctness | ||
// | ||
// `Genesis` network upgrade activation height must always be 0 | ||
activation_heights: [ | ||
(Height(0), NetworkUpgrade::Genesis), | ||
// TODO: Find out if `BeforeOverwinter` must always be active at Height(1), remove it here if it's not required. | ||
(Height(1), NetworkUpgrade::BeforeOverwinter), | ||
] | ||
.into_iter() | ||
.collect(), | ||
hrp_sapling_extended_spending_key: | ||
zp_constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY.to_string(), | ||
hrp_sapling_extended_full_viewing_key: | ||
zp_constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY.to_string(), | ||
hrp_sapling_payment_address: zp_constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS | ||
.to_string(), | ||
} | ||
} | ||
} | ||
|
||
impl ParametersBuilder { | ||
/// Checks that the provided network upgrade activation heights are in the correct order, then | ||
/// sets them as the new network upgrade activation heights. | ||
pub fn activation_heights( | ||
mut self, | ||
ConfiguredActivationHeights { | ||
// TODO: Find out if `BeforeOverwinter` is required at Height(1), allow for | ||
// configuring its activation height if it's not required to be at Height(1) | ||
before_overwinter: _, | ||
overwinter, | ||
sapling, | ||
blossom, | ||
heartwood, | ||
canopy, | ||
nu5, | ||
}: ConfiguredActivationHeights, | ||
) -> Self { | ||
use NetworkUpgrade::*; | ||
|
||
// # Correctness | ||
// | ||
// These must be in order so that later network upgrades overwrite prior ones | ||
// if multiple network upgrades are configured with the same activation height. | ||
let activation_heights: BTreeMap<_, _> = overwinter | ||
.into_iter() | ||
.map(|h| (h, Overwinter)) | ||
.chain(sapling.into_iter().map(|h| (h, Sapling))) | ||
.chain(blossom.into_iter().map(|h| (h, Blossom))) | ||
.chain(heartwood.into_iter().map(|h| (h, Heartwood))) | ||
.chain(canopy.into_iter().map(|h| (h, Canopy))) | ||
.chain(nu5.into_iter().map(|h| (h, Nu5))) | ||
.filter(|&(_, nu)| nu != NetworkUpgrade::BeforeOverwinter) | ||
.map(|(h, nu)| (h.try_into().expect("activation height must be valid"), nu)) | ||
.collect(); | ||
|
||
let network_upgrades: Vec<_> = activation_heights.iter().map(|(_h, &nu)| nu).collect(); | ||
|
||
// Check that the provided network upgrade activation heights are in the same order by height as the default testnet activation heights | ||
let mut activation_heights_iter = activation_heights.iter(); | ||
for expected_network_upgrade in NETWORK_UPGRADES_IN_ORDER { | ||
if !network_upgrades.contains(&expected_network_upgrade) { | ||
continue; | ||
} else if let Some((&height, &network_upgrade)) = activation_heights_iter.next() { | ||
assert_ne!( | ||
height, | ||
Height(0), | ||
"Height(0) is reserved for the `Genesis` upgrade" | ||
); | ||
|
||
assert!( | ||
network_upgrade == expected_network_upgrade, | ||
"network upgrades must be activated in order, the correct order is {NETWORK_UPGRADES_IN_ORDER:?}" | ||
); | ||
} | ||
} | ||
|
||
// # Correctness | ||
// | ||
// Height(0) must be reserved for the `NetworkUpgrade::Genesis`. | ||
self.activation_heights.split_off(&Height(2)); | ||
self.activation_heights.extend(activation_heights); | ||
|
||
self | ||
} | ||
|
||
/// Converts the builder to a [`Parameters`] struct | ||
pub fn finish(self) -> Parameters { | ||
let Self { | ||
activation_heights, | ||
hrp_sapling_extended_spending_key, | ||
hrp_sapling_extended_full_viewing_key, | ||
hrp_sapling_payment_address, | ||
} = self; | ||
Parameters { | ||
activation_heights, | ||
hrp_sapling_extended_spending_key, | ||
hrp_sapling_extended_full_viewing_key, | ||
hrp_sapling_payment_address, | ||
} | ||
} | ||
|
||
/// Converts the builder to a configured [`Network::Testnet`] | ||
pub fn to_network(self) -> Network { | ||
Network::new_configured_testnet(self.finish()) | ||
} | ||
} | ||
|
||
/// 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 Parameters {} | ||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] | ||
pub struct Parameters { | ||
/// The network upgrade activation heights for this network. | ||
/// | ||
/// Note: This value is ignored by `Network::activation_list()` when `zebra-chain` is | ||
/// compiled with the `zebra-test` feature flag AND the `TEST_FAKE_ACTIVATION_HEIGHTS` | ||
/// environment variable is set. | ||
activation_heights: BTreeMap<Height, NetworkUpgrade>, | ||
/// Sapling extended spending key human-readable prefix for this network | ||
hrp_sapling_extended_spending_key: String, | ||
/// Sapling extended full viewing key human-readable prefix for this network | ||
hrp_sapling_extended_full_viewing_key: String, | ||
/// Sapling payment address human-readable prefix for this network | ||
hrp_sapling_payment_address: String, | ||
} | ||
|
||
impl Default for Parameters { | ||
/// Returns an instance of the default public testnet [`Parameters`]. | ||
fn default() -> Self { | ||
Self { | ||
activation_heights: TESTNET_ACTIVATION_HEIGHTS.iter().cloned().collect(), | ||
hrp_sapling_extended_spending_key: | ||
zp_constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY.to_string(), | ||
hrp_sapling_extended_full_viewing_key: | ||
zp_constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY.to_string(), | ||
hrp_sapling_payment_address: zp_constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS | ||
.to_string(), | ||
} | ||
} | ||
} | ||
|
||
impl Parameters { | ||
/// Creates a new [`ParametersBuilder`]. | ||
pub fn build() -> ParametersBuilder { | ||
ParametersBuilder::default() | ||
} | ||
|
||
/// Returns true if the instance of [`Parameters`] represents the default public Testnet. | ||
pub fn is_default_testnet(&self) -> bool { | ||
self == &Self::default() | ||
} | ||
|
||
/// Returns the network upgrade activation heights | ||
pub fn activation_heights(&self) -> &BTreeMap<Height, NetworkUpgrade> { | ||
&self.activation_heights | ||
} | ||
|
||
/// Returns the `hrp_sapling_extended_spending_key` field | ||
pub fn hrp_sapling_extended_spending_key(&self) -> &str { | ||
&self.hrp_sapling_extended_spending_key | ||
} | ||
|
||
/// Returns the `hrp_sapling_extended_full_viewing_key` field | ||
pub fn hrp_sapling_extended_full_viewing_key(&self) -> &str { | ||
&self.hrp_sapling_extended_full_viewing_key | ||
} | ||
|
||
/// Returns the `hrp_sapling_payment_address` field | ||
pub fn hrp_sapling_payment_address(&self) -> &str { | ||
&self.hrp_sapling_payment_address | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
mod prop; | ||
mod vectors; |
Oops, something went wrong.