From d09c310bbcb88a10187d13835d336158ced191da Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 13 Oct 2020 13:38:49 +1000 Subject: [PATCH] Add failure tests for difficulty is valid --- zebra-consensus/src/block/tests.rs | 66 +++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/zebra-consensus/src/block/tests.rs b/zebra-consensus/src/block/tests.rs index be9ce0989..96b3f18fd 100644 --- a/zebra-consensus/src/block/tests.rs +++ b/zebra-consensus/src/block/tests.rs @@ -12,7 +12,11 @@ use color_eyre::eyre::{eyre, Report}; use once_cell::sync::Lazy; use tower::buffer::Buffer; -use zebra_chain::block::{self, Block}; +use zebra_chain::{ + block::{self, Block}, + work::difficulty::CompactDifficulty, + work::difficulty::ExpandedDifficulty, +}; use zebra_chain::{ parameters::{Network, NetworkUpgrade}, serialization::{ZcashDeserialize, ZcashDeserializeInto}, @@ -172,6 +176,66 @@ fn difficulty_is_valid_for_network(network: Network) -> Result<(), Report> { Ok(()) } +#[test] +fn difficulty_validation_failure() -> Result<(), Report> { + use crate::error::*; + + // Get a block in the mainnet, and mangle its difficulty field + let block = + Arc::::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..]) + .expect("block should deserialize"); + let mut block = Arc::try_unwrap(block).expect("block should unwrap"); + let height = block.coinbase_height().unwrap(); + let hash = block.hash(); + + // Set the difficulty field to an invalid value + block.header.difficulty_threshold = CompactDifficulty(u32::MAX); + + // Validate the block + let result = + check::difficulty_is_valid(&block.header, Network::Mainnet, &height, &hash).unwrap_err(); + let expected = BlockError::InvalidDifficulty(height, hash); + assert_eq!(expected, result); + + // Get a block in the testnet, but tell the validator it's from the mainnet + let block = + Arc::::zcash_deserialize(&zebra_test::vectors::BLOCK_TESTNET_925483_BYTES[..]) + .expect("block should deserialize"); + let block = Arc::try_unwrap(block).expect("block should unwrap"); + let height = block.coinbase_height().unwrap(); + let hash = block.hash(); + let difficulty_threshold = block.header.difficulty_threshold.to_expanded().unwrap(); + + // Validate the block as if it is a mainnet block + let result = + check::difficulty_is_valid(&block.header, Network::Mainnet, &height, &hash).unwrap_err(); + let expected = BlockError::TargetDifficultyLimit( + height, + hash, + difficulty_threshold, + Network::Mainnet, + ExpandedDifficulty::target_difficulty_limit(Network::Mainnet), + ); + assert_eq!(expected, result); + + // Get a block in the mainnet, but pass an easy hash to the validator + let block = + Arc::::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..]) + .expect("block should deserialize"); + let block = Arc::try_unwrap(block).expect("block should unwrap"); + let height = block.coinbase_height().unwrap(); + let bad_hash = block::Hash([0xff; 32]); + let difficulty_threshold = block.header.difficulty_threshold.to_expanded().unwrap(); + + // Validate the block + let result = check::difficulty_is_valid(&block.header, Network::Mainnet, &height, &bad_hash) + .unwrap_err(); + let expected = BlockError::DifficultyFilter(height, bad_hash, difficulty_threshold); + assert_eq!(expected, result); + + Ok(()) +} + #[test] fn equihash_is_valid_for_historical_blocks() -> Result<(), Report> { let block_iter = zebra_test::vectors::BLOCKS.iter();