feature: Get the current minimum protocol version
This commit is contained in:
parent
0e0c36c010
commit
da09965a5f
|
@ -199,12 +199,12 @@ where
|
||||||
// For example, we could reject old peers with probability 0.5.
|
// For example, we could reject old peers with probability 0.5.
|
||||||
//
|
//
|
||||||
// At the network upgrade, we also need to disconnect from old peers.
|
// At the network upgrade, we also need to disconnect from old peers.
|
||||||
// TODO: replace MIN_NETWORK_UPGRADE with
|
// TODO: replace min_for_upgrade(network, MIN_NETWORK_UPGRADE) with
|
||||||
// NetworkUpgrade::current(network, height) where network is
|
// current_min(network, height) where network is the
|
||||||
// the configured network, and height is the best tip's block
|
// configured network, and height is the best tip's block
|
||||||
// height.
|
// height.
|
||||||
|
|
||||||
if remote_version < Version::min_version(network, constants::MIN_NETWORK_UPGRADE) {
|
if remote_version < Version::min_for_upgrade(network, constants::MIN_NETWORK_UPGRADE) {
|
||||||
// Disconnect if peer is using an obsolete version.
|
// Disconnect if peer is using an obsolete version.
|
||||||
return Err(HandshakeError::ObsoleteVersion(remote_version));
|
return Err(HandshakeError::ObsoleteVersion(remote_version));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::constants::magics;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use zebra_chain::types::BlockHeight;
|
||||||
use zebra_chain::Network::{self, *};
|
use zebra_chain::Network::{self, *};
|
||||||
use zebra_consensus::parameters::NetworkUpgrade::{self, *};
|
use zebra_consensus::parameters::NetworkUpgrade::{self, *};
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ pub struct Version(pub u32);
|
||||||
impl Version {
|
impl Version {
|
||||||
/// Returns the minimum network protocol version for `network` and
|
/// Returns the minimum network protocol version for `network` and
|
||||||
/// `network_upgrade`.
|
/// `network_upgrade`.
|
||||||
pub fn min_version(network: Network, network_upgrade: NetworkUpgrade) -> Self {
|
pub fn min_for_upgrade(network: Network, network_upgrade: NetworkUpgrade) -> Self {
|
||||||
// TODO: Should we reject earlier protocol versions during our initial
|
// TODO: Should we reject earlier protocol versions during our initial
|
||||||
// sync? zcashd accepts 170_002 or later during its initial sync.
|
// sync? zcashd accepts 170_002 or later during its initial sync.
|
||||||
Version(match (network, network_upgrade) {
|
Version(match (network, network_upgrade) {
|
||||||
|
@ -54,6 +55,14 @@ impl Version {
|
||||||
(Mainnet, Canopy) => 170_013,
|
(Mainnet, Canopy) => 170_013,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the current minimum protocol version for `network` and `height`.
|
||||||
|
///
|
||||||
|
/// Returns None if the network has no branch id at this height.
|
||||||
|
pub fn current_min(network: Network, height: BlockHeight) -> Version {
|
||||||
|
let network_upgrade = NetworkUpgrade::current(network, height);
|
||||||
|
Version::min_for_upgrade(network, network_upgrade)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
@ -120,3 +129,69 @@ mod proptest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn version_extremes_mainnet() {
|
||||||
|
version_extremes(Mainnet)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn version_extremes_testnet() {
|
||||||
|
version_extremes(Testnet)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test the min_for_upgrade and current_min functions for `network` with
|
||||||
|
/// extreme values.
|
||||||
|
fn version_extremes(network: Network) {
|
||||||
|
assert_eq!(
|
||||||
|
Version::current_min(network, BlockHeight(0)),
|
||||||
|
Version::min_for_upgrade(network, BeforeOverwinter),
|
||||||
|
);
|
||||||
|
|
||||||
|
// We assume that the last version we know about continues forever
|
||||||
|
// (even if we suspect that won't be true)
|
||||||
|
assert_ne!(
|
||||||
|
Version::current_min(network, BlockHeight::MAX),
|
||||||
|
Version::min_for_upgrade(network, BeforeOverwinter),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn version_consistent_mainnet() {
|
||||||
|
version_consistent(Mainnet)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn version_consistent_testnet() {
|
||||||
|
version_consistent(Testnet)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that the min_for_upgrade and current_min functions
|
||||||
|
/// are consistent for `network`.
|
||||||
|
fn version_consistent(network: Network) {
|
||||||
|
let highest_network_upgrade = NetworkUpgrade::current(network, BlockHeight::MAX);
|
||||||
|
assert!(highest_network_upgrade == Canopy || highest_network_upgrade == Heartwood,
|
||||||
|
"expected coverage of all network upgrades: add the new network upgrade to the list in this test");
|
||||||
|
|
||||||
|
for &network_upgrade in &[
|
||||||
|
BeforeOverwinter,
|
||||||
|
Overwinter,
|
||||||
|
Sapling,
|
||||||
|
Blossom,
|
||||||
|
Heartwood,
|
||||||
|
Canopy,
|
||||||
|
] {
|
||||||
|
let height = network_upgrade.activation_height(network);
|
||||||
|
if let Some(height) = height {
|
||||||
|
assert_eq!(
|
||||||
|
Version::min_for_upgrade(network, network_upgrade),
|
||||||
|
Version::current_min(network, height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue