//! Block test vectors use hex::FromHex; use lazy_static::lazy_static; use std::{collections::BTreeMap, iter::FromIterator}; lazy_static! { /// All block test vectors pub static ref BLOCKS: Vec<&'static [u8]> = MAINNET_BLOCKS .iter() .chain(TESTNET_BLOCKS.iter()) .map(|(_height, block)| *block) .collect(); // Update these lists of blocks when you add new block test vectors to // this file // // We use integer heights in these maps, to avoid a dependency on zebra_chain /// Mainnet blocks, indexed by height /// /// This is actually a bijective map, the tests ensure that values are unique. pub static ref MAINNET_BLOCKS: BTreeMap = BTreeMap::from_iter( [ // Genesis (0, BLOCK_MAINNET_GENESIS_BYTES.as_ref()), // BeforeOverwinter (1, BLOCK_MAINNET_1_BYTES.as_ref()), (2, BLOCK_MAINNET_2_BYTES.as_ref()), (3, BLOCK_MAINNET_3_BYTES.as_ref()), (4, BLOCK_MAINNET_4_BYTES.as_ref()), (5, BLOCK_MAINNET_5_BYTES.as_ref()), (6, BLOCK_MAINNET_6_BYTES.as_ref()), (7, BLOCK_MAINNET_7_BYTES.as_ref()), (8, BLOCK_MAINNET_8_BYTES.as_ref()), (9, BLOCK_MAINNET_9_BYTES.as_ref()), (10, BLOCK_MAINNET_10_BYTES.as_ref()), (347_499, BLOCK_MAINNET_347499_BYTES.as_ref()), // Overwinter (347_500, BLOCK_MAINNET_347500_BYTES.as_ref()), (347_501, BLOCK_MAINNET_347501_BYTES.as_ref()), (415_000, BLOCK_MAINNET_415000_BYTES.as_ref()), (419_199, BLOCK_MAINNET_419199_BYTES.as_ref()), // Sapling (419_200, BLOCK_MAINNET_419200_BYTES.as_ref()), (419_201, BLOCK_MAINNET_419201_BYTES.as_ref()), (434_873, BLOCK_MAINNET_434873_BYTES.as_ref()), (653_599, BLOCK_MAINNET_653599_BYTES.as_ref()), // Blossom (653_600, BLOCK_MAINNET_653600_BYTES.as_ref()), (653_601, BLOCK_MAINNET_653601_BYTES.as_ref()), (902_999, BLOCK_MAINNET_902999_BYTES.as_ref()), // Heartwood (903_000, BLOCK_MAINNET_903000_BYTES.as_ref()), (903_001, BLOCK_MAINNET_903001_BYTES.as_ref()), (949_496, BLOCK_MAINNET_949496_BYTES.as_ref()), (975_066, BLOCK_MAINNET_975066_BYTES.as_ref()), (982_681, BLOCK_MAINNET_982681_BYTES.as_ref()), // TODO: Canopy and First Halving, see #1099 ].iter().cloned() ); /// Testnet blocks, indexed by height /// /// This is actually a bijective map, the tests ensure that values are unique. pub static ref TESTNET_BLOCKS: BTreeMap = BTreeMap::from_iter( [ // Genesis (0, BLOCK_TESTNET_GENESIS_BYTES.as_ref()), // BeforeOverwinter (1, BLOCK_TESTNET_1_BYTES.as_ref()), (2, BLOCK_TESTNET_2_BYTES.as_ref()), (3, BLOCK_TESTNET_3_BYTES.as_ref()), (4, BLOCK_TESTNET_4_BYTES.as_ref()), (5, BLOCK_TESTNET_5_BYTES.as_ref()), (6, BLOCK_TESTNET_6_BYTES.as_ref()), (7, BLOCK_TESTNET_7_BYTES.as_ref()), (8, BLOCK_TESTNET_8_BYTES.as_ref()), (9, BLOCK_TESTNET_9_BYTES.as_ref()), (10, BLOCK_TESTNET_10_BYTES.as_ref()), (141_042, BLOCK_TESTNET_141042_BYTES.as_ref()), (207_499, BLOCK_TESTNET_207499_BYTES.as_ref()), // Overwinter (207_500, BLOCK_TESTNET_207500_BYTES.as_ref()), (207_501, BLOCK_TESTNET_207501_BYTES.as_ref()), (279_999, BLOCK_TESTNET_279999_BYTES.as_ref()), // Sapling (280_000, BLOCK_TESTNET_280000_BYTES.as_ref()), (280_001, BLOCK_TESTNET_280001_BYTES.as_ref()), (583_999, BLOCK_TESTNET_583999_BYTES.as_ref()), // Blossom (584_000, BLOCK_TESTNET_584000_BYTES.as_ref()), (584_001, BLOCK_TESTNET_584001_BYTES.as_ref()), (903_799, BLOCK_TESTNET_903799_BYTES.as_ref()), // Heartwood (903_800, BLOCK_TESTNET_903800_BYTES.as_ref()), (903_801, BLOCK_TESTNET_903801_BYTES.as_ref()), (914_678, BLOCK_TESTNET_914678_BYTES.as_ref()), (925_483, BLOCK_TESTNET_925483_BYTES.as_ref()), (1_028_499, BLOCK_TESTNET_1028499_BYTES.as_ref()), // Canopy (1_028_500, BLOCK_TESTNET_1028500_BYTES.as_ref()), (1_028_501, BLOCK_TESTNET_1028501_BYTES.as_ref()), (1_095_000, BLOCK_TESTNET_1095000_BYTES.as_ref()), (1_101_629, BLOCK_TESTNET_1101629_BYTES.as_ref()), // TODO: First Halving, see #1104 ].iter().cloned() ); // Mainnet // Genesis/BeforeOverwinter // for i in `seq 0 9`; do // zcash-cli getblock $i 0 > block-main--000-00$i.txt // done pub static ref BLOCK_MAINNET_GENESIS_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-000.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_1_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-001.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_2_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-002.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_3_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-003.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_4_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-004.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_5_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-005.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_6_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-006.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_7_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-007.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_8_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-008.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_9_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-009.txt").trim()) .expect("Block bytes are in valid hex representation"); // zcash-cli getblock 10 0 > block-main-0-000-010.txt pub static ref BLOCK_MAINNET_10_BYTES: Vec = >::from_hex(include_str!("block-main-0-000-010.txt").trim()) .expect("Block bytes are in valid hex representation"); // Overwinter transition // for i in 347499 347500 347501; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_MAINNET_347499_BYTES: Vec = >::from_hex(include_str!("block-main-0-347-499.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_347500_BYTES: Vec = >::from_hex(include_str!("block-main-0-347-500.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_347501_BYTES: Vec = >::from_hex(include_str!("block-main-0-347-501.txt").trim()) .expect("Block bytes are in valid hex representation"); // zcash-cli getblock 415000 0 > block-main-0-415-000.txt pub static ref BLOCK_MAINNET_415000_BYTES: Vec = >::from_hex(include_str!("block-main-0-415-000.txt").trim()) .expect("Block bytes are in valid hex representation"); // Sapling transition // for i in 419199 419200 419201; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_MAINNET_419199_BYTES: Vec = >::from_hex(include_str!("block-main-0-419-199.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_419200_BYTES: Vec = >::from_hex(include_str!("block-main-0-419-200.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_419201_BYTES: Vec = >::from_hex(include_str!("block-main-0-419-201.txt").trim()) .expect("Block bytes are in valid hex representation"); // this one has a bad version field // zcash-cli getblock 434873 0 > block-main-0-434-873.txt pub static ref BLOCK_MAINNET_434873_BYTES: Vec = >::from_hex(include_str!("block-main-0-434-873.txt").trim()) .expect("Block bytes are in valid hex representation"); // Blossom transition // for i in 653599 653600 653601; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_MAINNET_653599_BYTES: Vec = >::from_hex(include_str!("block-main-0-653-599.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_653600_BYTES: Vec = >::from_hex(include_str!("block-main-0-653-600.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_653601_BYTES: Vec = >::from_hex(include_str!("block-main-0-653-601.txt").trim()) .expect("Block bytes are in valid hex representation"); // Heartwood transition // i=902999 // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt pub static ref BLOCK_MAINNET_902999_BYTES: Vec = >::from_hex(include_str!("block-main-0-902-999.txt").trim()) .expect("Block bytes are in valid hex representation"); // for i in 903000 903001; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-00$[i%1000].txt // done pub static ref BLOCK_MAINNET_903000_BYTES: Vec = >::from_hex(include_str!("block-main-0-903-000.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_MAINNET_903001_BYTES: Vec = >::from_hex(include_str!("block-main-0-903-001.txt").trim()) .expect("Block bytes are in valid hex representation"); // Shielded coinbase // for i in 949496 982681; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done // i=975066 // zcash-cli getblock $i 0 > block-main-$[i/1000000]-$[i/1000%1000]-0$[i%1000].txt // First shielded coinbase block pub static ref BLOCK_MAINNET_949496_BYTES: Vec = >::from_hex(include_str!("block-main-0-949-496.txt").trim()) .expect("Block bytes are in valid hex representation"); // Largest shielded coinbase block so far (in bytes) pub static ref BLOCK_MAINNET_975066_BYTES: Vec = >::from_hex(include_str!("block-main-0-975-066.txt").trim()) .expect("Block bytes are in valid hex representation"); // Last shielded coinbase block so far pub static ref BLOCK_MAINNET_982681_BYTES: Vec = >::from_hex(include_str!("block-main-0-982-681.txt").trim()) .expect("Block bytes are in valid hex representation"); // TODO: Canopy transition, after mainnet canopy activation // for i in 1046399 1046400 1046401; do // zcash-cli getblock $i 0 > block-main-$[i/1000000]-0$[i/1000%1000]-$[i%1000].txt // done // TODO: one more Canopy Mainnet block // (so that we have at least 3 blocks from Canopy) // Note: don't use the highest block, it must be below the reorg limit! // Testnet // Genesis/BeforeOverwinter // for i in `seq 0 9`; do // zcash-cli -testnet getblock $i 0 > block-test-0-000-00$i.txt // done pub static ref BLOCK_TESTNET_GENESIS_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-000.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_1_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-001.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_2_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-002.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_3_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-003.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_4_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-004.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_5_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-005.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_6_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-006.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_7_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-007.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_8_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-008.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_9_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-009.txt").trim()) .expect("Block bytes are in valid hex representation"); // zcash-cli -testnet getblock 10 0 > block-test-0-000-010.txt pub static ref BLOCK_TESTNET_10_BYTES: Vec = >::from_hex(include_str!("block-test-0-000-010.txt").trim()) .expect("Block bytes are in valid hex representation"); // A large block // i=141042 // zcash-cli -testnet getblock $i 0 | xxd -revert -plain > block-test-$[i/1000000]-$[i/1000%1000]-0$[i%1000].bin // // Block 141042 is almost ~2 MB in size (the maximum size for a block), // and contains 1 coinbase reward transaction and 20 transactions. // In each transaction, there is one joinsplit, with 244 inputs and 0 outputs. // https://zcash.readthedocs.io/en/latest/rtd_pages/shield_coinbase.html // // We store large blocks as binary, to reduce disk and network usage. // (git compresses blocks in transit and in its index, so there is not much need for extra compression.) pub static ref BLOCK_TESTNET_141042_BYTES: Vec = include_bytes!("block-test-0-141-042.bin").to_vec(); // Overwinter transition // for i in 207499 207500 207501; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_TESTNET_207499_BYTES: Vec = >::from_hex(include_str!("block-test-0-207-499.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_207500_BYTES: Vec = >::from_hex(include_str!("block-test-0-207-500.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_207501_BYTES: Vec = >::from_hex(include_str!("block-test-0-207-501.txt").trim()) .expect("Block bytes are in valid hex representation"); // Sapling transition // i=279999 // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // for i in 280000 280001; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-00$[i%1000].txt // done pub static ref BLOCK_TESTNET_279999_BYTES: Vec = >::from_hex(include_str!("block-test-0-279-999.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_280000_BYTES: Vec = >::from_hex(include_str!("block-test-0-280-000.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_280001_BYTES: Vec = >::from_hex(include_str!("block-test-0-280-001.txt").trim()) .expect("Block bytes are in valid hex representation"); // Blossom transition // i=583999 // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // for i in 584000 584001; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-00$[i%1000].txt // done pub static ref BLOCK_TESTNET_583999_BYTES: Vec = >::from_hex(include_str!("block-test-0-583-999.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_584000_BYTES: Vec = >::from_hex(include_str!("block-test-0-584-000.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_584001_BYTES: Vec = >::from_hex(include_str!("block-test-0-584-001.txt").trim()) .expect("Block bytes are in valid hex representation"); // Heartwood transition // for i in 903799 903800 903801; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_TESTNET_903799_BYTES: Vec = >::from_hex(include_str!("block-test-0-903-799.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_903800_BYTES: Vec = >::from_hex(include_str!("block-test-0-903-800.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_903801_BYTES: Vec = >::from_hex(include_str!("block-test-0-903-801.txt").trim()) .expect("Block bytes are in valid hex representation"); // Shielded coinbase // for i in 914678 925483; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-$[i/1000%1000]-$[i%1000].txt // done // First shielded coinbase block pub static ref BLOCK_TESTNET_914678_BYTES: Vec = >::from_hex(include_str!("block-test-0-914-678.txt").trim()) .expect("Block bytes are in valid hex representation"); // Largest shielded coinbase block so far (in bytes) pub static ref BLOCK_TESTNET_925483_BYTES: Vec = >::from_hex(include_str!("block-test-0-925-483.txt").trim()) .expect("Block bytes are in valid hex representation"); // Canopy transition // for i in 1028499 1028500 1028501; do // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-0$[i/1000%1000]-$[i%1000].txt // done pub static ref BLOCK_TESTNET_1028499_BYTES: Vec = >::from_hex(include_str!("block-test-1-028-499.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_1028500_BYTES: Vec = >::from_hex(include_str!("block-test-1-028-500.txt").trim()) .expect("Block bytes are in valid hex representation"); pub static ref BLOCK_TESTNET_1028501_BYTES: Vec = >::from_hex(include_str!("block-test-1-028-501.txt").trim()) .expect("Block bytes are in valid hex representation"); // One more Canopy block // (so that we have at least 3 blocks from Canopy) // i=1095000 // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-0$[i/1000%1000]-00$[i%1000].txt pub static ref BLOCK_TESTNET_1095000_BYTES: Vec = >::from_hex(include_str!("block-test-1-095-000.txt").trim()) .expect("Block bytes are in valid hex representation"); // Shielded coinbase + Canopy // i=1101629 // zcash-cli -testnet getblock $i 0 > block-test-$[i/1000000]-0$[i/1000%1000]-$[i%1000].txt // Last shielded coinbase block so far pub static ref BLOCK_TESTNET_1101629_BYTES: Vec = >::from_hex(include_str!("block-test-1-101-629.txt").trim()) .expect("Block bytes are in valid hex representation"); } #[cfg(test)] mod test { use super::*; use std::collections::HashSet; use crate::init; #[test] fn block_test_vectors_unique() { init(); let block_count = BLOCKS.len(); let block_set: HashSet<_> = BLOCKS.iter().collect(); // putting the same block in two files is an easy mistake to make assert_eq!( block_count, block_set.len(), "block test vectors must be unique" ); } /// Make sure we use all the test vectors in the lists. /// /// We're using lazy_static! and combinators, so it would be easy to make this mistake. #[test] fn block_test_vectors_count() { init(); assert!( BLOCKS.len() > 50, "there should be a reasonable number of block test vectors" ); } }