From dbd49a3f00173084153d422c3a8fa01e938f6dc9 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 23 Nov 2021 02:17:05 -0300 Subject: [PATCH] Validate coinbase expiration height (#3082) * add testnet test blocks around nu5 * validate coinbase expiration height * change const name and doc Co-authored-by: teor * change commit location Co-authored-by: teor * use pre Nu5 rules when there is no activation height * add sapling final root to nu5 test vectors * fix tests Co-authored-by: teor --- zebra-chain/src/block/height.rs | 8 ++++ zebra-chain/src/transaction/arbitrary.rs | 10 ++--- zebra-chain/src/transaction/tests/vectors.rs | 15 +++++-- zebra-consensus/src/block.rs | 3 ++ zebra-consensus/src/block/check.rs | 45 +++++++++++++++++++ zebra-consensus/src/block/tests.rs | 31 +++++++++++++ zebra-consensus/src/error.rs | 3 ++ .../src/vectors/block-test-1-599-199.txt | 1 + .../src/vectors/block-test-1-599-200.txt | 1 + .../src/vectors/block-test-1-599-201.txt | 1 + zebra-test/src/vectors/block.rs | 31 +++++++++++++ 11 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 zebra-test/src/vectors/block-test-1-599-199.txt create mode 100644 zebra-test/src/vectors/block-test-1-599-200.txt create mode 100644 zebra-test/src/vectors/block-test-1-599-201.txt diff --git a/zebra-chain/src/block/height.rs b/zebra-chain/src/block/height.rs index 0c11b2d7..b05e017c 100644 --- a/zebra-chain/src/block/height.rs +++ b/zebra-chain/src/block/height.rs @@ -48,6 +48,14 @@ impl Height { /// `Height::MAX.0` can't be used in match range patterns, use this /// alias instead. pub const MAX_AS_U32: u32 = Self::MAX.0; + + /// The maximum expiration Height that is allowed in all transactions + /// previous to Nu5 and in non-coinbase transactions from Nu5 activation height + /// and above. + /// + /// TODO: This is currently the same as `Height::MAX` but that change in #1113. + /// Remove this TODO when that happens. + pub const MAX_EXPIRY_HEIGHT: Height = Height(499_999_999); } impl Add for Height { diff --git a/zebra-chain/src/transaction/arbitrary.rs b/zebra-chain/src/transaction/arbitrary.rs index 0ca4344e..b818e19a 100644 --- a/zebra-chain/src/transaction/arbitrary.rs +++ b/zebra-chain/src/transaction/arbitrary.rs @@ -801,7 +801,7 @@ pub fn transaction_to_fake_v5( inputs: inputs.to_vec(), outputs: outputs.to_vec(), lock_time: *lock_time, - expiry_height: block::Height(0), + expiry_height: height, sapling_shielded_data: None, orchard_shielded_data: None, }, @@ -815,7 +815,7 @@ pub fn transaction_to_fake_v5( inputs: inputs.to_vec(), outputs: outputs.to_vec(), lock_time: *lock_time, - expiry_height: block::Height(0), + expiry_height: height, sapling_shielded_data: None, orchard_shielded_data: None, }, @@ -823,14 +823,13 @@ pub fn transaction_to_fake_v5( inputs, outputs, lock_time, - expiry_height, .. } => V5 { network_upgrade: block_nu, inputs: inputs.to_vec(), outputs: outputs.to_vec(), lock_time: *lock_time, - expiry_height: *expiry_height, + expiry_height: height, sapling_shielded_data: None, orchard_shielded_data: None, }, @@ -838,7 +837,6 @@ pub fn transaction_to_fake_v5( inputs, outputs, lock_time, - expiry_height, sapling_shielded_data, .. } => V5 { @@ -846,7 +844,7 @@ pub fn transaction_to_fake_v5( inputs: inputs.to_vec(), outputs: outputs.to_vec(), lock_time: *lock_time, - expiry_height: *expiry_height, + expiry_height: height, sapling_shielded_data: sapling_shielded_data .clone() .map(sapling_shielded_v4_to_fake_v5) diff --git a/zebra-chain/src/transaction/tests/vectors.rs b/zebra-chain/src/transaction/tests/vectors.rs index e1609719..843b255c 100644 --- a/zebra-chain/src/transaction/tests/vectors.rs +++ b/zebra-chain/src/transaction/tests/vectors.rs @@ -499,11 +499,18 @@ fn fake_v5_librustzcash_round_trip_for_network(network: Network) { .expect("a valid height") .0; - // skip blocks that are before overwinter as they will not have a valid consensus branch id - let blocks_after_overwinter = - block_iter.skip_while(|(height, _)| **height < overwinter_activation_height); + let nu5_activation_height = NetworkUpgrade::Nu5 + .activation_height(network) + .unwrap_or(Height::MAX_EXPIRY_HEIGHT) + .0; - for (height, original_bytes) in blocks_after_overwinter { + // skip blocks that are before overwinter as they will not have a valid consensus branch id + // skip blocks equal or greater Nu5 activation as they are already v5 transactions + let blocks_after_overwinter_and_before_nu5 = block_iter + .skip_while(|(height, _)| **height < overwinter_activation_height) + .take_while(|(height, _)| **height < nu5_activation_height); + + for (height, original_bytes) in blocks_after_overwinter_and_before_nu5 { let original_block = original_bytes .zcash_deserialize_into::() .expect("block is structurally valid"); diff --git a/zebra-consensus/src/block.rs b/zebra-consensus/src/block.rs index a53346aa..99e43089 100644 --- a/zebra-consensus/src/block.rs +++ b/zebra-consensus/src/block.rs @@ -188,6 +188,9 @@ where tx::check::coinbase_outputs_are_decryptable(coinbase_tx, network, height)?; check::subsidy_is_valid(&block, network)?; + // Validate `nExpiryHeight` consensus rules + check::coinbase_expiry_height(&height, coinbase_tx, network)?; + let mut async_checks = FuturesUnordered::new(); let known_utxos = Arc::new(transparent::new_ordered_outputs( diff --git a/zebra-consensus/src/block/check.rs b/zebra-consensus/src/block/check.rs index 01505ba7..abec8df9 100644 --- a/zebra-consensus/src/block/check.rs +++ b/zebra-consensus/src/block/check.rs @@ -248,3 +248,48 @@ pub fn merkle_root_validity( Ok(()) } + +/// Returns `Ok(())` if the expiry height for the coinbase transaction is valid +/// according to specifications [7.1] and [ZIP-203]. +/// +/// [7.1]: https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus +/// [ZIP-203]: https://zips.z.cash/zip-0203 +pub fn coinbase_expiry_height( + height: &Height, + coinbase: &transaction::Transaction, + network: Network, +) -> Result<(), BlockError> { + match NetworkUpgrade::Nu5.activation_height(network) { + // If Nu5 does not have a height, apply the pre-Nu5 rule. + None => validate_expiry_height_max(coinbase.expiry_height()), + Some(activation_height) => { + // Conesnsus rule: from NU5 activation, the nExpiryHeight field of a + // coinbase transaction MUST be set equal to the block height. + if *height >= activation_height { + match coinbase.expiry_height() { + None => Err(TransactionError::CoinbaseExpiration)?, + Some(expiry) => { + if expiry != *height { + return Err(TransactionError::CoinbaseExpiration)?; + } + } + } + return Ok(()); + } + // Consensus rule: [Overwinter to Canopy inclusive, pre-NU5] nExpiryHeight + // MUST be less than or equal to 499999999. + validate_expiry_height_max(coinbase.expiry_height()) + } + } +} + +/// Validate the consensus rule: nExpiryHeight MUST be less than or equal to 499999999. +fn validate_expiry_height_max(expiry_height: Option) -> Result<(), BlockError> { + if let Some(expiry) = expiry_height { + if expiry > Height::MAX_EXPIRY_HEIGHT { + return Err(TransactionError::CoinbaseExpiration)?; + } + } + + Ok(()) +} diff --git a/zebra-consensus/src/block/tests.rs b/zebra-consensus/src/block/tests.rs index 2be53a81..08717324 100644 --- a/zebra-consensus/src/block/tests.rs +++ b/zebra-consensus/src/block/tests.rs @@ -661,3 +661,34 @@ fn legacy_sigops_count_for_historic_blocks() { assert!(legacy_sigop_count <= MAX_BLOCK_SIGOPS); } } + +#[test] +fn coinbase_height_validation() -> Result<(), Report> { + zebra_test::init(); + + coinbase_height_for_network(Network::Mainnet)?; + coinbase_height_for_network(Network::Testnet)?; + + Ok(()) +} + +fn coinbase_height_for_network(network: Network) -> Result<(), Report> { + let block_iter = match network { + Network::Mainnet => zebra_test::vectors::MAINNET_BLOCKS.iter(), + Network::Testnet => zebra_test::vectors::TESTNET_BLOCKS.iter(), + }; + + for (&height, block) in block_iter { + let block = Block::zcash_deserialize(&block[..]).expect("block should deserialize"); + + // Validate + let result = check::coinbase_expiry_height( + &Height(height), + block.transactions.get(0).unwrap(), + network, + ); + assert!(result.is_ok()); + } + + Ok(()) +} diff --git a/zebra-consensus/src/error.rs b/zebra-consensus/src/error.rs index ef5db91e..518d776e 100644 --- a/zebra-consensus/src/error.rs +++ b/zebra-consensus/src/error.rs @@ -56,6 +56,9 @@ pub enum TransactionError { #[error("coinbase inputs MUST NOT exist in mempool")] CoinbaseInMempool, + #[error("coinbase expiration height is invalid")] + CoinbaseExpiration, + #[error("coinbase transaction failed subsidy validation")] #[cfg_attr(any(test, feature = "proptest-impl"), proptest(skip))] Subsidy(#[from] SubsidyError), diff --git a/zebra-test/src/vectors/block-test-1-599-199.txt b/zebra-test/src/vectors/block-test-1-599-199.txt new file mode 100644 index 00000000..9e9303bc --- /dev/null +++ b/zebra-test/src/vectors/block-test-1-599-199.txt @@ -0,0 +1 @@ +04000000b26e0c796bca49d9f3728e922af97a3e256f4ec5e742f3ac04c68284fd344900b21c06e5efbab781a9e24cd6e05fae07d5fc7ba2afa9fb041e251c4cfffcf9d437333ddce980f8998f03dcb9dabd6e604f9316db5928918fe7630b3bc944b02764365d617e046f1f22000d646c8255fc55033c901d155342d73ad69d7651df2eb9b8988392b50000fd4005014a93d51a057de5f208135b6de23b09892f4ee19724bcb23afb5c6c3721487509d52fc42a4a67b3d8bb0ea1b14adc87ee60ec7426b9fbdd605735af9aafd423fe9473f9554c835e0e14d1acef041239f676c8a301e5b3afc812c8b7943dc6637b6eb8761bf9d68add1131b5fc8d8b4a5a6ec574fa43d19442af5fd62df20a250cf824ca91fcaadc00e9f0188cea505fd6a7665fa51587afbb1125f71016963fdae7ca3c827775a70c7d9080905607ef4ddbd664dac41e420b8abb8bf81e1d03af4c9fc21944629800cacf375705d3f9a94312f9dd29f6ddb56fc0aa65f2a4b35b264af57c67dd5157b68651d715c3fea987f96070d1b63e9ad2f0170d729772064e4a1f446c431136d5d47edc8a592636156c1a3e4dca9d070a0764c3534bd35f47b21dd61112213d82dded6453a0bfc301b3a735da4c5977457e22451c9c2c1312ebbd9fe3b067d926515420528a1e0199d8c0c80e2e48d02da0258fe70c008b7fb3ee7435635b145d11301ba85cd541d95029da7f1f7611e60e21e6ef49c5c6c717a67137dd24b248aa35a82ac612c27be3c278cea5dff6a39783557e7581bcd0db5c0cfdfdbaa2cebc4bd84894b742f9504263d87593d31cbad0e9d20c3527919df7cbf1de3e2e414f9e66c30d8d8ceefc8a1851345e829263c0ed8ed279ffaeb65f002b4af7a83aa9f49e25f590f22d71ed00997e43049d0c85b1e1eee12672f4fcdd6025e943da133f1227f8e6a8f531c801dfc5a7a85f75bee5f1f37a8e0c12c9ae80d617a3d6f4ed742d6e3c5965d7d81e21f73911c7d41d558745cd021673bc53da121a6dff82510688453d908674dcf52e54e8c7c25c5d8fd33c796a1788a2a86724743db33b321c13c3ac1103c35c47b21c596c946d8c974e997083d28a676e211f23145afb272fee8037b35fc1de9b22d2b599c84e5f52df43d30217585e790b609d0f3b90397237bba93a8c9ac0fa0ef6ceabe9a9329b6982793492f7bb6eda5ad96e92041682b5b1918ae531b061709136740cd656b3862705203f89e2d41caea4408136f1dd544920a811bc95022ff575af24e3c7ec7a262b7144c8263d40f84db42c27e379ba0b417d77e694b46bdc71fb7791bdb5d80403b2141d5be888e9214118eaad58718c891532f1146bacc28fdff5afef82414a1d9e0054976eb407e6037ad7cace999a6743eb32e9e8b8d71da5c92e5c001c1edd03ed70e137b0da02c6723b8d83142e1ce09603db9b8132891975876f35f2ab347eaa1f7534279a06f25f2e30f78b91d048817c1cc1cc058328edc268145baaf3f6cb42f17f9732bbe142d435d45c9c8cd777fce3e58a6f057f9e40f7ffe66f58da209b5d69da1fbaa3bb3f11d27f9f8b83ab6ea74809c6b877932a1fcd99abe1a43469ceaf155aa0aee7496223b3260502430a072816567bf563a24eeef9a4bd7082d53cf6103c6d25ac65a9a9e55ba827cbda3f1a8692feace204bb95a74814544b2cc0f15eeaca87ec74c1f1d4ef3c86f6538cb394dfa3df7569ba48f79e32bf5246dd092f3518b01a1f45699a64ea51c01ddb47121b5d7c35699ef9d590bab9f216d6bdbc65a085e19a8f44d30ec9a92dc00c47d69f4d741ec1ee3deee7e0b9021134191cdecc1215e366e4bb031dfea632d7f75a588e05c586298173dbe9a19a11e254a50ad12aa82bcf345263b306de295cff73ce17ff914cdcc6655e1dc3820870ef26d749e6ab7c7071bbc8e98821ab025220f908a36e11ca4f29bac17324188acfcbe11acbd03c9a0a338b5ed0d63f86c0f23608d5b8552d92f799ab0c3e6995c2981c79ad5d9195d04fe0e713108added942a1adde96ca14d9bb525f697cefac2f23e62720e254da847763f1efd15f10b857ed9c2eb1ae3d23d1d81010400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff0603df66180101ffffffff0480b2e60e000000001976a91403e105ea5dbb243cddada1ec31cebd92266cd22588ac286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a914221c95f83bf073cfb76724ed23af737c1ee3bb498740787d010000000017a91471e1df05024288a00802de81e08c437859586c878700000000000000000000000000000000000000 diff --git a/zebra-test/src/vectors/block-test-1-599-200.txt b/zebra-test/src/vectors/block-test-1-599-200.txt new file mode 100644 index 00000000..fb070857 --- /dev/null +++ b/zebra-test/src/vectors/block-test-1-599-200.txt @@ -0,0 +1 @@ +04000000ed34eead710be6b5da373edd2e5515407a0d9f5f2b511f09f1ddabd3764e27008039c40bd3ab96700f2242b1200608d4a1c74264bc71b3f956a2339b4606957ba7d9248f4d9300eca388220a40b4e98ab8f0459af40d74dff3bb07a9691df4487e365d61a94e6d1f2a00ab6acaf882cba8e6f322ab507bf2c349664286203c6f194b1708250c0000fd40050008feecb65909d17f1120a372873dacc148305f700e82b5b34e8898135857f4a4f3cc568ad4d0bed15913e4461ed0d39e56a038737e664414b53b5db2d763666c1d99096ce943ebc9c9fb7fd665be8c049b6218178d33323a94502f1afa91eb9552f254b9796afa3f2a80dff1dc1dfae350eb733ee840512630fef7658525ad7740256720d1a469725d0b2fe8f6a8161807843933a43b83245073b4fd161c38cdce0ac57bd9629e0ce5961d33848464ee2fb1cc64529f1588820e06e62d52a476721bdf95add623872aef7cc13622b58103182b969f0d66b38f8351f20d0919e3a111e3f74f843746877d349a75eed5df74983fc3726e15fbf1bcce1054e38a2096ef4fc087f10c6fae6fb1a0fd78c4cd343bb3f52d939d36d204e3b55c3e26599ed2dcb2ee2b541195d06757a58908a536c04d83b67581bed02e3f72c584122ff27dadd6657e61b5375f092cfb4cf700785920fd8e3b92f58ba3d98be05a799257dd02945c8c9b0637a5d39bc3ac16d491f7355af88a9be77212d248bace52cab1dab316e83dfa7ae208a532d7ab16157abd0b299b377927d3db496e832db82739b9a91abeef2ea7942c2f1893b310969ff051786352f5884e8a572c8317d659efe1089f7a4e68bef3135ea9501e9b15c4ec91cfa1c875435cbbfda4421eab78f0d42439bde9230965617ef5c5b099fff24a52d139d07e07f1388f8caf6e25a7be438a487ad9b2f46e3d029d3831cb9337b6fcb3bb53c4ee9cc79d4b894ebd02d60e125f220c543ed1f5adb320cc3da5026bf41ecc9b15497a39662a66315de4f488f2cbe4f57d4b0d14e80be341a3678ccfb9aa1011c86934d8619324cea3a71768a37dd2ce37d59730484e5dccde868ee3fc2aef1befe9c117504c01a6325a5de16824c70e73f9267844666bc043d848fd72d7289a83ec15a2c1eefb08cd0085657436e2fca122681375d86109d986a6b6a1d110cc656138cd90b89422aae8a27da27b6e7abf9dcf0b21c3370cf453a9eafe12331a72a85338dddf45af34234cd3f50db21b6c5a67eea8e2e4965618bf9f3e0abeec58e91d4d55b138416743b3f179496addcb7633b9dfcacf128ff17e471368c5e7469246145e690c0b54f492d4c50cf7d40f80d36e7b25607c8d2a4bfe19073da2b82a1ce3ca6ac4fc12f6b4c9ea185ca61401cbfd34f09f1cff1ae9119c9fc09d00f07c56e01e0ce223c7b1c7066accf135917ac60e79f2a117c72e108012c5342f79c9938f32f1ca77445cca50ef81dc2a95ad681f4c6b44be22e4afc8bc7b11718b58ea3e02b4a48b4a8f90cefb4b804443b6b5e83b0af55a7a1ebb7b4409cfa2134c5e291dd2750eaac6131c0d4710bbda6d9b4ead5ce43681cd7ac8dc27c3081e76775f959f2692a1c5d3e8bd0629c54cadae408bd5149a0129e966b8091e2eba31b294ff5d47c0f91655691917ef791dc912f5c78bc373285d36d57ea68f9971ce0bb0fb4e4d1970637a8fa24dc858e914bfbfa9953320dfd474a36bcc39ffcff67becfb7122c2885a0aa605b09470e5456d349b5eb32685fdb460ce7bcaf75f13b927536de5a29530b6e27da228736cae7abe4a490b358c38424ce53ac123e419acec6aa1c28936b38d10edcb2c2790a282af0d8302fe734d58f507fec0470410fd20bb615f65f516a0921bd8ca8cc494ade81313ac0b2411e24d57d3f5ca742dd91e12ae27dfe74e07f9fc1c1b26ba7574d544095d30495efb0efe3eaf438c2e1c6b1a635f8ea4d4fd362948e20d85de15f80d22a3e8815f995f58bce5afe3cd79918dcdb25a09160a1a59d1d0d33b6535a1fe58920f06cca21d562716b2ee3a91df66639bb4921b93ff4b58bab61668ab295b49f77367d513e0c9088e55dada66fe65dc7d5601050000800a27a7262196513700000000e0661800010000000000000000000000000000000000000000000000000000000000000000ffffffff0603e066180102ffffffff0480b2e60e000000001976a9146e82b7c719334e3aac3916872a088b548c43c9fb88ac286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a914221c95f83bf073cfb76724ed23af737c1ee3bb498740787d010000000017a91471e1df05024288a00802de81e08c437859586c8787000000 diff --git a/zebra-test/src/vectors/block-test-1-599-201.txt b/zebra-test/src/vectors/block-test-1-599-201.txt new file mode 100644 index 00000000..ed383583 --- /dev/null +++ b/zebra-test/src/vectors/block-test-1-599-201.txt @@ -0,0 +1 @@ +04000000da438160fc9c57ca00c5251e689f9c8b21e1f84fcd645b95c0a85e9948e43100f6c3f2ef2b6f542ad77967e75314f45c509033eb887b09828ff9137c2b73ef4752da86ea6380c2353ec868cba9a16edb3b1a483a2d084ae76ab4404b2d929b048f365d61149c6c1f1c007c736075333a175f237e246890a5906e0c065d4adfedcb16fecaca250000fd4005002699b2262a65cdf85c128de3aaa471314b5c2cbb0e307fbdc2046603836141116974b80890ed989b7b19890642cc641f17fd31b7a92c7d74af40cbdefda224896b818b9baad78d22e2fa0ba66f2dd7251fe241095ced9f9249c4d7955392c4a228fa6e6bfb973c6e0d632ec3bcc389eaa15bb3c3193536862f4071a3b92bb0f227c10e3120f9b42331204428d6585b1abf396dda3c47b31ef2a5887979ae9a7efc534c7c3c3cc407355da6c927245f6ea0e15f0d1d7ed13b73d48f8021b415f63d93e04fa3a4644e3c529926a4d976d81e13a7c965cfb7e1b9d812b7c01af0bff6a4aa9ad00819e92754c1d9c5c12427e4434c2670c33df93d6eb41fbc7684220ec890a62a93ec3e4c7eb5329c5cece735eebdfa670d97c50b6689b9e0fb713f8e39fdd8e4223e3aa8abe23de3e4fc94b6fcf2708930abf88aac55ca4dd5f2d80998c678285e7ad52186ffef7f229800a24f98f9d8b0995beff6e980d17f4e73f9da5b3603da84b20f876d57eb53b3eedbcf17b6cf561e9ccf2f41570f009e4131c3f983d81ef3fb65a66d70e6114255c5b46559b0fdca9c4a51fee1c146d117fb235c1150d22b2b45848bec53a5fc7bb1a98757003e0f2c49d98e949cdd69b7340be5df7ddb553668425efb6a123bd981e425cb29e96d31898f250815c644b9365d1835316d520e234ccd22c8c459488fbee8e6fcb66202c83ed96dd298933a32f251ddc96f69b788759c7d1319baada1924e137eede59400512bea082a71ad020c120aa559c72bc7690ad163b7af65a1dc7d1d635c3a78154f57a5fec9ed1327f9d2f6749a0a08d72a4e05e1e840e82b3d61e15cc3684a4847f79cfdbd1b2506a998fc018c636c6dcc74a4fc61690abd06da5be806c1a9e44184dcc0f602b340aa72716a03f435671a2230a4699d568a44cbe043261a46eff0de687852470138a4b0bd20b685bd011a1e89fc9c731ba35c2ba90f8d17a86d3069f38ef3827076a8a4553b844d5dc60289e4638707f5aecfdaf25255d62b54b4032c8d5f086306f1b34466407508012dd59d14ea80025dd0270372bce36d49e8c9db0c0224e118e2455c42cf038b0cd955cda1b15ac9964ce1132f24daf05f43d0e8c226f9fe7080187c997798136b013dbb876b4d1c314b566af314b11f5e779614b5b8a878439d8727bb45a601eeebaf58d3f6c93f77a17b5370eb199e33d698010b345f0e0649677e985e923d12b6ab7d0c3aaf48720741d65e611979edd512368ab8e6b5a5bb9777fd245079733d5e57324b2089c61f5bbf921ecebd970eb6036f56c937cba3fba4dca34c293e01aa7e7fdaf1dd127df1c17d8d7b19dad363cbfe69c79d24107840aa0bfc447158535d772b3453fa2ce7a99e87bbd8f6a5160c7538a993e9b1251c8396e8bc678a56353662b401b72494df058c6e4941f13ad05655ca34d571f93d2e175a2cb8937259668dd3dcf9e4c81edc3fd77464167affc3c39e34bff852c3c45cbde28f9b9a5f8a7e54763dc2fd970271cade79ae49d40a8706853eb116185a6eeef82745d18957e2ce01169c38bbc31c68684a47dbe3de542463771e9711de6c3476291034f5032ba18e8e924c4f30c4df96dbe15f2a5a55503a9cdd40a8f62fc5a70107df34a68cc6756c33a137be63540d2551218a248fe92dae21d922bef56a42d7bda739383ad9fd27d63c74d1d2253c752fc1f57e852e8bc912a8cb8f12d5b50d97569560d8661afdb00b7c711e23a31d1d025f13a9779343268b5233f9af589a9b2a17b7e9915dcc65c39c4a5612b3f74b6a30c8762280352b122afad7caafd1ae1883e7c5de831d539c605c21376469eb113e88abbcf5578c6b2e56445bdc6f6321b8eff24e97d43ecfcc62d1f4ebd4acfd63d4c69701050000800a27a7262196513700000000e1661800010000000000000000000000000000000000000000000000000000000000000000ffffffff0603e166180101ffffffff0480b2e60e000000001976a9146e82b7c719334e3aac3916872a088b548c43c9fb88ac286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a914221c95f83bf073cfb76724ed23af737c1ee3bb498740787d010000000017a91471e1df05024288a00802de81e08c437859586c8787000000 diff --git a/zebra-test/src/vectors/block.rs b/zebra-test/src/vectors/block.rs index beba87af..e52e26e5 100644 --- a/zebra-test/src/vectors/block.rs +++ b/zebra-test/src/vectors/block.rs @@ -220,6 +220,10 @@ lazy_static! { (1_116_000, BLOCK_TESTNET_1116000_BYTES.as_ref()), (1_116_001, BLOCK_TESTNET_1116001_BYTES.as_ref()), (1_326_100, BLOCK_TESTNET_1326100_BYTES.as_ref()), + (1_599_199, BLOCK_TESTNET_1599199_BYTES.as_ref()), + // Nu5 + (1_599_200, BLOCK_TESTNET_1599200_BYTES.as_ref()), + (1_599_201, BLOCK_TESTNET_1599201_BYTES.as_ref()), ].iter().cloned().collect(); /// Testnet final Sprout roots, indexed by height. @@ -272,6 +276,10 @@ lazy_static! { (1_116_000, SAPLING_FINAL_ROOT_TESTNET_1116000_BYTES.as_ref().try_into().unwrap()), (1_116_001, SAPLING_FINAL_ROOT_TESTNET_1116001_BYTES.as_ref().try_into().unwrap()), (1_326_100, SAPLING_FINAL_ROOT_TESTNET_1326100_BYTES.as_ref().try_into().unwrap()), + (1_599_199, SAPLING_FINAL_ROOT_TESTNET_1599199_BYTES.as_ref().try_into().unwrap()), + // Nu5 + (1_599_200, SAPLING_FINAL_ROOT_TESTNET_1599200_BYTES.as_ref().try_into().unwrap()), + (1_599_201, SAPLING_FINAL_ROOT_TESTNET_1599201_BYTES.as_ref().try_into().unwrap()), ].iter().cloned().collect(); // Mainnet @@ -835,6 +843,29 @@ lazy_static! { pub static ref SAPLING_FINAL_ROOT_TESTNET_1326100_BYTES: [u8; 32] = <[u8; 32]>::from_hex("2b30b19f4254709fe365bd0b381b2e3d9d0c933eb4dba4dd1d07f0f6e196a183") .expect("final root bytes are in valid hex representation").rev(); + + // Nu5 transition + // for i in 1599199 1599200 1599201; do + // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt + // done + pub static ref BLOCK_TESTNET_1599199_BYTES: Vec = + >::from_hex(include_str!("block-test-1-599-199.txt").trim()) + .expect("Block bytes are in valid hex representation"); + pub static ref BLOCK_TESTNET_1599200_BYTES: Vec = + >::from_hex(include_str!("block-test-1-599-200.txt").trim()) + .expect("Block bytes are in valid hex representation"); + pub static ref BLOCK_TESTNET_1599201_BYTES: Vec = + >::from_hex(include_str!("block-test-1-599-201.txt").trim()) + .expect("Block bytes are in valid hex representation"); + pub static ref SAPLING_FINAL_ROOT_TESTNET_1599199_BYTES: [u8; 32] = + <[u8; 32]>::from_hex("4de75d10def701ad22ecc17517a3adc8789ea8c214ac5bfc917b8924377e6c89") + .expect("final root bytes are in valid hex representation").rev(); + pub static ref SAPLING_FINAL_ROOT_TESTNET_1599200_BYTES: [u8; 32] = + <[u8; 32]>::from_hex("4de75d10def701ad22ecc17517a3adc8789ea8c214ac5bfc917b8924377e6c89") + .expect("final root bytes are in valid hex representation").rev(); + pub static ref SAPLING_FINAL_ROOT_TESTNET_1599201_BYTES: [u8; 32] = + <[u8; 32]>::from_hex("4de75d10def701ad22ecc17517a3adc8789ea8c214ac5bfc917b8924377e6c89") + .expect("final root bytes are in valid hex representation").rev(); } #[cfg(test)]