2020-08-15 00:14:07 -07:00
|
|
|
use crate::{
|
2021-11-05 11:24:24 -07:00
|
|
|
block::{Block, MAX_BLOCK_BYTES},
|
|
|
|
serialization::{CompactSizeMessage, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize},
|
|
|
|
work::equihash::{Solution, SOLUTION_SIZE},
|
2020-08-15 00:14:07 -07:00
|
|
|
};
|
|
|
|
|
2021-11-05 11:24:24 -07:00
|
|
|
use super::super::*;
|
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
/// Includes the 32-byte nonce.
|
2020-08-15 00:14:07 -07:00
|
|
|
const EQUIHASH_SOLUTION_BLOCK_OFFSET: usize = equihash::Solution::INPUT_LENGTH + 32;
|
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
/// Includes the 3-byte equihash length field.
|
|
|
|
const BLOCK_HEADER_LENGTH: usize = EQUIHASH_SOLUTION_BLOCK_OFFSET + 3 + equihash::SOLUTION_SIZE;
|
|
|
|
|
2020-08-15 00:14:07 -07:00
|
|
|
#[test]
|
2020-10-28 04:59:57 -07:00
|
|
|
fn equihash_solution_test_vectors() {
|
2022-08-04 08:44:44 -07:00
|
|
|
let _init_guard = zebra_test::init();
|
2020-08-15 00:14:07 -07:00
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
for block in zebra_test::vectors::BLOCKS.iter() {
|
|
|
|
let solution_bytes = &block[EQUIHASH_SOLUTION_BLOCK_OFFSET..BLOCK_HEADER_LENGTH];
|
|
|
|
|
|
|
|
let solution = solution_bytes
|
|
|
|
.zcash_deserialize_into::<equihash::Solution>()
|
|
|
|
.expect("Test vector EquihashSolution should deserialize");
|
2020-08-15 00:14:07 -07:00
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
let mut data = Vec::new();
|
|
|
|
solution
|
|
|
|
.zcash_serialize(&mut data)
|
|
|
|
.expect("Test vector EquihashSolution should serialize");
|
2020-08-15 00:14:07 -07:00
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
assert_eq!(solution_bytes.len(), data.len());
|
|
|
|
assert_eq!(solution_bytes, data.as_slice());
|
|
|
|
}
|
2020-08-15 00:14:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-10-28 04:59:57 -07:00
|
|
|
fn equihash_solution_test_vectors_are_valid() -> color_eyre::eyre::Result<()> {
|
2022-08-04 08:44:44 -07:00
|
|
|
let _init_guard = zebra_test::init();
|
2020-08-15 00:14:07 -07:00
|
|
|
|
2020-10-28 04:59:57 -07:00
|
|
|
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)?;
|
|
|
|
}
|
2020-08-15 00:14:07 -07:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-11-05 11:24:24 -07:00
|
|
|
|
|
|
|
static EQUIHASH_SIZE_TESTS: &[usize] = &[
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
SOLUTION_SIZE - 1,
|
|
|
|
SOLUTION_SIZE,
|
|
|
|
SOLUTION_SIZE + 1,
|
|
|
|
(MAX_BLOCK_BYTES - 1) as usize,
|
|
|
|
MAX_BLOCK_BYTES as usize,
|
|
|
|
];
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn equihash_solution_size_field() {
|
2022-08-04 08:44:44 -07:00
|
|
|
let _init_guard = zebra_test::init();
|
2021-11-05 11:24:24 -07:00
|
|
|
|
|
|
|
for size in EQUIHASH_SIZE_TESTS.iter().copied() {
|
|
|
|
let mut data = Vec::new();
|
|
|
|
|
|
|
|
let size: CompactSizeMessage = size
|
|
|
|
.try_into()
|
|
|
|
.expect("test size fits in MAX_PROTOCOL_MESSAGE_LEN");
|
|
|
|
size.zcash_serialize(&mut data)
|
|
|
|
.expect("CompactSize should serialize");
|
|
|
|
data.resize(data.len() + SOLUTION_SIZE, 0);
|
|
|
|
|
|
|
|
let result = Solution::zcash_deserialize(data.as_slice());
|
|
|
|
if size == SOLUTION_SIZE.try_into().unwrap() {
|
|
|
|
result.expect("Correct size field in EquihashSolution should deserialize");
|
|
|
|
} else {
|
|
|
|
result.expect_err("Wrong size field in EquihashSolution should fail on deserialize");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|