- 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
This commit is contained in:
parent
997e265636
commit
93c7a58330
|
@ -6,6 +6,54 @@ use crate::{
|
|||
parameters::{network_upgrade::TESTNET_ACTIVATION_HEIGHTS, NetworkUpgrade},
|
||||
};
|
||||
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
impl Default for ParametersBuilder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// # Correctness
|
||||
//
|
||||
// `Genesis` network upgrade activation height must always be 0
|
||||
// TODO: Find out if `BeforeOverwinter` must always be active at height 1
|
||||
activation_heights: [
|
||||
(Height(0), NetworkUpgrade::Genesis),
|
||||
(Height(1), NetworkUpgrade::BeforeOverwinter),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ParametersBuilder {
|
||||
/// Extends network upgrade activation heights with the provided activation heights.
|
||||
pub fn activation_heights(
|
||||
mut self,
|
||||
new_activation_heights: Vec<(Height, NetworkUpgrade)>,
|
||||
) -> Self {
|
||||
let new_activation_heights: BTreeMap<_, _> =
|
||||
new_activation_heights.iter().cloned().collect();
|
||||
|
||||
// # Correctness
|
||||
//
|
||||
// Height(0) must be reserved for the `NetworkUpgrade::Genesis`.
|
||||
self.activation_heights
|
||||
.extend(new_activation_heights.range(Height(1)..));
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts the builder to a [`Parameters`] struct
|
||||
pub fn finish(self) -> Parameters {
|
||||
let Self { activation_heights } = self;
|
||||
Parameters { activation_heights }
|
||||
}
|
||||
}
|
||||
|
||||
/// Network consensus parameters for test networks such as Regtest and the default Testnet.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct Parameters {
|
||||
|
@ -14,21 +62,31 @@ pub struct Parameters {
|
|||
/// 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.
|
||||
pub activation_heights: BTreeMap<Height, NetworkUpgrade>,
|
||||
activation_heights: BTreeMap<Height, NetworkUpgrade>,
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
Self::build()
|
||||
.activation_heights(TESTNET_ACTIVATION_HEIGHTS.to_vec())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
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 a reference to the network upgrade activation heights
|
||||
pub fn activation_heights(&self) -> &BTreeMap<Height, NetworkUpgrade> {
|
||||
&self.activation_heights
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ impl Network {
|
|||
}
|
||||
|
||||
Mainnet => MAINNET_ACTIVATION_HEIGHTS.iter().cloned().collect(),
|
||||
Testnet(params) => params.activation_heights.clone(),
|
||||
Testnet(params) => params.activation_heights().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -625,9 +625,9 @@ impl<'de> Deserialize<'de> for Config {
|
|||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
/// Network consensus parameters for test networks such as Regtest and the default Testnet.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct DTestnetParameters {
|
||||
#[derive(Deserialize)]
|
||||
struct DTestnetParameters {
|
||||
#[serde(default)]
|
||||
pub(super) activation_heights: Vec<(u32, NetworkUpgrade)>,
|
||||
}
|
||||
|
||||
|
@ -686,6 +686,11 @@ impl<'de> Deserialize<'de> for Config {
|
|||
let activation_heights = activation_heights
|
||||
.into_iter()
|
||||
.map(|(height, network_upgrade)| {
|
||||
assert!(
|
||||
network_upgrade != NetworkUpgrade::Genesis || height == 0,
|
||||
"Genesis network upgrade activation height is not configurable"
|
||||
);
|
||||
|
||||
(
|
||||
height.try_into().expect("activation height must be valid"),
|
||||
network_upgrade,
|
||||
|
@ -693,7 +698,11 @@ impl<'de> Deserialize<'de> for Config {
|
|||
})
|
||||
.collect();
|
||||
|
||||
Network::new_configured_testnet(testnet::Parameters { activation_heights })
|
||||
let testnet_parameters = testnet::Parameters::build()
|
||||
.activation_heights(activation_heights)
|
||||
.finish();
|
||||
|
||||
Network::new_configured_testnet(testnet_parameters)
|
||||
} else {
|
||||
// Convert to default `Network` for a `NetworkKind` if there are no testnet parameters.
|
||||
match network_kind {
|
||||
|
|
|
@ -62,7 +62,6 @@ peerset_initial_target_size = 25
|
|||
|
||||
[network.testnet_parameters]
|
||||
activation_heights = [
|
||||
[0, "Genesis"],
|
||||
[1, "BeforeOverwinter"],
|
||||
[207_500, "Overwinter"],
|
||||
[280_000, "Sapling"],
|
||||
|
|
Loading…
Reference in New Issue