mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Use consensus rule that minimum difficulty is 10 (#251)
This commit is contained in:
parent
596bbd9b6e
commit
10a1ddf5e8
3 changed files with 29 additions and 5 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in a new issue