diff --git a/zebra-chain/src/work/equihash.rs b/zebra-chain/src/work/equihash.rs index 2de4c6179..ce6cea601 100644 --- a/zebra-chain/src/work/equihash.rs +++ b/zebra-chain/src/work/equihash.rs @@ -29,7 +29,10 @@ pub struct Solution(#[serde(with = "serde_helpers::BigArray")] pub [u8; SOLUTION impl Solution { /// The length of the portion of the header used as input when verifying - /// equihash solutions, in bytes + /// equihash solutions, in bytes. + /// + /// Excludes the 32-byte nonce, which is passed as a separate argument + /// to the verification function. pub const INPUT_LENGTH: usize = 4 + 32 * 3 + 4 * 2; /// Returns `Ok(())` if `EquihashSolution` is valid for `header` diff --git a/zebra-chain/src/work/tests/vectors.rs b/zebra-chain/src/work/tests/vectors.rs index 9d5a558bd..885c2934b 100644 --- a/zebra-chain/src/work/tests/vectors.rs +++ b/zebra-chain/src/work/tests/vectors.rs @@ -5,33 +5,43 @@ use crate::{ serialization::{ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize}, }; +/// Includes the 32-byte nonce. const EQUIHASH_SOLUTION_BLOCK_OFFSET: usize = equihash::Solution::INPUT_LENGTH + 32; +/// Includes the 3-byte equihash length field. +const BLOCK_HEADER_LENGTH: usize = EQUIHASH_SOLUTION_BLOCK_OFFSET + 3 + equihash::SOLUTION_SIZE; + #[test] -fn equihash_solution_test_vector() { +fn equihash_solution_test_vectors() { zebra_test::init(); - let solution_bytes = - &zebra_test::vectors::HEADER_MAINNET_415000_BYTES[EQUIHASH_SOLUTION_BLOCK_OFFSET..]; - let solution = solution_bytes - .zcash_deserialize_into::() - .expect("Test vector EquihashSolution should deserialize"); + for block in zebra_test::vectors::BLOCKS.iter() { + let solution_bytes = &block[EQUIHASH_SOLUTION_BLOCK_OFFSET..BLOCK_HEADER_LENGTH]; - let mut data = Vec::new(); - solution - .zcash_serialize(&mut data) - .expect("Test vector EquihashSolution should serialize"); + let solution = solution_bytes + .zcash_deserialize_into::() + .expect("Test vector EquihashSolution should deserialize"); - assert_eq!(solution_bytes, data.as_slice()); + let mut data = Vec::new(); + solution + .zcash_serialize(&mut data) + .expect("Test vector EquihashSolution should serialize"); + + assert_eq!(solution_bytes.len(), data.len()); + assert_eq!(solution_bytes, data.as_slice()); + } } #[test] -fn equihash_solution_test_vector_is_valid() -> color_eyre::eyre::Result<()> { +fn equihash_solution_test_vectors_are_valid() -> color_eyre::eyre::Result<()> { zebra_test::init(); - let block = Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..]) - .expect("block test vector should deserialize"); - block.header.solution.check(&block.header)?; + for block in zebra_test::vectors::BLOCKS.iter() { + let block = + Block::zcash_deserialize(&block[..]).expect("block test vector should deserialize"); + + block.header.solution.check(&block.header)?; + } Ok(()) }