feature: Add a "Genesis" network upgrade

We can use this network upgrade to implement different consensus rules
and chain context handling for genesis blocks.

Part of the chain state design in #682.
This commit is contained in:
teor 2020-07-27 17:54:55 +10:00 committed by Deirdre Connolly
parent 5ece62f0a5
commit 993532b604
3 changed files with 34 additions and 18 deletions

View File

@ -8,12 +8,18 @@ use std::ops::Bound::*;
use zebra_chain::types::BlockHeight;
use zebra_chain::{Network, Network::*};
/// A Zcash network protocol upgrade.
//
// TODO: are new network upgrades a breaking change, or should we make this
// enum non-exhaustive?
/// A Zcash network upgrade.
///
/// Network upgrades can change the Zcash network protocol or consensus rules in
/// incompatible ways.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum NetworkUpgrade {
/// The Zcash protocol for a Genesis block.
///
/// Zcash genesis blocks use a different set of consensus rules from
/// other BeforeOverwinter blocks, so we treat them like a separate network
/// upgrade.
Genesis,
/// The Zcash protocol before the Overwinter upgrade.
///
/// We avoid using `Sprout`, because the specification says that Sprout
@ -36,7 +42,8 @@ pub enum NetworkUpgrade {
/// This is actually a bijective map, but it is const, so we use a vector, and
/// do the uniqueness check in the unit tests.
pub(crate) const MAINNET_ACTIVATION_HEIGHTS: &[(BlockHeight, NetworkUpgrade)] = &[
(BlockHeight(0), BeforeOverwinter),
(BlockHeight(0), Genesis),
(BlockHeight(1), BeforeOverwinter),
(BlockHeight(347_500), Overwinter),
(BlockHeight(419_200), Sapling),
(BlockHeight(653_600), Blossom),
@ -49,7 +56,8 @@ pub(crate) const MAINNET_ACTIVATION_HEIGHTS: &[(BlockHeight, NetworkUpgrade)] =
/// This is actually a bijective map, but it is const, so we use a vector, and
/// do the uniqueness check in the unit tests.
pub(crate) const TESTNET_ACTIVATION_HEIGHTS: &[(BlockHeight, NetworkUpgrade)] = &[
(BlockHeight(0), BeforeOverwinter),
(BlockHeight(0), Genesis),
(BlockHeight(1), BeforeOverwinter),
(BlockHeight(207_500), Overwinter),
(BlockHeight(280_000), Sapling),
(BlockHeight(584_000), Blossom),
@ -68,8 +76,8 @@ pub struct ConsensusBranchId(u32);
/// Branch ids are the same for mainnet and testnet. If there is a testnet
/// rollback after a bug, the branch id changes.
///
/// Branch ids were introduced in the Overwinter upgrade, so there is no
/// BeforeOverwinter branch id.
/// Branch ids were introduced in the Overwinter upgrade, so there are no
/// Genesis or BeforeOverwinter branch ids.
///
/// This is actually a bijective map, but it is const, so we use a vector, and
/// do the uniqueness check in the unit tests.

View File

@ -39,21 +39,32 @@ fn activation_extremes_testnet() {
/// Test the activation_list, activation_height, current, and next functions
/// for `network` with extreme values.
fn activation_extremes(network: Network) {
// The first two upgrades are BeforeOverwinter and Overwinter
// The first three upgrades are Genesis, BeforeOverwinter, and Overwinter
assert_eq!(
NetworkUpgrade::activation_list(network).get(&BlockHeight(0)),
Some(&Genesis)
);
assert_eq!(Genesis.activation_height(network), Some(BlockHeight(0)));
assert_eq!(NetworkUpgrade::current(network, BlockHeight(0)), Genesis);
assert_eq!(
NetworkUpgrade::next(network, BlockHeight(0)),
Some(BeforeOverwinter)
);
assert_eq!(
NetworkUpgrade::activation_list(network).get(&BlockHeight(1)),
Some(&BeforeOverwinter)
);
assert_eq!(
BeforeOverwinter.activation_height(network),
Some(BlockHeight(0))
Some(BlockHeight(1))
);
assert_eq!(
NetworkUpgrade::current(network, BlockHeight(0)),
NetworkUpgrade::current(network, BlockHeight(1)),
BeforeOverwinter
);
assert_eq!(
NetworkUpgrade::next(network, BlockHeight(0)),
NetworkUpgrade::next(network, BlockHeight(1)),
Some(Overwinter)
);
@ -61,12 +72,9 @@ fn activation_extremes(network: Network) {
// (even if we suspect that won't be true)
assert_ne!(
NetworkUpgrade::activation_list(network).get(&BlockHeight::MAX),
Some(&BeforeOverwinter)
);
assert_ne!(
NetworkUpgrade::current(network, BlockHeight::MAX),
BeforeOverwinter
Some(&Genesis)
);
assert_ne!(NetworkUpgrade::current(network, BlockHeight::MAX), Genesis);
assert_eq!(NetworkUpgrade::next(network, BlockHeight::MAX), None);
}

View File

@ -43,7 +43,7 @@ impl Version {
// TODO: Should we reject earlier protocol versions during our initial
// sync? zcashd accepts 170_002 or later during its initial sync.
Version(match (network, network_upgrade) {
(_, BeforeOverwinter) => 170_002,
(_, Genesis) | (_, BeforeOverwinter) => 170_002,
(Testnet, Overwinter) => 170_003,
(Mainnet, Overwinter) => 170_005,
(_, Sapling) => 170_007,