Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge queue: embarking main (e95a70d) and #8413 together #8467

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
9db4762
minor cleanup and rename
arya2 Mar 20, 2024
4b86bd6
Adds an empty NetworkParameters struct to Network::Testnet variant, u…
arya2 Mar 20, 2024
7533e2f
Updates tests
arya2 Mar 20, 2024
06cf947
Adds `NetworkKind` and uses it instead of `Network` in `HistoryTreePa…
arya2 Mar 22, 2024
4900a20
Adds a [network.testnet_parameters] section to the config, uses `Netw…
arya2 Mar 22, 2024
cb8726b
Applies some suggestions from code review
arya2 Apr 1, 2024
d5a807a
Applies suggestions from code review
arya2 Apr 2, 2024
d108ec6
returns b58 prefix constants directly to remove From<NetworkKind> imp…
arya2 Apr 2, 2024
574b1f9
Applies more suggestions from code review.
arya2 Apr 2, 2024
05e41a2
moves conversions to zcash_primitives::consensus::Network to where th…
arya2 Apr 2, 2024
fd3d505
Apply suggestions from code review
arya2 Apr 11, 2024
f04b94b
rename `network` variables and method names typed as NetworkKind to `…
arya2 Apr 11, 2024
ea2d001
use only test block heights for the network associated with them
arya2 Apr 11, 2024
86cd919
Applies more suggestions from code review.
arya2 Apr 11, 2024
365b58e
Rename `NetworkParameters` to `Parameters` and move it a new `testnet…
arya2 Apr 11, 2024
eca7f6b
Merge branch 'main' into network-params
arya2 Apr 11, 2024
60248e3
adds activation heights field
arya2 Apr 2, 2024
b9bdf05
updates stored test config, adds a quicker test for checking that sto…
arya2 Apr 3, 2024
ad4e7dc
implement Parameters for Network
arya2 Apr 3, 2024
4347a80
Passes &Network directly instead of converting to zp_consensus::Netwo…
arya2 Apr 3, 2024
080affd
fixes a bad merge (removes a network conversion in zcash_note_encrypt…
arya2 Apr 11, 2024
2493e7e
Adds a test for the Parameters impl for zebra_chain::Network
arya2 Apr 11, 2024
997e265
fixes doc links
arya2 Apr 11, 2024
93c7a58
- Makes the `activation_heights` config field optional by adding a #[…
arya2 Apr 12, 2024
0fd4158
small refactor of activation_heights() method
arya2 Apr 12, 2024
3952caa
check that activation heights are in the right order
arya2 Apr 12, 2024
e697d36
Updates `NetworkUpgrade::activation_height()` to return the height of…
arya2 Apr 12, 2024
325a6c6
checks that the miner address is of TestnetKind on Regtest and update…
arya2 Apr 12, 2024
f724c01
Adds a DNetworkUpgradeActivationHeights struct for better control ove…
arya2 Apr 12, 2024
a37510a
moves all ordered network upgrades to a constant, adds a no_duplicate…
arya2 Apr 12, 2024
0abe873
panics if any network upgrades are configured to activate at Height(0…
arya2 Apr 12, 2024
1dfad53
Simplifies the `ParametersBuilder::activation_heights()` method and r…
arya2 Apr 12, 2024
868535b
Merge branch 'main' into activ-heights-param-impl
arya2 Apr 17, 2024
0b835f1
Adds Sapling HRPs as fields on testnet params. (#8398)
arya2 Apr 17, 2024
fb2d13a
Applies suggestions from code review.
arya2 Apr 17, 2024
fea2162
Update zebra-chain/src/parameters/network_upgrade.rs
arya2 Apr 18, 2024
a94dcab
Adds `network_name` field and accessor method on `Parameters`, uses i…
arya2 Apr 18, 2024
1173faf
Removes unnecessary `.filter()`
arya2 Apr 18, 2024
1608472
adds constraints on valid network names and a test
arya2 Apr 18, 2024
08f0838
adds config field for setting network name, adds "with_" prefix to Pa…
arya2 Apr 18, 2024
0e97b53
Adds `MainnetKind`, `TestnetKind`, and `RegtestKind` to reserved netw…
arya2 Apr 18, 2024
a842c12
updates stored test configs and fixes `network_name()` docs
arya2 Apr 18, 2024
c79e06f
Merge remote-tracking branch 'origin/main' into params-network-name
arya2 Apr 19, 2024
6e29727
Adds a `new_regtest()` method on `Network` and `testnet::Parameters`,…
arya2 Apr 18, 2024
32d0758
Updates `activates_network_upgrades_correctly` test to check Regtest …
arya2 Apr 18, 2024
e816c66
Refactors if-let & match statement into general match statement, remo…
arya2 Apr 18, 2024
32e4fbb
Removes outdated TODO
arya2 Apr 18, 2024
63623ae
Restores `testnet_parameters` section of the latest stored config.
arya2 Apr 18, 2024
d871590
Adds `with_sapling_hrps()` method and uses it to set the Regtest HRPs…
arya2 Apr 18, 2024
4671efe
Checks that default Mainnet/Testnet/Regtest Sapling HRPs pass validat…
arya2 Apr 18, 2024
9b41cba
Uses the correct constant in test
arya2 Apr 18, 2024
b38dbfd
Adds `is_regtest()` methods
arya2 Apr 19, 2024
b7957e9
Merge remote-tracking branch 'origin/main' into params-new-regtest
arya2 Apr 24, 2024
13d59ad
Updates test docs
arya2 Apr 24, 2024
3b5a7f5
drop custom panic hooks after expected panics
arya2 Apr 24, 2024
ace7f19
Merge branch 'main' into params-new-regtest
arya2 Apr 24, 2024
07a4f89
Merge of #8413
mergify[bot] Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions zebra-chain/src/parameters/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::{
parameters::NetworkUpgrade,
};

use self::testnet::ConfiguredActivationHeights;

pub mod testnet;

#[cfg(test)]
Expand Down Expand Up @@ -142,8 +144,6 @@ impl<'a> From<&'a Network> for &'a str {
fn from(network: &'a Network) -> &'a str {
match network {
Network::Mainnet => "Mainnet",
// TODO:
// - zcashd calls the Regtest cache dir 'regtest' (#8327).
Network::Testnet(params) => params.network_name(),
}
}
Expand All @@ -166,6 +166,11 @@ impl Network {
Self::Testnet(Arc::new(params))
}

/// Creates a new [`Network::Testnet`] with `Regtest` parameters and the provided network upgrade activation heights.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
Self::new_configured_testnet(testnet::Parameters::new_regtest(activation_heights))
}

/// 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 {
Expand All @@ -175,6 +180,15 @@ impl Network {
}
}

/// Returns true if the network is Regtest, or false otherwise.
pub fn is_regtest(&self) -> bool {
if let Self::Testnet(params) = self {
params.is_regtest()
} else {
false
}
}

/// Returns the [`NetworkKind`] for this network.
pub fn kind(&self) -> NetworkKind {
match self {
Expand Down
86 changes: 78 additions & 8 deletions zebra-chain/src/parameters/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub const RESERVED_NETWORK_NAMES: [&str; 6] = [
/// Maximum length for a configured network name.
pub const MAX_NETWORK_NAME_LENGTH: usize = 30;

/// Maximum length for a configured human-readable prefix.
pub const MAX_HRP_LENGTH: usize = 30;

/// Configurable activation heights for Regtest and configured Testnets.
#[derive(Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
Expand Down Expand Up @@ -67,13 +70,7 @@ impl Default for ParametersBuilder {
// # 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(),
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:
Expand Down Expand Up @@ -109,6 +106,44 @@ impl ParametersBuilder {
self
}

/// Checks that the provided Sapling human-readable prefixes (HRPs) are valid and unique, then
/// sets the Sapling HRPs to be used in the [`Parameters`] being built.
pub fn with_sapling_hrps(
mut self,
hrp_sapling_extended_spending_key: impl fmt::Display,
hrp_sapling_extended_full_viewing_key: impl fmt::Display,
hrp_sapling_payment_address: impl fmt::Display,
) -> Self {
self.hrp_sapling_extended_spending_key = hrp_sapling_extended_spending_key.to_string();
self.hrp_sapling_extended_full_viewing_key =
hrp_sapling_extended_full_viewing_key.to_string();
self.hrp_sapling_payment_address = hrp_sapling_payment_address.to_string();

let sapling_hrps = [
&self.hrp_sapling_extended_spending_key,
&self.hrp_sapling_extended_full_viewing_key,
&self.hrp_sapling_payment_address,
];

for sapling_hrp in sapling_hrps {
assert!(sapling_hrp.len() <= MAX_HRP_LENGTH, "Sapling human-readable prefix {sapling_hrp} is too long, must be {MAX_HRP_LENGTH} characters or less");
assert!(
sapling_hrp.chars().all(|c| c.is_ascii_lowercase() || c == '-'),
"human-readable prefixes should contain only lowercase ASCII characters and dashes, hrp: {sapling_hrp}"
);
assert_eq!(
sapling_hrps
.iter()
.filter(|&&hrp| hrp == sapling_hrp)
.count(),
1,
"Sapling human-readable prefixes must be unique, repeated Sapling HRP: {sapling_hrp}"
);
}

self
}

/// 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 with_activation_heights(
Expand Down Expand Up @@ -166,6 +201,7 @@ impl ParametersBuilder {
// # Correctness
//
// Height(0) must be reserved for the `NetworkUpgrade::Genesis`.
// TODO: Find out if `BeforeOverwinter` must always be active at Height(1), remove it here if it's not required.
self.activation_heights.split_off(&Height(2));
self.activation_heights.extend(activation_heights);

Expand Down Expand Up @@ -220,7 +256,6 @@ impl Default for Parameters {
fn default() -> Self {
Self {
network_name: "Testnet".to_string(),
activation_heights: TESTNET_ACTIVATION_HEIGHTS.iter().cloned().collect(),
..Self::build().finish()
}
}
Expand All @@ -232,11 +267,46 @@ impl Parameters {
ParametersBuilder::default()
}

/// Accepts a [`ConfiguredActivationHeights`].
///
/// Creates an instance of [`Parameters`] with `Regtest` values.
pub fn new_regtest(activation_heights: ConfiguredActivationHeights) -> Self {
Self {
network_name: "Regtest".to_string(),
..Self::build()
.with_sapling_hrps(
zp_constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
)
// Removes default Testnet activation heights if not configured,
// most network upgrades are disabled by default for Regtest in zcashd
.with_activation_heights(activation_heights)
.finish()
}
}

/// Returns true if the instance of [`Parameters`] represents the default public Testnet.
pub fn is_default_testnet(&self) -> bool {
self == &Self::default()
}

/// Returns true if the instance of [`Parameters`] represents Regtest.
pub fn is_regtest(&self) -> bool {
let Self {
network_name,
hrp_sapling_extended_spending_key,
hrp_sapling_extended_full_viewing_key,
hrp_sapling_payment_address,
..
} = Self::new_regtest(ConfiguredActivationHeights::default());

self.network_name == network_name
&& self.hrp_sapling_extended_spending_key == hrp_sapling_extended_spending_key
&& self.hrp_sapling_extended_full_viewing_key == hrp_sapling_extended_full_viewing_key
&& self.hrp_sapling_payment_address == hrp_sapling_payment_address
}

/// Returns the network name
pub fn network_name(&self) -> &str {
&self.network_name
Expand Down
176 changes: 171 additions & 5 deletions zebra-chain/src/parameters/network/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
//! Fixed test vectors for the network consensus parameters.

use zcash_primitives::consensus::{self as zp_consensus, Parameters};
use zcash_primitives::{
consensus::{self as zp_consensus, Parameters},
constants as zp_constants,
};

use crate::{
block::Height,
parameters::{
testnet::{
self, ConfiguredActivationHeights, MAX_NETWORK_NAME_LENGTH, RESERVED_NETWORK_NAMES,
self, ConfiguredActivationHeights, MAX_HRP_LENGTH, MAX_NETWORK_NAME_LENGTH,
RESERVED_NETWORK_NAMES,
},
Network, NetworkUpgrade, NETWORK_UPGRADES_IN_ORDER,
Network, NetworkUpgrade, MAINNET_ACTIVATION_HEIGHTS, NETWORK_UPGRADES_IN_ORDER,
TESTNET_ACTIVATION_HEIGHTS,
},
};

Expand Down Expand Up @@ -93,8 +98,9 @@ fn check_parameters_impl() {
}

/// Checks that `NetworkUpgrade::activation_height()` returns the activation height of the next
/// network upgrade if it doesn't find an activation height for a prior network upgrade, and that the
/// `Genesis` upgrade is always at `Height(0)`.
/// network upgrade if it doesn't find an activation height for a prior network upgrade, that the
/// `Genesis` upgrade is always at `Height(0)`, and that the default Mainnet/Testnet/Regtest activation
/// heights are what's expected.
#[test]
fn activates_network_upgrades_correctly() {
let expected_activation_height = 1;
Expand Down Expand Up @@ -126,6 +132,164 @@ fn activates_network_upgrades_correctly() {
should match NU5 activation height, network_upgrade: {nu}, activation_height: {activation_height:?}"
);
}

let expected_default_regtest_activation_heights = &[
(Height(0), NetworkUpgrade::Genesis),
(Height(1), NetworkUpgrade::BeforeOverwinter),
];

for (network, expected_activation_heights) in [
(Network::Mainnet, MAINNET_ACTIVATION_HEIGHTS),
(Network::new_default_testnet(), TESTNET_ACTIVATION_HEIGHTS),
(
Network::new_regtest(Default::default()),
expected_default_regtest_activation_heights,
),
] {
assert_eq!(
network.activation_list(),
expected_activation_heights.iter().cloned().collect(),
"network activation list should match expected activation heights"
);
}
}

/// Checks that configured testnet names are validated and used correctly.
#[test]
fn check_configured_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().with_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().with_network_name(invalid_network_name)
})
.expect_err("should panic when setting network name that's too long or contains non-alphanumeric characters (except '_')");
}

drop(std::panic::take_hook());

// 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'"
);
assert_eq!(
Network::new_regtest(Default::default()).to_string(),
"Regtest",
"Regtest should be displayed as '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
.with_network_name("a".repeat(MAX_NETWORK_NAME_LENGTH))
.with_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"
);
}

/// Checks that configured Sapling human-readable prefixes (HRPs) are validated and used correctly.
#[test]
fn check_configured_sapling_hrps() {
// Sets a no-op panic hook to avoid long output.
std::panic::set_hook(Box::new(|_| {}));

// Check that configured Sapling HRPs must be unique.
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_sapling_hrps("", "", "");
})
.expect_err("should panic when setting non-unique Sapling HRPs");

// Check that max length is enforced, and that network names may only contain lowecase ASCII characters and dashes.
for invalid_hrp in [
"a".repeat(MAX_NETWORK_NAME_LENGTH + 1),
"!!!!non-alphabetical-name".to_string(),
"A".to_string(),
] {
std::panic::catch_unwind(|| {
testnet::Parameters::build().with_sapling_hrps(invalid_hrp, "dummy-hrp-a", "dummy-hrp-b");
})
.expect_err("should panic when setting Sapling HRPs that are too long or contain non-alphanumeric characters (except '-')");
}

drop(std::panic::take_hook());

// Check that Sapling HRPs can contain lowercase ascii characters and dashes.
let expected_hrp_sapling_extended_spending_key = "sapling-hrp-a";
let expected_hrp_sapling_extended_full_viewing_key = "sapling-hrp-b";
let expected_hrp_sapling_payment_address = "sapling-hrp-c";

let network = testnet::Parameters::build()
// Check that Sapling HRPs can contain `MAX_HRP_LENGTH` characters
.with_sapling_hrps("a".repeat(MAX_HRP_LENGTH), "dummy-hrp-a", "dummy-hrp-b")
.with_sapling_hrps(
expected_hrp_sapling_extended_spending_key,
expected_hrp_sapling_extended_full_viewing_key,
expected_hrp_sapling_payment_address,
)
.to_network();

// Check that configured Sapling HRPs are returned by `Parameters` trait methods
assert_eq!(
network.hrp_sapling_extended_spending_key(),
expected_hrp_sapling_extended_spending_key,
"should return expected Sapling extended spending key HRP"
);
assert_eq!(
network.hrp_sapling_extended_full_viewing_key(),
expected_hrp_sapling_extended_full_viewing_key,
"should return expected Sapling EFVK HRP"
);
assert_eq!(
network.hrp_sapling_payment_address(),
expected_hrp_sapling_payment_address,
"should return expected Sapling payment address HRP"
);

// Check that default Mainnet, Testnet, and Regtest HRPs are valid, these calls will panic
// if any of the values fail validation.
testnet::Parameters::build()
.with_sapling_hrps(
zp_constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS,
)
.with_sapling_hrps(
zp_constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS,
)
.with_sapling_hrps(
zp_constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY,
zp_constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
zp_constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS,
);
}

/// Checks that configured testnet names are validated and used correctly.
Expand Down Expand Up @@ -153,6 +317,8 @@ fn check_network_name() {
.expect_err("should panic when setting network name that's too long or contains non-alphanumeric characters (except '_')");
}

drop(std::panic::take_hook());

// Checks that network names are displayed correctly
assert_eq!(
Network::new_default_testnet().to_string(),
Expand Down
Loading
Loading