@@ -22,6 +22,7 @@ pub enum NetworkUpgrade {
2222 Nu5 ,
2323 Nu6 ,
2424 Nu6_1 ,
25+ Nu6_2 ,
2526}
2627
2728/// Parameters for a single network upgrade
@@ -43,6 +44,7 @@ impl NetworkUpgrade {
4344 NetworkUpgrade :: Nu5 ,
4445 NetworkUpgrade :: Nu6 ,
4546 NetworkUpgrade :: Nu6_1 ,
47+ NetworkUpgrade :: Nu6_2 ,
4648 ] ;
4749
4850 /// Get the parameters for this network upgrade
@@ -90,6 +92,16 @@ impl NetworkUpgrade {
9092 mainnet_activation_height : 3146400 ,
9193 testnet_activation_height : 3536500 ,
9294 } ,
95+ // NU6.2: emergency hard fork re-enabling Orchard with the corrected circuit
96+ // after GHSA-ghc3-g8w4-whf9. Values match ZcashFoundation/zebra
97+ // `network_upgrade.rs` (CONSENSUS_BRANCH_IDS) / `constants::activation_heights`.
98+ // Not yet in the pinned zebra-chain 7.0 dependency, so the parity tests below
99+ // skip Nu6_2 and it is guarded by `test_nu6_2_constants` until the dep is bumped (T1-3519).
100+ NetworkUpgrade :: Nu6_2 => UpgradeParams {
101+ branch_id : 0x5437f330 ,
102+ mainnet_activation_height : 3364600 ,
103+ testnet_activation_height : 4052000 ,
104+ } ,
93105 }
94106 }
95107
@@ -156,6 +168,22 @@ mod tests {
156168 }
157169 }
158170
171+ /// NU6.2 is not yet in the pinned zebra-chain dependency (see T1-3519), so it is
172+ /// excluded from the parity tests below. Guard its hardcoded constants here instead.
173+ /// Source: ZcashFoundation/zebra network_upgrade.rs + constants::activation_heights.
174+ #[ test]
175+ fn test_nu6_2_constants ( ) {
176+ assert_eq ! ( NetworkUpgrade :: Nu6_2 . branch_id( ) , 0x5437f330 ) ;
177+ assert_eq ! ( NetworkUpgrade :: Nu6_2 . mainnet_activation_height( ) , 3_364_600 ) ;
178+ assert_eq ! ( NetworkUpgrade :: Nu6_2 . testnet_activation_height( ) , 4_052_000 ) ;
179+ // Heights at/after activation resolve to NU6.2; the block before stays NU6.1.
180+ assert_eq ! ( branch_id_for_height( 3_364_600 , true ) , Some ( 0x5437f330 ) ) ;
181+ assert_eq ! (
182+ branch_id_for_height( 3_364_599 , true ) ,
183+ Some ( NetworkUpgrade :: Nu6_1 . branch_id( ) )
184+ ) ;
185+ }
186+
159187 /// Tests that verify our constants match zebra-chain crate.
160188 /// These tests are exhaustive - they verify ALL upgrades in zebra-chain
161189 /// and will fail if we're missing any.
@@ -167,9 +195,11 @@ mod tests {
167195 } ;
168196
169197 /// Map our NetworkUpgrade to zebra-chain's NetworkUpgrade.
170- /// This match is exhaustive - if zebra adds a new upgrade, this will fail to compile.
171- fn to_zebra_upgrade ( upgrade : NetworkUpgrade ) -> ZebraNetworkUpgrade {
172- match upgrade {
198+ /// Returns `None` for upgrades not yet present in the pinned zebra-chain
199+ /// dependency (currently NU6.2 — see T1-3519). The match is otherwise exhaustive,
200+ /// so a new upgrade added here without a mapping will fail to compile.
201+ fn to_zebra_upgrade ( upgrade : NetworkUpgrade ) -> Option < ZebraNetworkUpgrade > {
202+ Some ( match upgrade {
173203 NetworkUpgrade :: Overwinter => ZebraNetworkUpgrade :: Overwinter ,
174204 NetworkUpgrade :: Sapling => ZebraNetworkUpgrade :: Sapling ,
175205 NetworkUpgrade :: Blossom => ZebraNetworkUpgrade :: Blossom ,
@@ -178,7 +208,9 @@ mod tests {
178208 NetworkUpgrade :: Nu5 => ZebraNetworkUpgrade :: Nu5 ,
179209 NetworkUpgrade :: Nu6 => ZebraNetworkUpgrade :: Nu6 ,
180210 NetworkUpgrade :: Nu6_1 => ZebraNetworkUpgrade :: Nu6_1 ,
181- }
211+ // NU6.2 is not in pinned zebra-chain 7.0; validated by test_nu6_2_constants.
212+ NetworkUpgrade :: Nu6_2 => return None ,
213+ } )
182214 }
183215
184216 /// Map zebra-chain's NetworkUpgrade to ours.
@@ -228,18 +260,21 @@ mod tests {
228260 )
229261 } ) ;
230262
231- // Verify round-trip
263+ // Verify round-trip (zebra-known upgrades always map back to Some)
232264 assert_eq ! (
233265 to_zebra_upgrade( our_upgrade) ,
234- zebra_upgrade,
266+ Some ( zebra_upgrade) ,
235267 "Round-trip failed for {:?}" ,
236268 zebra_upgrade
237269 ) ;
238270 }
239271
240- // Verify every upgrade in our ALL list maps to zebra
272+ // Verify every upgrade in our ALL list maps to zebra.
273+ // NU6.2 is not yet in the pinned zebra-chain (T1-3519), so it is skipped here.
241274 for & our_upgrade in NetworkUpgrade :: ALL {
242- let zebra_upgrade = to_zebra_upgrade ( our_upgrade) ;
275+ let Some ( zebra_upgrade) = to_zebra_upgrade ( our_upgrade) else {
276+ continue ;
277+ } ;
243278 assert ! (
244279 zebra_upgrade. branch_id( ) . is_some( ) ,
245280 "{:?} should have a branch ID" ,
@@ -251,7 +286,9 @@ mod tests {
251286 #[ test]
252287 fn test_branch_ids_match_zebra ( ) {
253288 for & upgrade in NetworkUpgrade :: ALL {
254- let zebra_upgrade = to_zebra_upgrade ( upgrade) ;
289+ let Some ( zebra_upgrade) = to_zebra_upgrade ( upgrade) else {
290+ continue ; // NU6.2 not in pinned zebra-chain (T1-3519)
291+ } ;
255292 let expected = zebra_upgrade
256293 . branch_id ( )
257294 . map ( u32:: from)
@@ -272,7 +309,9 @@ mod tests {
272309 fn test_mainnet_heights_match_zebra ( ) {
273310 let network = ZebraNetwork :: Mainnet ;
274311 for & upgrade in NetworkUpgrade :: ALL {
275- let zebra_upgrade = to_zebra_upgrade ( upgrade) ;
312+ let Some ( zebra_upgrade) = to_zebra_upgrade ( upgrade) else {
313+ continue ; // NU6.2 not in pinned zebra-chain (T1-3519)
314+ } ;
276315 let expected = zebra_upgrade
277316 . activation_height ( & network)
278317 . map ( |h| h. 0 )
@@ -293,7 +332,9 @@ mod tests {
293332 fn test_testnet_heights_match_zebra ( ) {
294333 let network = ZebraNetwork :: new_default_testnet ( ) ;
295334 for & upgrade in NetworkUpgrade :: ALL {
296- let zebra_upgrade = to_zebra_upgrade ( upgrade) ;
335+ let Some ( zebra_upgrade) = to_zebra_upgrade ( upgrade) else {
336+ continue ; // NU6.2 not in pinned zebra-chain (T1-3519)
337+ } ;
297338 let expected = zebra_upgrade
298339 . activation_height ( & network)
299340 . map ( |h| h. 0 )
0 commit comments