Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move some tests into their own files #2060

Merged
merged 2 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions zebra-chain/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub use header::{BlockTimeError, CountedHeader, Header};
pub use height::Height;
pub use serialize::MAX_BLOCK_BYTES;

#[cfg(any(test, feature = "proptest-impl"))]
pub use arbitrary::LedgerState;

use serde::{Deserialize, Serialize};

use crate::{
Expand Down
40 changes: 38 additions & 2 deletions zebra-chain/src/block/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,49 @@ use chrono::{TimeZone, Utc};
use std::sync::Arc;

use crate::{
parameters::Network,
parameters::{Network, NetworkUpgrade},
work::{difficulty::CompactDifficulty, equihash},
LedgerState,
};

use super::*;

#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
/// The configuration data for proptest when generating arbitrary chains
pub struct LedgerState {
/// The tip height of the block or start of the chain
pub tip_height: Height,
/// The network to generate fake blocks for
pub network: Network,

/// Make this fake transaction a coinbase transaction
pub(crate) is_coinbase: bool,
}

impl LedgerState {
/// Construct a new ledger state for generating arbitrary chains via proptest
pub fn new(tip_height: Height, network: Network) -> Self {
Self {
tip_height,
is_coinbase: true,
network,
}
}
}

impl Default for LedgerState {
fn default() -> Self {
let network = Network::Mainnet;
let tip_height = NetworkUpgrade::Canopy.activation_height(network).unwrap();

Self {
tip_height,
is_coinbase: true,
network,
}
}
}

impl Arbitrary for Block {
type Parameters = LedgerState;

Expand Down
39 changes: 1 addition & 38 deletions zebra-chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,5 @@ pub mod transaction;
pub mod transparent;
pub mod work;

#[derive(Debug, Clone, Copy)]
#[cfg(any(test, feature = "proptest-impl"))]
#[non_exhaustive]
/// The configuration data for proptest when generating arbitrary chains
pub struct LedgerState {
/// The tip height of the block or start of the chain
pub tip_height: block::Height,
is_coinbase: bool,
/// The network to generate fake blocks for
pub network: parameters::Network,
}

#[cfg(any(test, feature = "proptest-impl"))]
impl LedgerState {
/// Construct a new ledger state for generating arbitrary chains via proptest
pub fn new(tip_height: block::Height, network: parameters::Network) -> Self {
Self {
tip_height,
is_coinbase: true,
network,
}
}
}

#[cfg(any(test, feature = "proptest-impl"))]
impl Default for LedgerState {
fn default() -> Self {
let network = parameters::Network::Mainnet;
let tip_height = parameters::NetworkUpgrade::Canopy
.activation_height(network)
.unwrap();

Self {
tip_height,
is_coinbase: true,
network,
}
}
}
pub use block::LedgerState;
3 changes: 1 addition & 2 deletions zebra-chain/src/transaction/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use std::{convert::TryInto, sync::Arc};
use chrono::{TimeZone, Utc};
use proptest::{arbitrary::any, array, collection::vec, option, prelude::*};

use crate::LedgerState;
use crate::{
amount::Amount,
block,
parameters::NetworkUpgrade,
primitives::{Bctv14Proof, Groth16Proof, ZkSnarkProof},
sapling, sprout, transparent,
sapling, sprout, transparent, LedgerState,
};

use super::{FieldNotPresent, JoinSplitData, LockTime, Memo, Transaction};
Expand Down
244 changes: 5 additions & 239 deletions zebra-state/src/service/non_finalized_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
mod chain;
mod queued_blocks;

#[cfg(any(test, feature = "proptest-impl"))]
mod arbitrary;
#[cfg(test)]
mod tests;

pub use queued_blocks::QueuedBlocks;

use std::{collections::BTreeSet, mem, ops::Deref, sync::Arc};
Expand Down Expand Up @@ -271,242 +276,3 @@ impl NonFinalizedState {
metrics::gauge!("state.memory.best.chain.length", self.best_chain_len() as _);
}
}

#[cfg(test)]
mod tests {
use zebra_chain::serialization::ZcashDeserializeInto;
use zebra_test::prelude::*;

use crate::tests::{FakeChainHelper, Prepare};

use self::assert_eq;
use super::*;

#[test]
fn best_chain_wins() -> Result<()> {
zebra_test::init();

best_chain_wins_for_network(Network::Mainnet)?;
best_chain_wins_for_network(Network::Testnet)?;

Ok(())
}

fn best_chain_wins_for_network(network: Network) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let block2 = block1.make_fake_child().set_work(10);
let child = block1.make_fake_child().set_work(1);

let expected_hash = block2.hash();

let mut state = NonFinalizedState::default();
state.commit_new_chain(block2.prepare());
state.commit_new_chain(child.prepare());

let best_chain = state.best_chain().unwrap();
assert!(best_chain.height_by_hash.contains_key(&expected_hash));

Ok(())
}

#[test]
fn finalize_pops_from_best_chain() -> Result<()> {
zebra_test::init();

finalize_pops_from_best_chain_for_network(Network::Mainnet)?;
finalize_pops_from_best_chain_for_network(Network::Testnet)?;

Ok(())
}

fn finalize_pops_from_best_chain_for_network(network: Network) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let block2 = block1.make_fake_child().set_work(10);
let child = block1.make_fake_child().set_work(1);

let mut state = NonFinalizedState::default();
state.commit_new_chain(block1.clone().prepare());
state.commit_block(block2.clone().prepare());
state.commit_block(child.prepare());

let finalized = state.finalize();
assert_eq!(block1, finalized.block);

let finalized = state.finalize();
assert_eq!(block2, finalized.block);

assert!(state.best_chain().is_none());

Ok(())
}

#[test]
// This test gives full coverage for `take_chain_if`
fn commit_block_extending_best_chain_doesnt_drop_worst_chains() -> Result<()> {
zebra_test::init();

commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(Network::Mainnet)?;
commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(Network::Testnet)?;

Ok(())
}

fn commit_block_extending_best_chain_doesnt_drop_worst_chains_for_network(
network: Network,
) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let block2 = block1.make_fake_child().set_work(10);
let child1 = block1.make_fake_child().set_work(1);
let child2 = block2.make_fake_child().set_work(1);

let mut state = NonFinalizedState::default();
assert_eq!(0, state.chain_set.len());
state.commit_new_chain(block1.prepare());
assert_eq!(1, state.chain_set.len());
state.commit_block(block2.prepare());
assert_eq!(1, state.chain_set.len());
state.commit_block(child1.prepare());
assert_eq!(2, state.chain_set.len());
state.commit_block(child2.prepare());
assert_eq!(2, state.chain_set.len());

Ok(())
}

#[test]
fn shorter_chain_can_be_best_chain() -> Result<()> {
zebra_test::init();

shorter_chain_can_be_best_chain_for_network(Network::Mainnet)?;
shorter_chain_can_be_best_chain_for_network(Network::Testnet)?;

Ok(())
}

fn shorter_chain_can_be_best_chain_for_network(network: Network) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let long_chain_block1 = block1.make_fake_child().set_work(1);
let long_chain_block2 = long_chain_block1.make_fake_child().set_work(1);

let short_chain_block = block1.make_fake_child().set_work(3);

let mut state = NonFinalizedState::default();
state.commit_new_chain(block1.prepare());
state.commit_block(long_chain_block1.prepare());
state.commit_block(long_chain_block2.prepare());
state.commit_block(short_chain_block.prepare());
assert_eq!(2, state.chain_set.len());

assert_eq!(2, state.best_chain_len());

Ok(())
}

#[test]
fn longer_chain_with_more_work_wins() -> Result<()> {
zebra_test::init();

longer_chain_with_more_work_wins_for_network(Network::Mainnet)?;
longer_chain_with_more_work_wins_for_network(Network::Testnet)?;

Ok(())
}

fn longer_chain_with_more_work_wins_for_network(network: Network) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let long_chain_block1 = block1.make_fake_child().set_work(1);
let long_chain_block2 = long_chain_block1.make_fake_child().set_work(1);
let long_chain_block3 = long_chain_block2.make_fake_child().set_work(1);
let long_chain_block4 = long_chain_block3.make_fake_child().set_work(1);

let short_chain_block = block1.make_fake_child().set_work(3);

let mut state = NonFinalizedState::default();
state.commit_new_chain(block1.prepare());
state.commit_block(long_chain_block1.prepare());
state.commit_block(long_chain_block2.prepare());
state.commit_block(long_chain_block3.prepare());
state.commit_block(long_chain_block4.prepare());
state.commit_block(short_chain_block.prepare());
assert_eq!(2, state.chain_set.len());

assert_eq!(5, state.best_chain_len());

Ok(())
}

#[test]
fn equal_length_goes_to_more_work() -> Result<()> {
zebra_test::init();

equal_length_goes_to_more_work_for_network(Network::Mainnet)?;
equal_length_goes_to_more_work_for_network(Network::Testnet)?;

Ok(())
}
fn equal_length_goes_to_more_work_for_network(network: Network) -> Result<()> {
let block1: Arc<Block> = match network {
Network::Mainnet => {
zebra_test::vectors::BLOCK_MAINNET_1180900_BYTES.zcash_deserialize_into()?
}
Network::Testnet => {
zebra_test::vectors::BLOCK_TESTNET_1326100_BYTES.zcash_deserialize_into()?
}
};

let less_work_child = block1.make_fake_child().set_work(1);
let more_work_child = block1.make_fake_child().set_work(3);
let expected_hash = more_work_child.hash();

let mut state = NonFinalizedState::default();
state.commit_new_chain(block1.prepare());
state.commit_block(less_work_child.prepare());
state.commit_block(more_work_child.prepare());
assert_eq!(2, state.chain_set.len());

let tip_hash = state.best_tip().unwrap().1;
assert_eq!(expected_hash, tip_hash);

Ok(())
}
}
Loading