zebra_network/protocol/external/
types.rs1use std::{cmp::max, fmt};
2
3use zebra_chain::{
4 block,
5 parameters::{
6 Network::{self, *},
7 NetworkUpgrade::{self, *},
8 },
9};
10
11use crate::constants::{self, CURRENT_NETWORK_PROTOCOL_VERSION};
12
13#[cfg(any(test, feature = "proptest-impl"))]
14use proptest_derive::Arbitrary;
15
16#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
18pub struct Version(pub u32);
19
20impl fmt::Display for Version {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 f.write_str(&self.0.to_string())
23 }
24}
25
26impl Version {
27 pub fn min_remote_for_height(
34 network: &Network,
35 height: impl Into<Option<block::Height>>,
36 ) -> Version {
37 let height = height.into().unwrap_or(block::Height(0));
38 let min_spec = Version::min_specified_for_height(network, height);
39
40 assert!(
42 constants::CURRENT_NETWORK_PROTOCOL_VERSION >= min_spec,
43 "Zebra does not implement the minimum specified {:?} protocol version for {:?} at {:?}",
44 NetworkUpgrade::current(network, height),
45 network,
46 height,
47 );
48
49 max(min_spec, Version::initial_min_for_network(network))
50 }
51
52 fn initial_min_for_network(network: &Network) -> Version {
59 *constants::INITIAL_MIN_NETWORK_PROTOCOL_VERSION
60 .get(&network.kind())
61 .expect("We always have a value for testnet or mainnet")
62 }
63
64 fn min_specified_for_height(network: &Network, height: block::Height) -> Version {
69 let network_upgrade = NetworkUpgrade::current(network, height);
70 Version::min_specified_for_upgrade(network, network_upgrade)
71 }
72
73 pub(crate) fn min_specified_for_upgrade(
89 network: &Network,
90 network_upgrade: NetworkUpgrade,
91 ) -> Version {
92 Version(match (network, network_upgrade) {
93 (_, Genesis) | (_, BeforeOverwinter) => 170_002,
94 (Testnet(params), Overwinter) if params.is_default_testnet() => 170_003,
95 (Mainnet, Overwinter) => 170_005,
96 (Testnet(params), Sapling) if params.is_default_testnet() => 170_007,
97 (Testnet(params), Sapling) if params.is_regtest() => 170_006,
98 (Mainnet, Sapling) => 170_007,
99 (Testnet(params), Blossom) if params.is_default_testnet() || params.is_regtest() => {
100 170_008
101 }
102 (Mainnet, Blossom) => 170_009,
103 (Testnet(params), Heartwood) if params.is_default_testnet() || params.is_regtest() => {
104 170_010
105 }
106 (Mainnet, Heartwood) => 170_011,
107 (Testnet(params), Canopy) if params.is_default_testnet() || params.is_regtest() => {
108 170_012
109 }
110 (Mainnet, Canopy) => 170_013,
111 (Testnet(params), Nu5) if params.is_default_testnet() || params.is_regtest() => 170_050,
112 (Mainnet, Nu5) => 170_100,
113 (Testnet(params), Nu6) if params.is_default_testnet() || params.is_regtest() => 170_110,
114 (Mainnet, Nu6) => 170_120,
115 (Testnet(params), Nu6_1) if params.is_default_testnet() || params.is_regtest() => {
116 170_130
117 }
118 (Mainnet, Nu6_1) => 170_140,
119 (Testnet(params), Nu7) if params.is_default_testnet() || params.is_regtest() => 170_150,
120 (Mainnet, Nu7) => 170_160,
121
122 (Testnet(_), _) => CURRENT_NETWORK_PROTOCOL_VERSION.0,
124
125 #[cfg(zcash_unstable = "zfuture")]
126 (Mainnet, ZFuture) => {
127 panic!("ZFuture network upgrade should not be active on Mainnet")
128 }
129 })
130 }
131}
132
133bitflags! {
134 #[derive(Copy, Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
139 pub struct PeerServices: u64 {
140 const NODE_NETWORK = 1;
144 }
145}
146
147#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
149#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
150pub struct Nonce(pub u64);
151
152impl Default for Nonce {
153 fn default() -> Self {
154 use rand::{thread_rng, Rng};
155 Self(thread_rng().gen())
156 }
157}
158
159#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
161#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
162pub struct Tweak(pub u32);
163
164impl Default for Tweak {
165 fn default() -> Self {
166 use rand::{thread_rng, Rng};
167 Self(thread_rng().gen())
168 }
169}
170
171#[derive(Clone, Debug, Eq, PartialEq)]
174#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
175pub struct Filter(pub Vec<u8>);
176
177#[cfg(test)]
178mod test {
179 use super::*;
180
181 #[test]
182 fn version_extremes_mainnet() {
183 version_extremes(&Mainnet)
184 }
185
186 #[test]
187 fn version_extremes_testnet() {
188 version_extremes(&Network::new_default_testnet())
189 }
190
191 fn version_extremes(network: &Network) {
194 let _init_guard = zebra_test::init();
195
196 assert_eq!(
197 Version::min_specified_for_height(network, block::Height(0)),
198 Version::min_specified_for_upgrade(network, BeforeOverwinter),
199 );
200
201 assert_ne!(
204 Version::min_specified_for_height(network, block::Height::MAX),
205 Version::min_specified_for_upgrade(network, BeforeOverwinter),
206 );
207 }
208
209 #[test]
210 fn version_consistent_mainnet() {
211 version_consistent(&Mainnet)
212 }
213
214 #[test]
215 fn version_consistent_testnet() {
216 version_consistent(&Network::new_default_testnet())
217 }
218
219 fn version_consistent(network: &Network) {
222 let _init_guard = zebra_test::init();
223
224 let highest_network_upgrade = NetworkUpgrade::current(network, block::Height::MAX);
225 assert!(
226 matches!(highest_network_upgrade, Nu6 | Nu6_1 | Nu7),
227 "expected coverage of all network upgrades: \
228 add the new network upgrade to the list in this test"
229 );
230
231 for &network_upgrade in &[
232 BeforeOverwinter,
233 Overwinter,
234 Sapling,
235 Blossom,
236 Heartwood,
237 Canopy,
238 Nu5,
239 Nu6,
240 Nu6_1,
241 Nu7,
242 ] {
243 let height = network_upgrade.activation_height(network);
244 if let Some(height) = height {
245 assert_eq!(
246 Version::min_specified_for_upgrade(network, network_upgrade),
247 Version::min_specified_for_height(network, height)
248 );
249 }
250 }
251 }
252}