adds constraints on valid network names and a test
This commit is contained in:
parent
1173faf894
commit
1608472f5a
|
@ -1,5 +1,5 @@
|
|||
//! Types and implementation for Testnet consensus parameters
|
||||
use std::collections::BTreeMap;
|
||||
use std::{collections::BTreeMap, fmt};
|
||||
|
||||
use zcash_primitives::constants as zp_constants;
|
||||
|
||||
|
@ -11,6 +11,12 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
/// Reserved network names that should not be allowed for configured Testnets.
|
||||
pub const RESERVED_NETWORK_NAMES: [&str; 3] = ["Mainnet", "Testnet", "Regtest"];
|
||||
|
||||
/// Maximum length for a configured network name.
|
||||
pub const MAX_NETWORK_NAME_LENGTH: usize = 30;
|
||||
|
||||
/// Configurable activation heights for Regtest and configured Testnets.
|
||||
#[derive(Deserialize, Default)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
|
@ -50,7 +56,7 @@ pub struct ParametersBuilder {
|
|||
impl Default for ParametersBuilder {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
network_name: "Testnet".to_string(),
|
||||
network_name: "UnknownTestnet".to_string(),
|
||||
// # Correctness
|
||||
//
|
||||
// `Genesis` network upgrade activation height must always be 0
|
||||
|
@ -73,8 +79,26 @@ impl Default for ParametersBuilder {
|
|||
|
||||
impl ParametersBuilder {
|
||||
/// Sets the network name to be used in the [`Parameters`] being built.
|
||||
pub fn network_name(mut self, network_name: String) -> Self {
|
||||
self.network_name = network_name;
|
||||
pub fn network_name(mut self, network_name: impl fmt::Display) -> Self {
|
||||
self.network_name = network_name.to_string();
|
||||
|
||||
assert!(
|
||||
!RESERVED_NETWORK_NAMES.contains(&self.network_name.as_str()),
|
||||
"cannot use reserved network name '{network_name}' as configured Testnet name, reserved names: {RESERVED_NETWORK_NAMES:?}"
|
||||
);
|
||||
|
||||
assert!(
|
||||
self.network_name.len() <= MAX_NETWORK_NAME_LENGTH,
|
||||
"network name {network_name} is too long, must be {MAX_NETWORK_NAME_LENGTH} characters or less"
|
||||
);
|
||||
|
||||
assert!(
|
||||
self.network_name
|
||||
.chars()
|
||||
.all(|x| x.is_alphanumeric() || x == '_'),
|
||||
"network name must include only alphanumeric characters or '_'"
|
||||
);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -188,6 +212,7 @@ impl Default for Parameters {
|
|||
/// Returns an instance of the default public testnet [`Parameters`].
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
network_name: "Testnet".to_string(),
|
||||
activation_heights: TESTNET_ACTIVATION_HEIGHTS.iter().cloned().collect(),
|
||||
..Self::build().finish()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ use zcash_primitives::consensus::{self as zp_consensus, Parameters};
|
|||
use crate::{
|
||||
block::Height,
|
||||
parameters::{
|
||||
testnet::{self, ConfiguredActivationHeights},
|
||||
testnet::{
|
||||
self, ConfiguredActivationHeights, MAX_NETWORK_NAME_LENGTH, RESERVED_NETWORK_NAMES,
|
||||
},
|
||||
Network, NetworkUpgrade, NETWORK_UPGRADES_IN_ORDER,
|
||||
},
|
||||
};
|
||||
|
@ -125,3 +127,58 @@ fn activates_network_upgrades_correctly() {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that configured testnet names are validated and used correctly.
|
||||
#[test]
|
||||
fn check_network_name() {
|
||||
// Sets a no-op panic hook to avoid long output.
|
||||
std::panic::set_hook(Box::new(|_| {}));
|
||||
|
||||
// Checks that reserved network names cannot be used for configured testnets.
|
||||
for reserved_network_name in RESERVED_NETWORK_NAMES {
|
||||
std::panic::catch_unwind(|| {
|
||||
testnet::Parameters::build().network_name(reserved_network_name)
|
||||
})
|
||||
.expect_err("should panic when attempting to set network name as a reserved name");
|
||||
}
|
||||
|
||||
// Check that max length is enforced, and that network names may only contain alphanumeric characters and '_'.
|
||||
for invalid_network_name in [
|
||||
"a".repeat(MAX_NETWORK_NAME_LENGTH + 1),
|
||||
"!!!!non-alphanumeric-name".to_string(),
|
||||
] {
|
||||
std::panic::catch_unwind(|| {
|
||||
testnet::Parameters::build().network_name(invalid_network_name)
|
||||
})
|
||||
.expect_err("should panic when setting network name that's too long or contains non-alphanumeric characters (except '_')");
|
||||
}
|
||||
|
||||
// Checks that network names are displayed correctly
|
||||
assert_eq!(
|
||||
Network::new_default_testnet().to_string(),
|
||||
"Testnet",
|
||||
"default testnet should be displayed as 'Testnet'"
|
||||
);
|
||||
assert_eq!(
|
||||
Network::Mainnet.to_string(),
|
||||
"Mainnet",
|
||||
"Mainnet should be displayed as 'Mainnet'"
|
||||
);
|
||||
|
||||
// TODO: Check Regtest
|
||||
|
||||
// Check that network name can contain alphanumeric characters and '_'.
|
||||
let expected_name = "ConfiguredTestnet_1";
|
||||
let network = testnet::Parameters::build()
|
||||
// Check that network name can contain `MAX_NETWORK_NAME_LENGTH` characters
|
||||
.network_name("a".repeat(MAX_NETWORK_NAME_LENGTH))
|
||||
.network_name(expected_name)
|
||||
.to_network();
|
||||
|
||||
// Check that configured network name is displayed
|
||||
assert_eq!(
|
||||
network.to_string(),
|
||||
expected_name,
|
||||
"network must be displayed as configured network name"
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue