Skip to content

Commit

Permalink
Create a test strategy for test vector chain
Browse files Browse the repository at this point in the history
Splits a chain loaded from the test vectors in two parts, containing the
blocks to finalize and the blocks to keep in the non-finalized state.
  • Loading branch information
jvff committed Aug 5, 2021
1 parent ad0a089 commit 1b8e092
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions zebra-state/src/service/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ use tower::{buffer::Buffer, util::BoxService, Service, ServiceExt};
use zebra_chain::{
block::Block,
parameters::{Network, NetworkUpgrade},
serialization::ZcashDeserializeInto,
serialization::{ZcashDeserialize, ZcashDeserializeInto},
transaction, transparent,
};
use zebra_test::{prelude::*, transcript::Transcript};

use crate::{
constants, init_test, tests::setup::partial_nu5_chain_strategy, BoxError, Request, Response,
arbitrary::Prepare,
constants, init_test,
tests::setup::{partial_nu5_chain_strategy, transaction_v4_from_coinbase},
BoxError, FinalizedBlock, PreparedBlock, Request, Response,
};

const LAST_BLOCK_HEIGHT: u32 = 10;
Expand Down Expand Up @@ -275,3 +278,49 @@ proptest! {
prop_assert_eq!(response, Ok(()));
}
}

/// Test strategy to generate a chain split in two from the test vectors.
///
/// Selects either the mainnet or testnet chain test vector and randomly splits the chain in two
/// lists of blocks. The first containing the blocks to be finalized (which always includes at
/// least the genesis blocks) and the blocks to be stored in the non-finalized state.
fn continuous_empty_blocks_from_test_vectors(
) -> impl Strategy<Value = (Network, Vec<FinalizedBlock>, Vec<PreparedBlock>)> {
any::<Network>()
.prop_flat_map(|network| {
// Select the test vector based on the network
let raw_blocks = match network {
Network::Mainnet => &*zebra_test::vectors::CONTINUOUS_MAINNET_BLOCKS,
Network::Testnet => &*zebra_test::vectors::CONTINUOUS_TESTNET_BLOCKS,
};

// Transform the test vector's block bytes into a vector of `PreparedBlock`s.
let blocks: Vec<_> = raw_blocks
.iter()
.map(|(_height, &block_bytes)| {
let mut block_reader: &[u8] = block_bytes;
let mut block = Block::zcash_deserialize(&mut block_reader)
.expect("Failed to deserialize block from test vector");

let coinbase = transaction_v4_from_coinbase(&block.transactions[0]);
block.transactions = vec![Arc::new(coinbase)];

Arc::new(block).prepare()
})
.collect();

// Always finalize the genesis block
let finalized_blocks_count = 1..blocks.len();

(Just(network), Just(blocks), finalized_blocks_count)
})
.prop_map(|(network, mut blocks, finalized_blocks_count)| {
let non_finalized_blocks = blocks.split_off(finalized_blocks_count);
let finalized_blocks: Vec<_> = blocks
.into_iter()
.map(|prepared_block| FinalizedBlock::from(prepared_block.block.clone()))
.collect();

(network, finalized_blocks, non_finalized_blocks)
})
}

0 comments on commit 1b8e092

Please sign in to comment.