Add wrapper fn is_time_valid_at in zebra_consensus::block::check
This commit doesn't move the fn itself because it's tests can't depend on `generate` code which is not exposed to other crates.
This commit is contained in:
parent
7118e4da3c
commit
3f25da996a
|
|
@ -68,20 +68,8 @@ pub struct Header {
|
|||
}
|
||||
|
||||
impl Header {
|
||||
/// Check if `self.time` is less than or equal to
|
||||
/// 2 hours in the future, according to the node's local clock (`now`).
|
||||
///
|
||||
/// This is a non-deterministic rule, as clocks vary over time, and
|
||||
/// between different nodes.
|
||||
///
|
||||
/// "In addition, a full validator MUST NOT accept blocks with nTime
|
||||
/// more than two hours in the future according to its clock. This
|
||||
/// is not strictly a consensus rule because it is nondeterministic,
|
||||
/// and clock time varies between nodes. Also note that a block that
|
||||
/// is rejected by this rule at a given point in time may later be
|
||||
/// accepted." [§7.5][7.5]
|
||||
///
|
||||
/// [7.5]: https://zips.z.cash/protocol/protocol.pdf#blockheader
|
||||
/// TODO Inline this function in zebra_consensus::block::check see
|
||||
/// https://github.com/ZcashFoundation/zebra/issues/1021 for more details
|
||||
pub fn is_time_valid_at(&self, now: DateTime<Utc>) -> Result<(), Error> {
|
||||
let two_hours_in_the_future = now
|
||||
.checked_add_signed(Duration::hours(2))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
use std::{
|
||||
io::{Cursor, Write},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
use chrono::{DateTime, Duration, LocalResult, TimeZone, Utc};
|
||||
|
||||
|
|
@ -145,25 +142,6 @@ fn block_limits_single_tx() {
|
|||
Block::zcash_deserialize(&data[..]).expect_err("block should not deserialize");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn time_check_past_block() {
|
||||
// This block is also verified as part of the BlockVerifier service
|
||||
// tests.
|
||||
let block =
|
||||
Arc::<Block>::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..])
|
||||
.expect("block should deserialize");
|
||||
let now = Utc::now();
|
||||
|
||||
// This check is non-deterministic, but BLOCK_MAINNET_415000 is
|
||||
// a long time in the past. So it's unlikely that the test machine
|
||||
// will have a clock that's far enough in the past for the test to
|
||||
// fail.
|
||||
block
|
||||
.header
|
||||
.is_time_valid_at(now)
|
||||
.expect("the header time from a mainnet block should be valid");
|
||||
}
|
||||
|
||||
/// Test wrapper for `BlockHeader.is_time_valid_at`.
|
||||
///
|
||||
/// Generates a block header, sets its `time` to `block_header_time`, then
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ where
|
|||
|
||||
// Field validity and structure checks
|
||||
let now = Utc::now();
|
||||
block.header.is_time_valid_at(now)?;
|
||||
check::is_time_valid_at(&block.header, now)?;
|
||||
check::is_coinbase_first(&block)?;
|
||||
|
||||
// TODO:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Consensus check functions
|
||||
|
||||
use super::*;
|
||||
use chrono::{DateTime, Utc};
|
||||
use zebra_chain::{
|
||||
block::{Block, Header},
|
||||
work::equihash,
|
||||
|
|
@ -29,6 +30,25 @@ pub fn is_coinbase_first(block: &Block) -> Result<(), Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns true if the header is valid based on its `EquihashSolution`
|
||||
pub fn is_equihash_solution_valid(header: &Header) -> Result<(), equihash::Error> {
|
||||
header.solution.check(&header)
|
||||
}
|
||||
|
||||
/// Check if `header.time` is less than or equal to
|
||||
/// 2 hours in the future, according to the node's local clock (`now`).
|
||||
///
|
||||
/// This is a non-deterministic rule, as clocks vary over time, and
|
||||
/// between different nodes.
|
||||
///
|
||||
/// "In addition, a full validator MUST NOT accept blocks with nTime
|
||||
/// more than two hours in the future according to its clock. This
|
||||
/// is not strictly a consensus rule because it is nondeterministic,
|
||||
/// and clock time varies between nodes. Also note that a block that
|
||||
/// is rejected by this rule at a given point in time may later be
|
||||
/// accepted." [§7.5][7.5]
|
||||
///
|
||||
/// [7.5]: https://zips.z.cash/protocol/protocol.pdf#blockheader
|
||||
pub fn is_time_valid_at(header: &Header, now: DateTime<Utc>) -> Result<(), Error> {
|
||||
header.is_time_valid_at(now)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use super::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Utc;
|
||||
use color_eyre::eyre::{eyre, Report};
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
@ -121,3 +123,20 @@ async fn check_transcripts() -> Result<(), Report> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn time_check_past_block() {
|
||||
// This block is also verified as part of the BlockVerifier service
|
||||
// tests.
|
||||
let block =
|
||||
Arc::<Block>::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..])
|
||||
.expect("block should deserialize");
|
||||
let now = Utc::now();
|
||||
|
||||
// This check is non-deterministic, but BLOCK_MAINNET_415000 is
|
||||
// a long time in the past. So it's unlikely that the test machine
|
||||
// will have a clock that's far enough in the past for the test to
|
||||
// fail.
|
||||
check::is_time_valid_at(&block.header, now)
|
||||
.expect("the header time from a mainnet block should be valid");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue