Use consensus rule that minimum difficulty is 10 (#251)

This commit is contained in:
AntiochP 2017-11-13 19:45:10 -05:00 committed by Ignotus Peverell
parent 596bbd9b6e
commit 10a1ddf5e8
3 changed files with 29 additions and 5 deletions

View file

@ -21,6 +21,7 @@ use time;
use core::consensus; use core::consensus;
use core::core::hash::{Hash, Hashed}; use core::core::hash::{Hash, Hashed};
use core::core::{Block, BlockHeader}; use core::core::{Block, BlockHeader};
use core::core::target::Difficulty;
use core::core::transaction; use core::core::transaction;
use types::*; use types::*;
use store; use store;
@ -182,6 +183,12 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
if !ctx.opts.intersects(SKIP_POW) { if !ctx.opts.intersects(SKIP_POW) {
// verify the proof of work and related parameters // 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::minimum() {
return Err(Error::DifficultyTooLow);
}
if header.total_difficulty != prev.total_difficulty.clone() + prev.pow.to_difficulty() { if header.total_difficulty != prev.total_difficulty.clone() + prev.pow.to_difficulty() {
return Err(Error::WrongTotalDifficulty); return Err(Error::WrongTotalDifficulty);
} }

View file

@ -20,6 +20,7 @@
//! here. //! here.
use std::fmt; use std::fmt;
use std::cmp::max;
use ser; use ser;
use core::target::Difficulty; use core::target::Difficulty;
@ -119,10 +120,10 @@ pub const DIFFICULTY_ADJUST_WINDOW: u64 = 23;
/// Average time span of the difficulty adjustment window /// Average time span of the difficulty adjustment window
pub const BLOCK_TIME_WINDOW: u64 = DIFFICULTY_ADJUST_WINDOW * BLOCK_TIME_SEC; pub const BLOCK_TIME_WINDOW: u64 = DIFFICULTY_ADJUST_WINDOW * BLOCK_TIME_SEC;
/// Maximum size time window used for difficutly adjustments /// Maximum size time window used for difficulty adjustments
pub const UPPER_TIME_BOUND: u64 = BLOCK_TIME_WINDOW * 4 / 3; pub const UPPER_TIME_BOUND: u64 = BLOCK_TIME_WINDOW * 4 / 3;
/// Minimum size time window used for difficutly adjustments /// Minimum size time window used for difficulty adjustments
pub const LOWER_TIME_BOUND: u64 = BLOCK_TIME_WINDOW * 5 / 6; pub const LOWER_TIME_BOUND: u64 = BLOCK_TIME_WINDOW * 5 / 6;
/// Error when computing the next difficulty adjustment. /// Error when computing the next difficulty adjustment.
@ -181,7 +182,7 @@ where
// Check we have enough blocks // Check we have enough blocks
if window_end.len() < (MEDIAN_TIME_WINDOW as usize) { if window_end.len() < (MEDIAN_TIME_WINDOW as usize) {
return Ok(Difficulty::from_num(MINIMUM_DIFFICULTY)); return Ok(Difficulty::minimum());
} }
// Calculating time medians at the beginning and end of the window. // Calculating time medians at the beginning and end of the window.
@ -203,7 +204,10 @@ where
ts_damp ts_damp
}; };
Ok(diff_avg * Difficulty::from_num(BLOCK_TIME_WINDOW) / Difficulty::from_num(adj_ts)) let difficulty =
diff_avg * Difficulty::from_num(BLOCK_TIME_WINDOW) / Difficulty::from_num(adj_ts);
Ok(max(difficulty, Difficulty::minimum()))
} }
/// Consensus rule that collections of items are sorted lexicographically over the wire. /// Consensus rule that collections of items are sorted lexicographically over the wire.
@ -319,6 +323,12 @@ mod test {
next_difficulty(repeat(200, 1000, just_enough)).unwrap(), next_difficulty(repeat(200, 1000, just_enough)).unwrap(),
Difficulty::from_num(750) Difficulty::from_num(750)
); );
// We should never drop below MINIMUM_DIFFICULTY (10)
assert_eq!(
next_difficulty(repeat(90, 10, just_enough)).unwrap(),
Difficulty::from_num(10)
);
} }
#[test] #[test]

View file

@ -25,6 +25,7 @@ use std::ops::{Add, Div, Mul, Sub};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use consensus;
use core::hash::Hash; use core::hash::Hash;
use ser::{self, Readable, Reader, Writeable, Writer}; use ser::{self, Readable, Reader, Writeable, Writer};
@ -38,7 +39,7 @@ pub struct Difficulty {
} }
impl Difficulty { impl Difficulty {
/// Difficulty of zero, which is practically invalid (not target can be /// Difficulty of zero, which is invalid (no target can be
/// calculated from it) but very useful as a start for additions. /// calculated from it) but very useful as a start for additions.
pub fn zero() -> Difficulty { pub fn zero() -> Difficulty {
Difficulty { num: 0 } Difficulty { num: 0 }
@ -46,10 +47,16 @@ impl Difficulty {
/// Difficulty of one, which is the minumum difficulty (when the hash /// Difficulty of one, which is the minumum difficulty (when the hash
/// equals the max target) /// equals the max target)
/// TODO - is this the minimum dificulty or is consensus::MINIMUM_DIFFICULTY the minimum?
pub fn one() -> Difficulty { pub fn one() -> Difficulty {
Difficulty { num: 1 } Difficulty { num: 1 }
} }
/// Minimum difficulty according to our consensus rules.
pub fn minimum() -> Difficulty {
Difficulty { num: consensus::MINIMUM_DIFFICULTY }
}
/// Convert a `u32` into a `Difficulty` /// Convert a `u32` into a `Difficulty`
pub fn from_num(num: u64) -> Difficulty { pub fn from_num(num: u64) -> Difficulty {
Difficulty { num: num } Difficulty { num: num }