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

change(consensus): Refactor production code for network consensus rules to Network methods #8340

Merged
merged 24 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cf70754
begin refactor suggested as "step 2": https://github.com/ZcashFoundat…
AloeareV Feb 22, 2024
72fe76c
break out more little traits
AloeareV Feb 22, 2024
2c5dcbf
add activation implementation leveraging From<Network> for lrz::cons::
zancas Feb 23, 2024
ad8530d
for transfer of ownership I cannot return a type that's owned by the …
zancas Feb 23, 2024
a43134a
hrp_sapling_extended_full_viewing_key
zancas Feb 23, 2024
950a3b6
complete implementation of interface of Parameters on Network reuse P…
zancas Feb 23, 2024
74770c6
move doc-comments to trait declarations (from impls)
zancas Feb 23, 2024
e6d874b
Simplify/complete Parameters impl for Network
AloeareV Feb 29, 2024
aee311d
Add checkpoint_list method, move documentation, etc
AloeareV Feb 29, 2024
78d028d
Merge branch 'main' into method_per_rule_smaller_traits
AloeareV Mar 4, 2024
f561645
move last match network to inside network method
AloeareV Mar 4, 2024
afc09f3
add back comment
AloeareV Mar 4, 2024
72f26c6
use zcash_address for parameter types in zebra-chain
AloeareV Mar 5, 2024
cc4dda4
use inherent methods instead of big parameters passthrough
AloeareV Mar 5, 2024
617138b
Merge branch 'main' into method_per_rule
zancas Mar 5, 2024
1da36d7
revert to implementation of From on zcash_primitives::..::Network vs …
zancas Mar 5, 2024
9132e38
move match
AloeareV Mar 6, 2024
946ff14
add test to block maximum time rule
AloeareV Mar 6, 2024
602fa5c
update changelog
AloeareV Mar 7, 2024
94127dc
finish porting target_difficutly_limit
AloeareV Mar 12, 2024
fa68a73
remove obscelete code comment
AloeareV Mar 12, 2024
ab9f326
revert non-functional change
AloeareV Mar 12, 2024
d2ec3b5
finish migrating target_difficulty_limit, checkpoint_list
AloeareV Mar 12, 2024
dce8137
update changelog
AloeareV Mar 12, 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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to Zebra are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org).

## Unreleased

### Added
- `zebra_chain::Network` methods:
- `b58_pubkey_address_prefix`, `b58_script_address_prefix`, `num_funding_streams`

### Changed
- Functions that take a `zebra_chain::Network` as an argument have been moved to be methods of `Network`, including
- `zebra_chain::parameters`:
- `genesis::genesis_hash`, `NetworkUpgrade::activation_list`, `NetworkUpgrade::is_max_block_time_enforced`,
- `zebra_chain::work::difficulty::ExpandedDifficulty::target_difficutly_limit`
- `zebra_consensus::height_for_first_halving`
- `zebra_consensus::checkpoint::CheckpointList::new` (now `Network::checkpoint_list`)

## [Zebra 1.6.0](https://github.com/ZcashFoundation/zebra/releases/tag/v1.6.0) - 2024-02-23

This release exposes the shielded scanning functionality through an initial
Expand Down
4 changes: 1 addition & 3 deletions zebra-chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ async-error = [

# Mining RPC support
getblocktemplate-rpcs = [
"zcash_address",
]

# Experimental shielded scanning support
Expand Down Expand Up @@ -132,8 +131,7 @@ serde_json = { version = "1.0.113", optional = true }
# Production feature async-error and testing feature proptest-impl
tokio = { version = "1.36.0", optional = true }

# Production feature getblocktemplate-rpcs
zcash_address = { version = "0.3.1", optional = true }
zcash_address = { version = "0.3.1" }
arya2 marked this conversation as resolved.
Show resolved Hide resolved

# Experimental feature shielded-scan
zcash_client_backend = { version = "0.10.0-rc.1", optional = true }
Expand Down
16 changes: 1 addition & 15 deletions zebra-chain/src/parameters/genesis.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
//! Genesis consensus parameters for each Zcash network.

use crate::{block, parameters::Network};

/// The previous block hash for the genesis block.
///
/// All known networks use the Bitcoin `null` value for the parent of the
/// genesis block. (In Bitcoin, `null` is `[0; 32]`.)
pub const GENESIS_PREVIOUS_BLOCK_HASH: block::Hash = block::Hash([0; 32]);

/// Returns the hash for the genesis block in `network`.
pub fn genesis_hash(network: Network) -> block::Hash {
match network {
// zcash-cli getblockhash 0
Network::Mainnet => "00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08",
// zcash-cli -testnet getblockhash 0
Network::Testnet => "05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38",
}
.parse()
.expect("hard-coded hash parses")
}
pub const GENESIS_PREVIOUS_BLOCK_HASH: crate::block::Hash = crate::block::Hash([0; 32]);
31 changes: 30 additions & 1 deletion zebra-chain/src/parameters/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{fmt, str::FromStr};
use thiserror::Error;

use crate::{
block::{Height, HeightDiff},
block::{self, Height, HeightDiff},
parameters::NetworkUpgrade::Canopy,
};

Expand Down Expand Up @@ -63,6 +63,35 @@ pub enum Network {
Testnet,
}

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()
}

/// 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()
}
/// Returns true if the maximum block time rule is active for `network` and `height`.
///
/// Always returns true if `network` is the Mainnet.
/// If `network` is the Testnet, the `height` should be at least
/// TESTNET_MAX_TIME_START_HEIGHT to return true.
/// Returns false otherwise.
///
/// Part of the consensus rules at <https://zips.z.cash/protocol/protocol.pdf#blockheader>
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,
}
}
}

impl From<Network> for &'static str {
fn from(network: Network) -> &'static str {
match network {
Expand Down
17 changes: 16 additions & 1 deletion zebra-chain/src/parameters/network/tests/prop.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use proptest::prelude::*;

use super::super::{Network, ZIP_212_GRACE_PERIOD_DURATION};
use crate::parameters::NetworkUpgrade;
use crate::{
block::Height,
parameters::{NetworkUpgrade, TESTNET_MAX_TIME_START_HEIGHT},
};

proptest! {
/// Check that the mandatory checkpoint is after the ZIP-212 grace period.
Expand All @@ -23,4 +26,16 @@ proptest! {

assert!(network.mandatory_checkpoint_height() >= grace_period_end_height);
}

#[test]
/// Asserts that the activation height is correct for the block
/// maximum time rule on Testnet is correct.
fn max_block_times_correct_enforcement(height in any::<Height>()) {
let _init_guard = zebra_test::init();

assert!(Network::Mainnet.is_max_block_time_enforced(height));
assert_eq!(Network::Testnet.is_max_block_time_enforced(height), TESTNET_MAX_TIME_START_HEIGHT <= height);


}
arya2 marked this conversation as resolved.
Show resolved Hide resolved
}
34 changes: 12 additions & 22 deletions zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ const TESTNET_MINIMUM_DIFFICULTY_START_HEIGHT: block::Height = block::Height(299
/// <https://zips.z.cash/protocol/protocol.pdf#blockheader>
pub const TESTNET_MAX_TIME_START_HEIGHT: block::Height = block::Height(653_606);

impl NetworkUpgrade {
impl Network {
/// Returns a map between activation heights and network upgrades for `network`,
/// in ascending height order.
///
Expand All @@ -241,7 +241,7 @@ impl NetworkUpgrade {
/// When the environment variable TEST_FAKE_ACTIVATION_HEIGHTS is set
/// and it's a test build, this returns a list of fake activation heights
/// used by some tests.
pub fn activation_list(network: Network) -> BTreeMap<block::Height, NetworkUpgrade> {
pub fn activation_list(&self) -> BTreeMap<block::Height, NetworkUpgrade> {
let (mainnet_heights, testnet_heights) = {
#[cfg(not(feature = "zebra-test"))]
{
Expand Down Expand Up @@ -269,18 +269,20 @@ impl NetworkUpgrade {
(MAINNET_ACTIVATION_HEIGHTS, TESTNET_ACTIVATION_HEIGHTS)
}
};
match network {
match self {
Mainnet => mainnet_heights,
Testnet => testnet_heights,
}
.iter()
.cloned()
.collect()
}

}
impl NetworkUpgrade {
/// Returns the current network upgrade for `network` and `height`.
pub fn current(network: Network, height: block::Height) -> NetworkUpgrade {
NetworkUpgrade::activation_list(network)
network
.activation_list()
.range(..=height)
.map(|(_, nu)| *nu)
.next_back()
Expand All @@ -292,7 +294,8 @@ impl NetworkUpgrade {
/// Returns None if the next upgrade has not been implemented in Zebra
/// yet.
pub fn next(network: Network, height: block::Height) -> Option<NetworkUpgrade> {
NetworkUpgrade::activation_list(network)
network
.activation_list()
.range((Excluded(height), Unbounded))
.map(|(_, nu)| *nu)
.next()
Expand All @@ -303,7 +306,8 @@ impl NetworkUpgrade {
/// Returns None if this network upgrade is a future upgrade, and its
/// activation height has not been set yet.
pub fn activation_height(&self, network: Network) -> Option<block::Height> {
NetworkUpgrade::activation_list(network)
network
.activation_list()
.iter()
.filter(|(_, nu)| nu == &self)
.map(|(height, _)| *height)
Expand All @@ -316,7 +320,7 @@ impl NetworkUpgrade {
/// Use [`NetworkUpgrade::activation_height`] to get the specific network
/// upgrade.
pub fn is_activation_height(network: Network, height: block::Height) -> bool {
NetworkUpgrade::activation_list(network).contains_key(&height)
network.activation_list().contains_key(&height)
}

/// Returns an unordered mapping between NetworkUpgrades and their ConsensusBranchIds.
Expand Down Expand Up @@ -445,20 +449,6 @@ impl NetworkUpgrade {
NetworkUpgrade::current(network, height).averaging_window_timespan()
}

/// Returns true if the maximum block time rule is active for `network` and `height`.
///
/// Always returns true if `network` is the Mainnet.
/// If `network` is the Testnet, the `height` should be at least
/// TESTNET_MAX_TIME_START_HEIGHT to return true.
/// Returns false otherwise.
///
/// Part of the consensus rules at <https://zips.z.cash/protocol/protocol.pdf#blockheader>
pub fn is_max_block_time_enforced(network: Network, height: block::Height) -> bool {
match network {
Network::Mainnet => true,
Network::Testnet => height >= TESTNET_MAX_TIME_START_HEIGHT,
}
}
/// Returns the NetworkUpgrade given an u32 as ConsensusBranchId
pub fn from_branch_id(branch_id: u32) -> Option<NetworkUpgrade> {
CONSENSUS_BRANCH_IDS
Expand Down
12 changes: 6 additions & 6 deletions zebra-chain/src/parameters/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ use NetworkUpgrade::*;
fn activation_bijective() {
let _init_guard = zebra_test::init();

let mainnet_activations = NetworkUpgrade::activation_list(Mainnet);
let mainnet_activations = Mainnet.activation_list();
let mainnet_heights: HashSet<&block::Height> = mainnet_activations.keys().collect();
assert_eq!(MAINNET_ACTIVATION_HEIGHTS.len(), mainnet_heights.len());

let mainnet_nus: HashSet<&NetworkUpgrade> = mainnet_activations.values().collect();
assert_eq!(MAINNET_ACTIVATION_HEIGHTS.len(), mainnet_nus.len());

let testnet_activations = NetworkUpgrade::activation_list(Testnet);
let testnet_activations = Testnet.activation_list();
let testnet_heights: HashSet<&block::Height> = testnet_activations.keys().collect();
assert_eq!(TESTNET_ACTIVATION_HEIGHTS.len(), testnet_heights.len());

Expand All @@ -46,7 +46,7 @@ fn activation_extremes_testnet() {
fn activation_extremes(network: Network) {
// The first three upgrades are Genesis, BeforeOverwinter, and Overwinter
assert_eq!(
NetworkUpgrade::activation_list(network).get(&block::Height(0)),
network.activation_list().get(&block::Height(0)),
Some(&Genesis)
);
assert_eq!(Genesis.activation_height(network), Some(block::Height(0)));
Expand All @@ -62,7 +62,7 @@ fn activation_extremes(network: Network) {
);

assert_eq!(
NetworkUpgrade::activation_list(network).get(&block::Height(1)),
network.activation_list().get(&block::Height(1)),
Some(&BeforeOverwinter)
);
assert_eq!(
Expand Down Expand Up @@ -91,7 +91,7 @@ fn activation_extremes(network: Network) {
// We assume that the last upgrade we know about continues forever
// (even if we suspect that won't be true)
assert_ne!(
NetworkUpgrade::activation_list(network).get(&block::Height::MAX),
network.activation_list().get(&block::Height::MAX),
Some(&Genesis)
);
assert!(!NetworkUpgrade::is_activation_height(
Expand Down Expand Up @@ -121,7 +121,7 @@ fn activation_consistent_testnet() {
/// Check that the `activation_height`, `is_activation_height`,
/// `current`, and `next` functions are consistent for `network`.
fn activation_consistent(network: Network) {
let activation_list = NetworkUpgrade::activation_list(network);
let activation_list = network.activation_list();
let network_upgrades: HashSet<&NetworkUpgrade> = activation_list.values().collect();

for &network_upgrade in network_upgrades {
Expand Down
24 changes: 6 additions & 18 deletions zebra-chain/src/primitives/zcash_note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,12 @@ pub fn decrypts_successfully(transaction: &Transaction, network: Network, height

if let Some(bundle) = alt_tx.sapling_bundle() {
for output in bundle.shielded_outputs().iter() {
let recovery = match network {
Network::Mainnet => {
zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&zcash_primitives::consensus::MAIN_NETWORK,
alt_height,
&null_sapling_ovk,
output,
)
}
Network::Testnet => {
zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&zcash_primitives::consensus::TEST_NETWORK,
alt_height,
&null_sapling_ovk,
output,
)
}
};
let recovery = zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
&<zcash_primitives::consensus::Network>::from(network),
alt_height,
&null_sapling_ovk,
output,
);
if recovery.is_none() {
return false;
}
Expand Down
Loading
Loading