From 2552b34118dfcc2404452b1990c5d4582d025934 Mon Sep 17 00:00:00 2001
From: Antioch Peverell <30642645+antiochp@users.noreply.github.com>
Date: Thu, 15 Mar 2018 15:16:34 -0400
Subject: [PATCH] remove difficulty field from block_header (derive from
total_difficulty) (#777)
* remove difficulty field from block_header (derive from total_difficulty)
* address feedback on PR and general cleanup
* rustfmt
* rework pow/difficulty validation in pipe::validate_header
now that we only have total_difficulty available
* cleanup various todos
* rustfmt
* rework DifficultyIterator to track header and prev_header state
* rustfmt caught some garbage syntax
* cleanup
---
api/src/types.rs | 3 --
chain/src/pipe.rs | 53 ++++++++++++++-------------
chain/src/store.rs | 41 ++++++++++++++++-----
chain/tests/data_file_integrity.rs | 1 -
chain/tests/mine_simple_chain.rs | 3 +-
chain/tests/test_coinbase_maturity.rs | 7 ++--
core/src/core/block.rs | 19 +++-------
core/src/core/target.rs | 5 +--
core/src/genesis.rs | 2 -
doc/pow/pow.md | 2 -
grin/src/miner.rs | 23 +++++++-----
pow/src/lib.rs | 21 ++---------
12 files changed, 89 insertions(+), 91 deletions(-)
diff --git a/api/src/types.rs b/api/src/types.rs
index e8a23e0c6..23dd4806b 100644
--- a/api/src/types.rs
+++ b/api/src/types.rs
@@ -511,8 +511,6 @@ pub struct BlockHeaderPrintable {
pub kernel_root: String,
/// Nonce increment used to mine this block.
pub nonce: u64,
- /// Difficulty used to mine the block.
- pub difficulty: u64,
/// Total accumulated difficulty since genesis block
pub total_difficulty: u64,
}
@@ -529,7 +527,6 @@ impl BlockHeaderPrintable {
range_proof_root: util::to_hex(h.range_proof_root.to_vec()),
kernel_root: util::to_hex(h.kernel_root.to_vec()),
nonce: h.nonce,
- difficulty: h.difficulty.into_num(),
total_difficulty: h.total_difficulty.into_num(),
}
}
diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs
index 9fb2e511d..7d7b297d3 100644
--- a/chain/src/pipe.rs
+++ b/chain/src/pipe.rs
@@ -272,6 +272,8 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
)),
}?;
+ // make sure this header has a height exactly one higher than the previous
+ // header
if header.height != prev.height + 1 {
return Err(Error::InvalidBlockHeight);
}
@@ -283,43 +285,44 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
return Err(Error::InvalidBlockTime);
}
+ // verify the proof of work and related parameters
+ // at this point we have a previous block header
+ // we know the height increased by one
+ // so now we can check the total_difficulty increase is also valid
+ // check the pow hash shows a difficulty at least as large
+ // as the target difficulty
if !ctx.opts.contains(Options::SKIP_POW) {
- // verify the proof of work and related parameters
-
- // explicit check to ensure we are not below the minimum difficulty
- // we will also check difficulty based on next_difficulty later on
- if header.difficulty < Difficulty::one() {
+ if header.total_difficulty.clone() <= prev.total_difficulty.clone() {
return Err(Error::DifficultyTooLow);
}
- let diff_iter = store::DifficultyIter::from(header.previous, ctx.store.clone());
- let difficulty =
- consensus::next_difficulty(diff_iter).map_err(|e| Error::Other(e.to_string()))?;
+ let target_difficulty = header.total_difficulty.clone() - prev.total_difficulty.clone();
+
+ if header.pow.clone().to_difficulty() < target_difficulty {
+ return Err(Error::DifficultyTooLow);
+ }
+
+ // explicit check to ensure we are not below the minimum difficulty
+ // we will also check difficulty based on next_difficulty later on
+ if target_difficulty < Difficulty::one() {
+ return Err(Error::DifficultyTooLow);
+ }
// explicit check to ensure total_difficulty has increased by exactly
// the _network_ difficulty of the previous block
// (during testnet1 we use _block_ difficulty here)
- if header.total_difficulty != prev.total_difficulty.clone() + difficulty.clone() {
+ let diff_iter = store::DifficultyIter::from(header.previous, ctx.store.clone());
+ let network_difficulty =
+ consensus::next_difficulty(diff_iter).map_err(|e| Error::Other(e.to_string()))?;
+ if target_difficulty != network_difficulty.clone() {
error!(
LOGGER,
"validate_header: BANNABLE OFFENCE: header cumulative difficulty {} != {}",
- header.difficulty.into_num(),
- prev.total_difficulty.into_num() + difficulty.into_num()
+ target_difficulty.into_num(),
+ prev.total_difficulty.into_num() + network_difficulty.into_num()
);
return Err(Error::WrongTotalDifficulty);
}
-
- // now check that the difficulty is not less than that calculated by the
- // difficulty iterator based on the previous block
- if header.difficulty < difficulty {
- error!(
- LOGGER,
- "validate_header: BANNABLE OFFENCE: header difficulty {} < {}",
- header.difficulty.into_num(),
- difficulty.into_num()
- );
- return Err(Error::DifficultyTooLow);
- }
}
Ok(())
@@ -416,7 +419,7 @@ fn update_head(b: &Block, ctx: &mut BlockContext) -> Result