From f10bfd5806f74737d8d8d79541cfcc3949cc3cf4 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 16 Jun 2020 23:29:00 +1000 Subject: [PATCH] consensus: Add a block time check function Add a function that checks the block header miner times against the node's local clock. (We'll use this function in the next commit.) Part of #477. --- Cargo.lock | 1 + zebra-consensus/Cargo.toml | 1 + zebra-consensus/src/verify.rs | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 61b7d4bc..fcd9dcd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2327,6 +2327,7 @@ version = "0.1.0" name = "zebra-consensus" version = "0.1.0" dependencies = [ + "chrono", "color-eyre", "futures-util", "spandoc", diff --git a/zebra-consensus/Cargo.toml b/zebra-consensus/Cargo.toml index 681d4c48..061fdc75 100644 --- a/zebra-consensus/Cargo.toml +++ b/zebra-consensus/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" [dependencies] zebra-chain = { path = "../zebra-chain" } zebra-state = { path = "../zebra-state" } +chrono = "0.4.11" futures-util = "0.3.5" tower = "0.3.1" diff --git a/zebra-consensus/src/verify.rs b/zebra-consensus/src/verify.rs index 428b7b37..2a349402 100644 --- a/zebra-consensus/src/verify.rs +++ b/zebra-consensus/src/verify.rs @@ -31,6 +31,43 @@ struct BlockVerifier { // TODO(jlusby): Error = Report ? type Error = Box; +/// Block validity checks +mod block { + use super::Error; + + use chrono::{Duration, Utc}; + use std::sync::Arc; + + use zebra_chain::block::Block; + + /// Check if the block header time is less than or equal to + /// 2 hours in the future, according to the node's local clock. + /// + /// 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."[S 7.5][7.5] + /// + /// [7.5]: https://zips.z.cash/protocol/protocol.pdf#blockheader + pub(super) fn node_time_check(block: Arc) -> Result<(), Error> { + let now = Utc::now(); + let two_hours_in_the_future = now + .checked_add_signed(Duration::hours(2)) + .ok_or("overflow when calculating 2 hours in the future")?; + + if block.header.time <= two_hours_in_the_future { + Ok(()) + } else { + Err("block header time is more than 2 hours in the future".into()) + } + } +} + /// The BlockVerifier service implementation. /// /// After verification, blocks are added to the underlying state service.