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

Network Sustainability Mechanism - ZIP 233 implementation #8930

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
226 changes: 79 additions & 147 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ resolver = "2"
incrementalmerkletree = "0.7.0"
orchard = "0.9.0"
sapling-crypto = "0.2.0"
zcash_address = "0.5.0"
zcash_client_backend = "0.13.0"
zcash_encoding = "0.2.1"
zcash_history = "0.4.0"
zcash_keys = "0.3.0"
zcash_primitives = "0.17.0"
zcash_proofs = "0.17.0"
zcash_protocol = "0.3.0"
# TODO: Revert to a release once librustzcash is released (#8749).
zcash_address = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_client_backend = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_encoding = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_history = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_keys = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_primitives = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_proofs = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }
zcash_protocol = { git = "https://github.com/ShieldedLabs/librustzcash/", branch = "nsm-zebra" }

[workspace.metadata.release]

Expand Down
5 changes: 5 additions & 0 deletions zebra-chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ categories = ["asynchronous", "cryptography::cryptocurrencies", "encoding"]
[features]
default = []

nsm = []

# Production features that activate extra functionality

# Consensus-critical conversion from JSON to Zcash types
Expand Down Expand Up @@ -178,3 +180,6 @@ required-features = ["bench"]
[[bench]]
name = "redpallas"
harness = false

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(zcash_unstable, values("nsm"))'] }
2 changes: 1 addition & 1 deletion zebra-chain/src/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ impl Constraint for NonNegative {
/// -MAX_MONEY..=0,
/// );
/// ```
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Default)]
pub struct NegativeOrZero;

impl Constraint for NegativeOrZero {
Expand Down
4 changes: 4 additions & 0 deletions zebra-chain/src/block/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ impl Commitment {
(Nu5 | Nu6, _) => Ok(ChainHistoryBlockTxAuthCommitment(
ChainHistoryBlockTxAuthCommitmentHash(bytes),
)),
#[cfg(zcash_unstable = "nsm")]
(ZFuture, _) => Ok(ChainHistoryBlockTxAuthCommitment(
ChainHistoryBlockTxAuthCommitmentHash(bytes),
)),
}
}

Expand Down
21 changes: 21 additions & 0 deletions zebra-chain/src/history_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ impl NonEmptyHistoryTree {
)?;
InnerHistoryTree::OrchardOnward(tree)
}
#[cfg(zcash_unstable = "nsm")]
NetworkUpgrade::ZFuture => {
let tree = Tree::<OrchardOnward>::new_from_cache(
network,
network_upgrade,
size,
&peaks,
&Default::default(),
)?;
InnerHistoryTree::OrchardOnward(tree)
}
};
Ok(Self {
network: network.clone(),
Expand Down Expand Up @@ -165,6 +176,16 @@ impl NonEmptyHistoryTree {
)?;
(InnerHistoryTree::OrchardOnward(tree), entry)
}
#[cfg(zcash_unstable = "nsm")]
NetworkUpgrade::ZFuture => {
let (tree, entry) = Tree::<OrchardOnward>::new_from_block(
network,
block,
sapling_root,
orchard_root,
)?;
(InnerHistoryTree::OrchardOnward(tree), entry)
}
};
let mut peaks = BTreeMap::new();
peaks.insert(0u32, entry);
Expand Down
17 changes: 15 additions & 2 deletions zebra-chain/src/parameters/network/testnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ pub struct ConfiguredActivationHeights {
/// Activation height for `NU6` network upgrade.
#[serde(rename = "NU6")]
pub nu6: Option<u32>,
#[cfg(zcash_unstable = "nsm")]
#[serde(rename = "ZFuture")]
pub zfuture: Option<u32>,
}

/// Builder for the [`Parameters`] struct.
Expand Down Expand Up @@ -336,6 +339,8 @@ impl ParametersBuilder {
canopy,
nu5,
nu6,
#[cfg(zcash_unstable = "nsm")]
zfuture,
}: ConfiguredActivationHeights,
) -> Self {
use NetworkUpgrade::*;
Expand All @@ -348,7 +353,7 @@ impl ParametersBuilder {
//
// 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<_, _> = before_overwinter
let activation_heights = before_overwinter
.into_iter()
.map(|h| (h, BeforeOverwinter))
.chain(overwinter.into_iter().map(|h| (h, Overwinter)))
Expand All @@ -357,7 +362,13 @@ impl ParametersBuilder {
.chain(heartwood.into_iter().map(|h| (h, Heartwood)))
.chain(canopy.into_iter().map(|h| (h, Canopy)))
.chain(nu5.into_iter().map(|h| (h, Nu5)))
.chain(nu6.into_iter().map(|h| (h, Nu6)))
.chain(nu6.into_iter().map(|h| (h, Nu6)));

#[cfg(zcash_unstable = "nsm")]
let activation_heights =
activation_heights.chain(zfuture.into_iter().map(|h| (h, ZFuture)));

let activation_heights: BTreeMap<_, _> = activation_heights
.map(|(h, nu)| (h.try_into().expect("activation height must be valid"), nu))
.collect();

Expand Down Expand Up @@ -604,6 +615,8 @@ impl Parameters {
canopy: Some(1),
nu5: nu5_activation_height,
nu6: nu6_activation_height,
#[cfg(zcash_unstable = "nsm")]
zfuture: nu5_activation_height.map(|height| height + 1),
..Default::default()
})
.with_halving_interval(PRE_BLOSSOM_REGTEST_HALVING_INTERVAL);
Expand Down
9 changes: 8 additions & 1 deletion zebra-chain/src/parameters/network/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Fixed test vectors for the network consensus parameters.

use zcash_primitives::consensus::NetworkConstants as _;
use zcash_primitives::consensus::{self as zp_consensus, Parameters};
use zcash_protocol::consensus::NetworkConstants as _;

use crate::{
block::Height,
Expand Down Expand Up @@ -31,6 +31,8 @@ fn check_parameters_impl() {
zp_consensus::NetworkUpgrade::Heartwood,
zp_consensus::NetworkUpgrade::Canopy,
zp_consensus::NetworkUpgrade::Nu5,
#[cfg(zcash_unstable = "nsm")]
zp_consensus::NetworkUpgrade::ZFuture,
];

for (network, zp_network) in [
Expand Down Expand Up @@ -109,7 +111,10 @@ fn activates_network_upgrades_correctly() {
let expected_activation_height = 1;
let network = testnet::Parameters::build()
.with_activation_heights(ConfiguredActivationHeights {
#[cfg(not(zcash_unstable = "nsm"))]
nu6: Some(expected_activation_height),
#[cfg(zcash_unstable = "nsm")]
zfuture: Some(expected_activation_height),
..Default::default()
})
.to_network();
Expand Down Expand Up @@ -141,6 +146,8 @@ fn activates_network_upgrades_correctly() {
(Height(1), NetworkUpgrade::Canopy),
// TODO: Remove this once the testnet parameters are being serialized (#8920).
(Height(100), NetworkUpgrade::Nu5),
#[cfg(zcash_unstable = "nsm")]
(Height(101), NetworkUpgrade::ZFuture),
];

for (network, expected_activation_heights) in [
Expand Down
43 changes: 41 additions & 2 deletions zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use hex::{FromHex, ToHex};
use proptest_derive::Arbitrary;

/// A list of network upgrades in the order that they must be activated.
#[cfg(not(zcash_unstable = "nsm"))]
pub const NETWORK_UPGRADES_IN_ORDER: [NetworkUpgrade; 9] = [
Genesis,
BeforeOverwinter,
Expand All @@ -27,6 +28,21 @@ pub const NETWORK_UPGRADES_IN_ORDER: [NetworkUpgrade; 9] = [
Nu6,
];

#[cfg(zcash_unstable = "nsm")]
pub const NETWORK_UPGRADES_IN_ORDER: [NetworkUpgrade; 10] = [
Genesis,
BeforeOverwinter,
Overwinter,
Sapling,
Blossom,
Heartwood,
Canopy,
Nu5,
Nu6,
#[cfg(zcash_unstable = "nsm")]
ZFuture,
];

/// A Zcash network upgrade.
///
/// Network upgrades change the Zcash network protocol or consensus rules. Note that they have no
Expand Down Expand Up @@ -61,6 +77,10 @@ pub enum NetworkUpgrade {
/// The Zcash protocol after the NU6 upgrade.
#[serde(rename = "NU6")]
Nu6,
#[cfg(zcash_unstable = "nsm")]
#[serde(rename = "ZFuture")]
#[allow(non_snake_case)]
ZFuture,
}

impl fmt::Display for NetworkUpgrade {
Expand Down Expand Up @@ -89,8 +109,10 @@ pub(super) const MAINNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)]
(block::Height(903_000), Heartwood),
(block::Height(1_046_400), Canopy),
(block::Height(1_687_104), Nu5),
// TODO: Add NU6
// (block::Height(2_726_400), Nu6),
// TODO: Update NU6 activation height once it's been specified.
(block::Height(2_820_000), Nu6),
#[cfg(zcash_unstable = "nsm")]
(block::Height(3_000_000), ZFuture),
];

/// Fake mainnet network upgrade activation heights, used in tests.
Expand All @@ -105,6 +127,8 @@ const FAKE_MAINNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)] = &[
(block::Height(30), Canopy),
(block::Height(35), Nu5),
(block::Height(40), Nu6),
#[cfg(zcash_unstable = "nsm")]
(block::Height(45), ZFuture),
];

/// Testnet network upgrade activation heights.
Expand All @@ -127,6 +151,8 @@ pub(super) const TESTNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)]
(block::Height(1_028_500), Canopy),
(block::Height(1_842_420), Nu5),
(block::Height(2_976_000), Nu6),
#[cfg(zcash_unstable = "nsm")]
(block::Height(3_000_000), ZFuture),
];

/// Fake testnet network upgrade activation heights, used in tests.
Expand All @@ -141,6 +167,8 @@ const FAKE_TESTNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)] = &[
(block::Height(30), Canopy),
(block::Height(35), Nu5),
(block::Height(40), Nu6),
#[cfg(zcash_unstable = "nsm")]
(block::Height(45), ZFuture),
];

/// The Consensus Branch Id, used to bind transactions and blocks to a
Expand Down Expand Up @@ -217,6 +245,8 @@ pub(crate) const CONSENSUS_BRANCH_IDS: &[(NetworkUpgrade, ConsensusBranchId)] =
(Canopy, ConsensusBranchId(0xe9ff75a6)),
(Nu5, ConsensusBranchId(0xc2d6d0b4)),
(Nu6, ConsensusBranchId(0xc8e71055)),
#[cfg(zcash_unstable = "nsm")]
(ZFuture, ConsensusBranchId(0xffff_ffff)),
];

/// The target block spacing before Blossom.
Expand Down Expand Up @@ -333,7 +363,12 @@ impl NetworkUpgrade {
Heartwood => Some(Canopy),
Canopy => Some(Nu5),
Nu5 => Some(Nu6),
#[cfg(not(zcash_unstable = "nsm"))]
Nu6 => None,
#[cfg(zcash_unstable = "nsm")]
Nu6 => Some(ZFuture),
#[cfg(zcash_unstable = "nsm")]
ZFuture => None,
}
}

Expand Down Expand Up @@ -411,6 +446,8 @@ impl NetworkUpgrade {
let spacing_seconds = match self {
Genesis | BeforeOverwinter | Overwinter | Sapling => PRE_BLOSSOM_POW_TARGET_SPACING,
Blossom | Heartwood | Canopy | Nu5 | Nu6 => POST_BLOSSOM_POW_TARGET_SPACING.into(),
#[cfg(zcash_unstable = "nsm")]
ZFuture => POST_BLOSSOM_POW_TARGET_SPACING.into(),
};

Duration::seconds(spacing_seconds)
Expand Down Expand Up @@ -532,6 +569,8 @@ impl From<zcash_protocol::consensus::NetworkUpgrade> for NetworkUpgrade {
zcash_protocol::consensus::NetworkUpgrade::Canopy => Self::Canopy,
zcash_protocol::consensus::NetworkUpgrade::Nu5 => Self::Nu5,
zcash_protocol::consensus::NetworkUpgrade::Nu6 => Self::Nu6,
#[cfg(zcash_unstable = "nsm")]
zcash_protocol::consensus::NetworkUpgrade::ZFuture => Self::ZFuture,
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions zebra-chain/src/parameters/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ pub const SAPLING_VERSION_GROUP_ID: u32 = 0x892F_2085;
/// Orchard transactions must use transaction version 5 and this version
/// group ID. Sapling transactions can use v4 or v5 transactions.
pub const TX_V5_VERSION_GROUP_ID: u32 = 0x26A7_270A;

/// The version group ID for version ZFUTURE transactions.
#[cfg(zcash_unstable = "nsm")]
pub const TX_ZFUTURE_VERSION_GROUP_ID: u32 =
zcash_primitives::transaction::ZFUTURE_VERSION_GROUP_ID;
15 changes: 15 additions & 0 deletions zebra-chain/src/primitives/zcash_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,21 @@ impl Version for zcash_history::V1 {
end_height: height.0 as u64,
sapling_tx: sapling_tx_count,
},
#[cfg(zcash_unstable = "nsm")]
NetworkUpgrade::ZFuture => zcash_history::NodeData {
consensus_branch_id: branch_id.into(),
subtree_commitment: block_hash,
start_time: time,
end_time: time,
start_target: target,
end_target: target,
start_sapling_root: sapling_root,
end_sapling_root: sapling_root,
subtree_total_work: work,
start_height: height.0 as u64,
end_height: height.0 as u64,
sapling_tx: sapling_tx_count,
},
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions zebra-chain/src/primitives/zcash_primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ impl TryFrom<&Transaction> for zp_tx::Transaction {
Transaction::V5 {
network_upgrade, ..
} => network_upgrade,
#[cfg(zcash_unstable = "nsm")]
Transaction::ZFuture {
network_upgrade, ..
} => network_upgrade,
Transaction::V1 { .. }
| Transaction::V2 { .. }
| Transaction::V3 { .. }
Expand Down
Loading
Loading