zcash_protocol/
local_consensus.rs

1use crate::consensus::{BlockHeight, NetworkType, NetworkUpgrade, Parameters};
2
3/// a `LocalNetwork` setup should define the activation heights
4/// of network upgrades. `None` is considered as "not activated"
5/// These heights are not validated. Callers shall initialized
6/// them according to the settings used on the Full Nodes they
7/// are connecting to.
8///
9/// Example:
10///     Regtest Zcashd using the following `zcash.conf`
11///     ```
12///     ## NUPARAMS
13///     nuparams=5ba81b19:1 # Overwinter
14///     nuparams=76b809bb:1 # Sapling
15///     nuparams=2bb40e60:1 # Blossom
16///     nuparams=f5b9230b:1 # Heartwood
17///     nuparams=e9ff75a6:1 # Canopy
18///     nuparams=c2d6d0b4:1 # NU5
19///     nuparams=c8e71055:1 # NU6
20///     ```
21///     would use the following `LocalNetwork` struct
22///     ```
23///     let regtest = LocalNetwork {
24///         overwinter: Some(BlockHeight::from_u32(1)),
25///         sapling: Some(BlockHeight::from_u32(1)),
26///         blossom: Some(BlockHeight::from_u32(1)),
27///         heartwood: Some(BlockHeight::from_u32(1)),
28///         canopy: Some(BlockHeight::from_u32(1)),
29///         nu5: Some(BlockHeight::from_u32(1)),
30///         nu6: Some(BlockHeight::from_u32(1)),
31///     };
32///     ```
33///     
34#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)]
35pub struct LocalNetwork {
36    pub overwinter: Option<BlockHeight>,
37    pub sapling: Option<BlockHeight>,
38    pub blossom: Option<BlockHeight>,
39    pub heartwood: Option<BlockHeight>,
40    pub canopy: Option<BlockHeight>,
41    pub nu5: Option<BlockHeight>,
42    pub nu6: Option<BlockHeight>,
43    #[cfg(zcash_unstable = "nu7")]
44    pub nu7: Option<BlockHeight>,
45    #[cfg(zcash_unstable = "zfuture")]
46    pub z_future: Option<BlockHeight>,
47}
48
49/// Parameters implementation for `LocalNetwork`
50impl Parameters for LocalNetwork {
51    fn network_type(&self) -> NetworkType {
52        NetworkType::Regtest
53    }
54
55    fn activation_height(&self, nu: NetworkUpgrade) -> Option<BlockHeight> {
56        match nu {
57            NetworkUpgrade::Overwinter => self.overwinter,
58            NetworkUpgrade::Sapling => self.sapling,
59            NetworkUpgrade::Blossom => self.blossom,
60            NetworkUpgrade::Heartwood => self.heartwood,
61            NetworkUpgrade::Canopy => self.canopy,
62            NetworkUpgrade::Nu5 => self.nu5,
63            NetworkUpgrade::Nu6 => self.nu6,
64            #[cfg(zcash_unstable = "nu7")]
65            NetworkUpgrade::Nu7 => self.nu7,
66            #[cfg(zcash_unstable = "zfuture")]
67            NetworkUpgrade::ZFuture => self.z_future,
68        }
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use crate::{
75        consensus::{BlockHeight, NetworkConstants, NetworkUpgrade, Parameters},
76        constants,
77        local_consensus::LocalNetwork,
78    };
79
80    #[test]
81    fn regtest_nu_activation() {
82        let expected_overwinter = BlockHeight::from_u32(1);
83        let expected_sapling = BlockHeight::from_u32(2);
84        let expected_blossom = BlockHeight::from_u32(3);
85        let expected_heartwood = BlockHeight::from_u32(4);
86        let expected_canopy = BlockHeight::from_u32(5);
87        let expected_nu5 = BlockHeight::from_u32(6);
88        let expected_nu6 = BlockHeight::from_u32(7);
89        #[cfg(zcash_unstable = "nu7")]
90        let expected_nu7 = BlockHeight::from_u32(8);
91        #[cfg(zcash_unstable = "zfuture")]
92        let expected_z_future = BlockHeight::from_u32(8);
93
94        let regtest = LocalNetwork {
95            overwinter: Some(expected_overwinter),
96            sapling: Some(expected_sapling),
97            blossom: Some(expected_blossom),
98            heartwood: Some(expected_heartwood),
99            canopy: Some(expected_canopy),
100            nu5: Some(expected_nu5),
101            nu6: Some(expected_nu6),
102            #[cfg(zcash_unstable = "nu7")]
103            nu7: Some(expected_nu7),
104            #[cfg(zcash_unstable = "zfuture")]
105            z_future: Some(expected_z_future),
106        };
107
108        assert!(regtest.is_nu_active(NetworkUpgrade::Overwinter, expected_overwinter));
109        assert!(regtest.is_nu_active(NetworkUpgrade::Sapling, expected_sapling));
110        assert!(regtest.is_nu_active(NetworkUpgrade::Blossom, expected_blossom));
111        assert!(regtest.is_nu_active(NetworkUpgrade::Heartwood, expected_heartwood));
112        assert!(regtest.is_nu_active(NetworkUpgrade::Canopy, expected_canopy));
113        assert!(regtest.is_nu_active(NetworkUpgrade::Nu5, expected_nu5));
114        assert!(regtest.is_nu_active(NetworkUpgrade::Nu6, expected_nu6));
115        #[cfg(zcash_unstable = "nu7")]
116        assert!(!regtest.is_nu_active(NetworkUpgrade::Nu7, expected_nu6));
117        #[cfg(zcash_unstable = "zfuture")]
118        assert!(!regtest.is_nu_active(NetworkUpgrade::ZFuture, expected_nu6));
119    }
120
121    #[test]
122    fn regtest_activation_heights() {
123        let expected_overwinter = BlockHeight::from_u32(1);
124        let expected_sapling = BlockHeight::from_u32(2);
125        let expected_blossom = BlockHeight::from_u32(3);
126        let expected_heartwood = BlockHeight::from_u32(4);
127        let expected_canopy = BlockHeight::from_u32(5);
128        let expected_nu5 = BlockHeight::from_u32(6);
129        let expected_nu6 = BlockHeight::from_u32(7);
130        #[cfg(zcash_unstable = "nu7")]
131        let expected_nu7 = BlockHeight::from_u32(8);
132        #[cfg(zcash_unstable = "zfuture")]
133        let expected_z_future = BlockHeight::from_u32(8);
134
135        let regtest = LocalNetwork {
136            overwinter: Some(expected_overwinter),
137            sapling: Some(expected_sapling),
138            blossom: Some(expected_blossom),
139            heartwood: Some(expected_heartwood),
140            canopy: Some(expected_canopy),
141            nu5: Some(expected_nu5),
142            nu6: Some(expected_nu6),
143            #[cfg(zcash_unstable = "nu7")]
144            nu7: Some(expected_nu7),
145            #[cfg(zcash_unstable = "zfuture")]
146            z_future: Some(expected_z_future),
147        };
148
149        assert_eq!(
150            regtest.activation_height(NetworkUpgrade::Overwinter),
151            Some(expected_overwinter)
152        );
153        assert_eq!(
154            regtest.activation_height(NetworkUpgrade::Sapling),
155            Some(expected_sapling)
156        );
157        assert_eq!(
158            regtest.activation_height(NetworkUpgrade::Blossom),
159            Some(expected_blossom)
160        );
161        assert_eq!(
162            regtest.activation_height(NetworkUpgrade::Heartwood),
163            Some(expected_heartwood)
164        );
165        assert_eq!(
166            regtest.activation_height(NetworkUpgrade::Canopy),
167            Some(expected_canopy)
168        );
169        assert_eq!(
170            regtest.activation_height(NetworkUpgrade::Nu5),
171            Some(expected_nu5)
172        );
173        #[cfg(zcash_unstable = "nu7")]
174        assert_eq!(
175            regtest.activation_height(NetworkUpgrade::Nu7),
176            Some(expected_nu7)
177        );
178        #[cfg(zcash_unstable = "zfuture")]
179        assert_eq!(
180            regtest.activation_height(NetworkUpgrade::ZFuture),
181            Some(expected_z_future)
182        );
183    }
184
185    #[test]
186    fn regtests_constants() {
187        let expected_overwinter = BlockHeight::from_u32(1);
188        let expected_sapling = BlockHeight::from_u32(2);
189        let expected_blossom = BlockHeight::from_u32(3);
190        let expected_heartwood = BlockHeight::from_u32(4);
191        let expected_canopy = BlockHeight::from_u32(5);
192        let expected_nu5 = BlockHeight::from_u32(6);
193        let expected_nu6 = BlockHeight::from_u32(7);
194        #[cfg(zcash_unstable = "nu7")]
195        let expected_nu7 = BlockHeight::from_u32(8);
196        #[cfg(zcash_unstable = "zfuture")]
197        let expected_z_future = BlockHeight::from_u32(8);
198
199        let regtest = LocalNetwork {
200            overwinter: Some(expected_overwinter),
201            sapling: Some(expected_sapling),
202            blossom: Some(expected_blossom),
203            heartwood: Some(expected_heartwood),
204            canopy: Some(expected_canopy),
205            nu5: Some(expected_nu5),
206            nu6: Some(expected_nu6),
207            #[cfg(zcash_unstable = "nu7")]
208            nu7: Some(expected_nu7),
209            #[cfg(zcash_unstable = "zfuture")]
210            z_future: Some(expected_z_future),
211        };
212
213        assert_eq!(regtest.coin_type(), constants::regtest::COIN_TYPE);
214        assert_eq!(
215            regtest.hrp_sapling_extended_spending_key(),
216            constants::regtest::HRP_SAPLING_EXTENDED_SPENDING_KEY
217        );
218        assert_eq!(
219            regtest.hrp_sapling_extended_full_viewing_key(),
220            constants::regtest::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY
221        );
222        assert_eq!(
223            regtest.hrp_sapling_payment_address(),
224            constants::regtest::HRP_SAPLING_PAYMENT_ADDRESS
225        );
226        assert_eq!(
227            regtest.b58_pubkey_address_prefix(),
228            constants::regtest::B58_PUBKEY_ADDRESS_PREFIX
229        );
230        assert_eq!(
231            regtest.b58_script_address_prefix(),
232            constants::regtest::B58_SCRIPT_ADDRESS_PREFIX
233        );
234    }
235}