Move is_equihash_solution_valid to zebra-consensus
This commit is contained in:
parent
2a68ef5acb
commit
7118e4da3c
|
@ -1,6 +1,5 @@
|
|||
use chrono::{DateTime, Duration, Utc};
|
||||
|
||||
use crate::serialization::ZcashSerialize;
|
||||
use crate::work::{difficulty::CompactDifficulty, equihash::Solution};
|
||||
|
||||
use super::{merkle, Error, Hash};
|
||||
|
@ -69,24 +68,6 @@ pub struct Header {
|
|||
}
|
||||
|
||||
impl Header {
|
||||
/// Returns true if the header is valid based on its `EquihashSolution`
|
||||
pub fn is_equihash_solution_valid(&self) -> Result<(), EquihashError> {
|
||||
let n = 200;
|
||||
let k = 9;
|
||||
let nonce = &self.nonce;
|
||||
let solution = &self.solution.0;
|
||||
let mut input = Vec::new();
|
||||
|
||||
self.zcash_serialize(&mut input)
|
||||
.expect("serialization into a vec can't fail");
|
||||
|
||||
let input = &input[0..Solution::INPUT_LENGTH];
|
||||
|
||||
equihash::is_valid_solution(n, k, input, nonce, solution)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if `self.time` is less than or equal to
|
||||
/// 2 hours in the future, according to the node's local clock (`now`).
|
||||
///
|
||||
|
@ -112,8 +93,3 @@ impl Header {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("invalid equihash solution for BlockHeader")]
|
||||
pub struct EquihashError(#[from] equihash::Error);
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
//! Equihash Solution and related items.
|
||||
|
||||
use crate::block::Header;
|
||||
use crate::serialization::{
|
||||
serde_helpers, ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize,
|
||||
ZcashSerialize,
|
||||
};
|
||||
use std::{fmt, io};
|
||||
|
||||
/// The error type for Equihash
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("invalid equihash solution for BlockHeader")]
|
||||
pub struct Error(#[from] equihash::Error);
|
||||
|
||||
/// The size of an Equihash solution in bytes (always 1344).
|
||||
pub(crate) const SOLUTION_SIZE: usize = 1344;
|
||||
|
||||
|
@ -24,6 +31,25 @@ impl Solution {
|
|||
/// The length of the portion of the header used as input when verifying
|
||||
/// equihash solutions, in bytes
|
||||
pub const INPUT_LENGTH: usize = 4 + 32 * 3 + 4 * 2;
|
||||
|
||||
/// Returns true if the header is valid based on its `EquihashSolution`
|
||||
pub fn check(&self, block: &Header) -> Result<(), Error> {
|
||||
let n = 200;
|
||||
let k = 9;
|
||||
let nonce = &block.nonce;
|
||||
let solution = &self.0;
|
||||
let mut input = Vec::new();
|
||||
|
||||
block
|
||||
.zcash_serialize(&mut input)
|
||||
.expect("serialization into a vec can't fail");
|
||||
|
||||
let input = &input[0..Solution::INPUT_LENGTH];
|
||||
|
||||
equihash::is_valid_solution(n, k, input, nonce, solution)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Solution> for Solution {
|
||||
|
|
|
@ -39,11 +39,11 @@ fn equihash_prop_test_solution() -> color_eyre::eyre::Result<()> {
|
|||
for block_bytes in zebra_test::vectors::TEST_BLOCKS.iter() {
|
||||
let block = Block::zcash_deserialize(&block_bytes[..])
|
||||
.expect("block test vector should deserialize");
|
||||
block.header.is_equihash_solution_valid()?;
|
||||
block.header.solution.check(&block.header)?;
|
||||
|
||||
proptest!(|(fake_header in randomized_solutions(block.header))| {
|
||||
fake_header
|
||||
.is_equihash_solution_valid()
|
||||
fake_header.solution
|
||||
.check(&fake_header)
|
||||
.expect_err("block header should not validate on randomized solution");
|
||||
});
|
||||
}
|
||||
|
@ -71,11 +71,11 @@ fn equihash_prop_test_nonce() -> color_eyre::eyre::Result<()> {
|
|||
for block_bytes in zebra_test::vectors::TEST_BLOCKS.iter() {
|
||||
let block = Block::zcash_deserialize(&block_bytes[..])
|
||||
.expect("block test vector should deserialize");
|
||||
block.header.is_equihash_solution_valid()?;
|
||||
block.header.solution.check(&block.header)?;
|
||||
|
||||
proptest!(|(fake_header in randomized_nonce(block.header))| {
|
||||
fake_header
|
||||
.is_equihash_solution_valid()
|
||||
fake_header.solution
|
||||
.check(&fake_header)
|
||||
.expect_err("block header should not validate on randomized nonce");
|
||||
});
|
||||
}
|
||||
|
@ -106,11 +106,11 @@ fn equihash_prop_test_input() -> color_eyre::eyre::Result<()> {
|
|||
for block_bytes in zebra_test::vectors::TEST_BLOCKS.iter() {
|
||||
let block = Block::zcash_deserialize(&block_bytes[..])
|
||||
.expect("block test vector should deserialize");
|
||||
block.header.is_equihash_solution_valid()?;
|
||||
block.header.solution.check(&block.header)?;
|
||||
|
||||
proptest!(|(fake_header in randomized_input(block.header))| {
|
||||
fake_header
|
||||
.is_equihash_solution_valid()
|
||||
fake_header.solution
|
||||
.check(&fake_header)
|
||||
.expect_err("equihash solution should not validate on randomized input");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ fn equihash_solution_test_vector_is_valid() -> color_eyre::eyre::Result<()> {
|
|||
|
||||
let block = Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..])
|
||||
.expect("block test vector should deserialize");
|
||||
block.header.is_equihash_solution_valid()?;
|
||||
block.header.solution.check(&block.header)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ where
|
|||
if hash > difficulty_threshold {
|
||||
Err("Block failed the difficulty filter: hash must be less than or equal to the difficulty threshold.")?;
|
||||
}
|
||||
block.header.is_equihash_solution_valid()?;
|
||||
check::is_equihash_solution_valid(&block.header)?;
|
||||
|
||||
// Since errors cause an early exit, try to do the
|
||||
// quick checks first.
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
//! Consensus check functions
|
||||
|
||||
use super::*;
|
||||
use zebra_chain::block::Block;
|
||||
use zebra_chain::{
|
||||
block::{Block, Header},
|
||||
work::equihash,
|
||||
};
|
||||
|
||||
/// Check that there is exactly one coinbase transaction in `Block`, and that
|
||||
/// the coinbase transaction is the first transaction in the block.
|
||||
|
@ -25,3 +28,7 @@ pub fn is_coinbase_first(block: &Block) -> Result<(), Error> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_equihash_solution_valid(header: &Header) -> Result<(), equihash::Error> {
|
||||
header.solution.check(&header)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue