From ea2092ae210c810a0e4a0053fb35d7181c29bff6 Mon Sep 17 00:00:00 2001 From: Antioch Peverell Date: Tue, 17 Dec 2019 15:17:45 +0000 Subject: [PATCH] rework orphan block validation (pow_only) (#3172) --- chain/src/pipe.rs | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 5c82afd38..dd1cdc96a 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -54,16 +54,19 @@ fn check_known(header: &BlockHeader, ctx: &mut BlockContext<'_>) -> Result<(), E } // Validate only the proof of work in a block header. -// Used to cheaply validate orphans in process_block before adding them to OrphanBlockPool. +// Used to cheaply validate pow before checking if orphan or continuing block validation. fn validate_pow_only(header: &BlockHeader, ctx: &mut BlockContext<'_>) -> Result<(), Error> { + if ctx.opts.contains(Options::SKIP_POW) { + // Some of our tests require this check to be skipped (we should revisit this). + return Ok(()); + } if !header.pow.is_primary() && !header.pow.is_secondary() { return Err(ErrorKind::LowEdgebits.into()); } - let edge_bits = header.pow.edge_bits(); if !(ctx.pow_verifier)(header).is_ok() { error!( "pipe: error validating header with cuckoo edge_bits {}", - edge_bits + header.pow.edge_bits(), ); return Err(ErrorKind::InvalidPow.into()); } @@ -86,20 +89,22 @@ pub fn process_block(b: &Block, ctx: &mut BlockContext<'_>) -> Result) -> Result<( // check the pow hash shows a difficulty at least as large // as the target difficulty if !ctx.opts.contains(Options::SKIP_POW) { + // Quick check of this header in isolation. No point proceeding if this fails. + // We can do this without needing to iterate over previous headers. + validate_pow_only(header, ctx)?; + if header.total_difficulty() <= prev.total_difficulty() { return Err(ErrorKind::DifficultyTooLow.into()); }