Zebra/zebra-test/src/vectors/block.rs

437 lines
21 KiB
Rust

//! 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<u32, &'static [u8]> = 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<u32, &'static [u8]> = 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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> = 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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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<u8> =
<Vec<u8>>::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"
);
}
}