[T4] Rename all shiftsize / cuckoo_size to edge_bits and change value for T4 (#1752)

* replace all size_shift / cuckoo_size by edge_bits and change some constants for T4
* replace remaining occurrences of sizeshift
This commit is contained in:
John Tromp 2018-10-16 01:14:23 +02:00 committed by Ignotus Peverell
parent a41022f1e3
commit 34646ddf51
22 changed files with 136 additions and 137 deletions

View file

@ -502,7 +502,7 @@ pub struct BlockHeaderPrintable {
/// Nonce increment used to mine this block. /// Nonce increment used to mine this block.
pub nonce: u64, pub nonce: u64,
/// Size of the cuckoo graph /// Size of the cuckoo graph
pub cuckoo_size: u8, pub edge_bits: u8,
pub cuckoo_solution: Vec<u64>, pub cuckoo_solution: Vec<u64>,
/// Total accumulated difficulty since genesis block /// Total accumulated difficulty since genesis block
pub total_difficulty: u64, pub total_difficulty: u64,
@ -522,7 +522,7 @@ impl BlockHeaderPrintable {
range_proof_root: util::to_hex(h.range_proof_root.to_vec()), range_proof_root: util::to_hex(h.range_proof_root.to_vec()),
kernel_root: util::to_hex(h.kernel_root.to_vec()), kernel_root: util::to_hex(h.kernel_root.to_vec()),
nonce: h.pow.nonce, nonce: h.pow.nonce,
cuckoo_size: h.pow.cuckoo_sizeshift(), edge_bits: h.pow.edge_bits(),
cuckoo_solution: h.pow.proof.nonces.clone(), cuckoo_solution: h.pow.proof.nonces.clone(),
total_difficulty: h.pow.total_difficulty.to_num(), total_difficulty: h.pow.total_difficulty.to_num(),
total_kernel_offset: h.total_kernel_offset.to_hex(), total_kernel_offset: h.total_kernel_offset.to_hex(),

View file

@ -45,9 +45,9 @@ pub enum ErrorKind {
/// Addition of difficulties on all previous block is wrong /// Addition of difficulties on all previous block is wrong
#[fail(display = "Addition of difficulties on all previous blocks is wrong")] #[fail(display = "Addition of difficulties on all previous blocks is wrong")]
WrongTotalDifficulty, WrongTotalDifficulty,
/// Block header sizeshift is incorrect /// Block header edge_bits is lower than our min
#[fail(display = "Cuckoo size shift is invalid")] #[fail(display = "Cuckoo Size too small")]
InvalidSizeshift, LowEdgebits,
/// Scaling factor between primary and secondary PoW is invalid /// Scaling factor between primary and secondary PoW is invalid
#[fail(display = "Wrong scaling factor")] #[fail(display = "Wrong scaling factor")]
InvalidScaling, InvalidScaling,

View file

@ -371,13 +371,13 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
if !ctx.opts.contains(Options::SKIP_POW) { if !ctx.opts.contains(Options::SKIP_POW) {
if !header.pow.is_primary() && !header.pow.is_secondary() { if !header.pow.is_primary() && !header.pow.is_secondary() {
return Err(ErrorKind::InvalidSizeshift.into()); return Err(ErrorKind::LowEdgebits.into());
} }
let shift = header.pow.cuckoo_sizeshift(); let edge_bits = header.pow.edge_bits();
if !(ctx.pow_verifier)(header, shift).is_ok() { if !(ctx.pow_verifier)(header, edge_bits).is_ok() {
error!( error!(
LOGGER, LOGGER,
"pipe: error validating header with cuckoo shift size {}", shift "pipe: error validating header with cuckoo edge_bits {}", edge_bits
); );
return Err(ErrorKind::InvalidPow.into()); return Err(ErrorKind::InvalidPow.into());
} }

View file

@ -97,7 +97,7 @@ fn data_files() {
&mut b.header, &mut b.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
let _bhash = b.hash(); let _bhash = b.hash();

View file

@ -75,19 +75,19 @@ fn mine_empty_chain() {
chain.set_txhashset_roots(&mut b, false).unwrap(); chain.set_txhashset_roots(&mut b, false).unwrap();
let sizeshift = if n == 2 { let edge_bits = if n == 2 {
global::min_sizeshift() + 1 global::min_edge_bits() + 1
} else { } else {
global::min_sizeshift() global::min_edge_bits()
}; };
b.header.pow.proof.cuckoo_sizeshift = sizeshift; b.header.pow.proof.edge_bits = edge_bits;
pow::pow_size( pow::pow_size(
&mut b.header, &mut b.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
sizeshift, edge_bits,
).unwrap(); ).unwrap();
b.header.pow.proof.cuckoo_sizeshift = sizeshift; b.header.pow.proof.edge_bits = edge_bits;
let bhash = b.hash(); let bhash = b.hash();
chain.process_block(b, chain::Options::MINE).unwrap(); chain.process_block(b, chain::Options::MINE).unwrap();
@ -399,19 +399,19 @@ fn output_header_mappings() {
chain.set_txhashset_roots(&mut b, false).unwrap(); chain.set_txhashset_roots(&mut b, false).unwrap();
let sizeshift = if n == 2 { let edge_bits = if n == 2 {
global::min_sizeshift() + 1 global::min_edge_bits() + 1
} else { } else {
global::min_sizeshift() global::min_edge_bits()
}; };
b.header.pow.proof.cuckoo_sizeshift = sizeshift; b.header.pow.proof.edge_bits = edge_bits;
pow::pow_size( pow::pow_size(
&mut b.header, &mut b.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
sizeshift, edge_bits,
).unwrap(); ).unwrap();
b.header.pow.proof.cuckoo_sizeshift = sizeshift; b.header.pow.proof.edge_bits = edge_bits;
chain.process_block(b, chain::Options::MINE).unwrap(); chain.process_block(b, chain::Options::MINE).unwrap();

View file

@ -80,7 +80,7 @@ fn test_coinbase_maturity() {
&mut block.header, &mut block.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
assert_eq!(block.outputs().len(), 1); assert_eq!(block.outputs().len(), 1);
@ -137,7 +137,7 @@ fn test_coinbase_maturity() {
&mut block.header, &mut block.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
// mine enough blocks to increase the height sufficiently for // mine enough blocks to increase the height sufficiently for
@ -160,7 +160,7 @@ fn test_coinbase_maturity() {
&mut block.header, &mut block.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
chain.process_block(block, chain::Options::MINE).unwrap(); chain.process_block(block, chain::Options::MINE).unwrap();
@ -187,7 +187,7 @@ fn test_coinbase_maturity() {
&mut block.header, &mut block.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
let result = chain.process_block(block, chain::Options::MINE); let result = chain.process_block(block, chain::Options::MINE);

View file

@ -62,19 +62,20 @@ pub fn secondary_pow_ratio(height: u64) -> u64 {
/// Cuckoo-cycle proof size (cycle length) /// Cuckoo-cycle proof size (cycle length)
pub const PROOFSIZE: usize = 42; pub const PROOFSIZE: usize = 42;
/// Default Cuckoo Cycle size shift used for mining and validating. /// Default Cuckoo Cycle edge_bits, used for mining and validating.
pub const DEFAULT_MIN_SIZESHIFT: u8 = 30; pub const DEFAULT_MIN_EDGE_BITS: u8 = 30;
/// Secondary proof-of-work size shift, meant to be ASIC resistant. /// Secondary proof-of-work edge_bits, meant to be ASIC resistant.
pub const SECOND_POW_SIZESHIFT: u8 = 29; pub const SECOND_POW_EDGE_BITS: u8 = 29;
/// Original reference sizeshift to compute difficulty factors for higher /// Original reference edge_bits to compute difficulty factors for higher
/// Cuckoo graph sizes, changing this would hard fork /// Cuckoo graph sizes, changing this would hard fork
pub const REFERENCE_SIZESHIFT: u8 = 30; pub const BASE_EDGE_BITS: u8 = 24;
/// Default Cuckoo Cycle easiness, high enough to have good likeliness to find /// maximum scaling factor for secondary pow, enforced in diff retargetting
/// a solution. /// increasing scaling factor increases frequency of secondary blocks
pub const EASINESS: u32 = 50; /// ONLY IN TESTNET4 LIMITED TO ABOUT 8 TIMES THE NATURAL SCALE
pub const MAX_SECOND_POW_SCALE: u64 = 8 << 11;
/// Default number of blocks in the past when cross-block cut-through will start /// Default number of blocks in the past when cross-block cut-through will start
/// happening. Needs to be long enough to not overlap with a long reorg. /// happening. Needs to be long enough to not overlap with a long reorg.

View file

@ -158,11 +158,11 @@ fn fixed_size_of_serialized_header(_version: u16) -> usize {
} }
/// Serialized size of a BlockHeader /// Serialized size of a BlockHeader
pub fn serialized_size_of_header(version: u16, cuckoo_sizeshift: u8) -> usize { pub fn serialized_size_of_header(version: u16, edge_bits: u8) -> usize {
let mut size = fixed_size_of_serialized_header(version); let mut size = fixed_size_of_serialized_header(version);
size += mem::size_of::<u8>(); // pow.cuckoo_sizeshift size += mem::size_of::<u8>(); // pow.edge_bits
let nonce_bits = cuckoo_sizeshift as usize - 1; let nonce_bits = edge_bits as usize;
let bitvec_len = global::proofsize() * nonce_bits; let bitvec_len = global::proofsize() * nonce_bits;
size += bitvec_len / 8; // pow.nonces size += bitvec_len / 8; // pow.nonces
if bitvec_len % 8 != 0 { if bitvec_len % 8 != 0 {
@ -306,8 +306,8 @@ impl BlockHeader {
pub fn serialized_size(&self) -> usize { pub fn serialized_size(&self) -> usize {
let mut size = fixed_size_of_serialized_header(self.version); let mut size = fixed_size_of_serialized_header(self.version);
size += mem::size_of::<u8>(); // pow.cuckoo_sizeshift size += mem::size_of::<u8>(); // pow.edge_bits
let nonce_bits = self.pow.cuckoo_sizeshift() as usize - 1; let nonce_bits = self.pow.edge_bits() as usize;
let bitvec_len = global::proofsize() * nonce_bits; let bitvec_len = global::proofsize() * nonce_bits;
size += bitvec_len / 8; // pow.nonces size += bitvec_len / 8; // pow.nonces
if bitvec_len % 8 != 0 { if bitvec_len % 8 != 0 {

View file

@ -18,12 +18,11 @@
use consensus::HeaderInfo; use consensus::HeaderInfo;
use consensus::{ use consensus::{
BLOCK_TIME_SEC, COINBASE_MATURITY, CUT_THROUGH_HORIZON, DEFAULT_MIN_SIZESHIFT, BLOCK_TIME_SEC, COINBASE_MATURITY, CUT_THROUGH_HORIZON, DEFAULT_MIN_EDGE_BITS,
DIFFICULTY_ADJUST_WINDOW, INITIAL_DIFFICULTY, MEDIAN_TIME_WINDOW, PROOFSIZE, DIFFICULTY_ADJUST_WINDOW, INITIAL_DIFFICULTY, MEDIAN_TIME_WINDOW, PROOFSIZE,
REFERENCE_SIZESHIFT, BASE_EDGE_BITS,
}; };
use pow::{self, CuckatooContext, EdgeType, PoWContext}; use pow::{self, CuckatooContext, EdgeType, PoWContext};
/// An enum collecting sets of parameters used throughout the /// An enum collecting sets of parameters used throughout the
/// code wherever mining is needed. This should allow for /// code wherever mining is needed. This should allow for
/// different sets of parameters for different purposes, /// different sets of parameters for different purposes,
@ -33,14 +32,14 @@ use std::sync::RwLock;
/// Define these here, as they should be developer-set, not really tweakable /// Define these here, as they should be developer-set, not really tweakable
/// by users /// by users
/// Automated testing sizeshift /// Automated testing edge_bits
pub const AUTOMATED_TESTING_MIN_SIZESHIFT: u8 = 10; pub const AUTOMATED_TESTING_MIN_EDGE_BITS: u8 = 9;
/// Automated testing proof size /// Automated testing proof size
pub const AUTOMATED_TESTING_PROOF_SIZE: usize = 4; pub const AUTOMATED_TESTING_PROOF_SIZE: usize = 4;
/// User testing sizeshift /// User testing edge_bits
pub const USER_TESTING_MIN_SIZESHIFT: u8 = 19; pub const USER_TESTING_MIN_EDGE_BITS: u8 = 15;
/// User testing proof size /// User testing proof size
pub const USER_TESTING_PROOF_SIZE: usize = 42; pub const USER_TESTING_PROOF_SIZE: usize = 42;
@ -147,27 +146,27 @@ pub fn pow_type() -> PoWContextTypes {
PoWContextTypes::Cuckatoo PoWContextTypes::Cuckatoo
} }
/// The minimum acceptable sizeshift /// The minimum acceptable edge_bits
pub fn min_sizeshift() -> u8 { pub fn min_edge_bits() -> u8 {
let param_ref = CHAIN_TYPE.read().unwrap(); let param_ref = CHAIN_TYPE.read().unwrap();
match *param_ref { match *param_ref {
ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_SIZESHIFT, ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
ChainTypes::UserTesting => USER_TESTING_MIN_SIZESHIFT, ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
ChainTypes::Testnet1 => USER_TESTING_MIN_SIZESHIFT, ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS,
_ => DEFAULT_MIN_SIZESHIFT, _ => DEFAULT_MIN_EDGE_BITS,
} }
} }
/// Reference sizeshift used to compute factor on higher Cuckoo graph sizes, /// Reference edge_bits used to compute factor on higher Cuck(at)oo graph sizes,
/// while the min_sizeshift can be changed on a soft fork, changing /// while the min_edge_bits can be changed on a soft fork, changing
/// ref_sizeshift is a hard fork. /// base_edge_bits is a hard fork.
pub fn ref_sizeshift() -> u8 { pub fn base_edge_bits() -> u8 {
let param_ref = CHAIN_TYPE.read().unwrap(); let param_ref = CHAIN_TYPE.read().unwrap();
match *param_ref { match *param_ref {
ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_SIZESHIFT, ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
ChainTypes::UserTesting => USER_TESTING_MIN_SIZESHIFT, ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
ChainTypes::Testnet1 => USER_TESTING_MIN_SIZESHIFT, ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS,
_ => REFERENCE_SIZESHIFT, _ => BASE_EDGE_BITS,
} }
} }
@ -250,9 +249,9 @@ pub fn get_genesis_nonce() -> u64 {
match *param_ref { match *param_ref {
// won't make a difference // won't make a difference
ChainTypes::AutomatedTesting => 0, ChainTypes::AutomatedTesting => 0,
// Magic nonce for current genesis block at cuckoo16 // Magic nonce for current genesis block at cuckatoo15
ChainTypes::UserTesting => 27944, ChainTypes::UserTesting => 27944,
// Magic nonce for genesis block for testnet2 (cuckoo30) // Magic nonce for genesis block for testnet2 (cuckatoo29)
_ => panic!("Pre-set"), _ => panic!("Pre-set"),
} }
} }

View file

@ -130,7 +130,7 @@ macro_rules! to_edge {
} }
/// Utility struct to calculate commonly used Cuckoo parameters calculated /// Utility struct to calculate commonly used Cuckoo parameters calculated
/// from header, nonce, sizeshift, etc. /// from header, nonce, edge_bits, etc.
pub struct CuckooParams<T> pub struct CuckooParams<T>
where where
T: EdgeType, T: EdgeType,

View file

@ -246,7 +246,7 @@ where
match sol { match sol {
Ok(s) => { Ok(s) => {
let mut proof = Proof::new(map_vec!(s.to_vec(), |&n| n.to_u64().unwrap_or(0))); let mut proof = Proof::new(map_vec!(s.to_vec(), |&n| n.to_u64().unwrap_or(0)));
proof.cuckoo_sizeshift = self.params.edge_bits; proof.edge_bits = self.params.edge_bits;
return Ok(vec![proof]); return Ok(vec![proof]);
} }
Err(e) => match e.kind() { Err(e) => match e.kind() {
@ -398,21 +398,21 @@ mod test {
cuckoo_ctx.set_header_nonce(header.clone(), Some(39), true)?; cuckoo_ctx.set_header_nonce(header.clone(), Some(39), true)?;
let res = cuckoo_ctx.find_cycles()?; let res = cuckoo_ctx.find_cycles()?;
let mut proof = Proof::new(V1.to_vec()); let mut proof = Proof::new(V1.to_vec());
proof.cuckoo_sizeshift = 20; proof.edge_bits = 20;
assert_eq!(proof, res[0]); assert_eq!(proof, res[0]);
let mut cuckoo_ctx = CuckooContext::<T>::new(20, 42, 10)?; let mut cuckoo_ctx = CuckooContext::<T>::new(20, 42, 10)?;
cuckoo_ctx.set_header_nonce(header.clone(), Some(56), true)?; cuckoo_ctx.set_header_nonce(header.clone(), Some(56), true)?;
let res = cuckoo_ctx.find_cycles()?; let res = cuckoo_ctx.find_cycles()?;
let mut proof = Proof::new(V2.to_vec()); let mut proof = Proof::new(V2.to_vec());
proof.cuckoo_sizeshift = 20; proof.edge_bits = 20;
assert_eq!(proof, res[0]); assert_eq!(proof, res[0]);
//re-use context //re-use context
cuckoo_ctx.set_header_nonce(header, Some(66), true)?; cuckoo_ctx.set_header_nonce(header, Some(66), true)?;
let res = cuckoo_ctx.find_cycles()?; let res = cuckoo_ctx.find_cycles()?;
let mut proof = Proof::new(V3.to_vec()); let mut proof = Proof::new(V3.to_vec());
proof.cuckoo_sizeshift = 20; proof.edge_bits = 20;
assert_eq!(proof, res[0]); assert_eq!(proof, res[0]);
Ok(()) Ok(())
} }

View file

@ -79,7 +79,7 @@ pub fn mine_genesis_block() -> Result<Block, Error> {
// total_difficulty on the genesis header *is* the difficulty of that block // total_difficulty on the genesis header *is* the difficulty of that block
let genesis_difficulty = gen.header.pow.total_difficulty.clone(); let genesis_difficulty = gen.header.pow.total_difficulty.clone();
let sz = global::min_sizeshift(); let sz = global::min_edge_bits();
let proof_size = global::proofsize(); let proof_size = global::proofsize();
pow_size(&mut gen.header, genesis_difficulty, proof_size, sz)?; pow_size(&mut gen.header, genesis_difficulty, proof_size, sz)?;
@ -143,10 +143,10 @@ mod test {
&mut b.header, &mut b.header,
Difficulty::one(), Difficulty::one(),
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
assert!(b.header.pow.nonce != 310); assert!(b.header.pow.nonce != 310);
assert!(b.header.pow.to_difficulty() >= Difficulty::one()); assert!(b.header.pow.to_difficulty() >= Difficulty::one());
assert!(verify_size(&b.header, global::min_sizeshift()).is_ok()); assert!(verify_size(&b.header, global::min_edge_bits()).is_ok());
} }
} }

View file

@ -21,7 +21,7 @@ use std::{fmt, iter};
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use consensus::SECOND_POW_SIZESHIFT; use consensus::SECOND_POW_EDGE_BITS;
use core::hash::Hashed; use core::hash::Hashed;
use global; use global;
use ser::{self, Readable, Reader, Writeable, Writer}; use ser::{self, Readable, Reader, Writeable, Writer};
@ -80,16 +80,20 @@ impl Difficulty {
Difficulty { num: max(num, 1) } Difficulty { num: max(num, 1) }
} }
/// Compute difficulty scaling factor for graph defined by 2 * 2^edge_bits * edge_bits bits
pub fn scale(edge_bits: u8) -> u64 {
(2 << (edge_bits - global::base_edge_bits()) as u64) * (edge_bits as u64)
}
/// Computes the difficulty from a hash. Divides the maximum target by the /// Computes the difficulty from a hash. Divides the maximum target by the
/// provided hash and applies the Cuckoo sizeshift adjustment factor (see /// provided hash and applies the Cuck(at)oo size adjustment factor (see
/// https://lists.launchpad.net/mimblewimble/msg00494.html). /// https://lists.launchpad.net/mimblewimble/msg00494.html).
fn from_proof_adjusted(proof: &Proof) -> Difficulty { fn from_proof_adjusted(proof: &Proof) -> Difficulty {
// Adjust the difficulty based on a 2^(N-M)*(N-1) factor, with M being // Adjust the difficulty based on a 2^(N-M)*(N-1) factor, with M being
// the minimum sizeshift and N the provided sizeshift // the minimum edge_bits and N the provided edge_bits
let shift = proof.cuckoo_sizeshift; let edge_bits = proof.edge_bits;
let adjust_factor = (1 << (shift - global::ref_sizeshift()) as u64) * (shift as u64 - 1);
Difficulty::from_num(proof.raw_difficulty() * adjust_factor) Difficulty::from_num(proof.raw_difficulty() * Difficulty::scale(edge_bits))
} }
/// Same as `from_proof_adjusted` but instead of an adjustment based on /// Same as `from_proof_adjusted` but instead of an adjustment based on
@ -277,38 +281,38 @@ impl ProofOfWork {
pub fn to_difficulty(&self) -> Difficulty { pub fn to_difficulty(&self) -> Difficulty {
// 2 proof of works, Cuckoo29 (for now) and Cuckoo30+, which are scaled // 2 proof of works, Cuckoo29 (for now) and Cuckoo30+, which are scaled
// differently (scaling not controlled for now) // differently (scaling not controlled for now)
if self.proof.cuckoo_sizeshift == SECOND_POW_SIZESHIFT { if self.proof.edge_bits == SECOND_POW_EDGE_BITS {
Difficulty::from_proof_scaled(&self.proof, self.scaling_difficulty) Difficulty::from_proof_scaled(&self.proof, self.scaling_difficulty)
} else { } else {
Difficulty::from_proof_adjusted(&self.proof) Difficulty::from_proof_adjusted(&self.proof)
} }
} }
/// The shift used for the cuckoo cycle size on this proof /// The edge_bits used for the cuckoo cycle size on this proof
pub fn cuckoo_sizeshift(&self) -> u8 { pub fn edge_bits(&self) -> u8 {
self.proof.cuckoo_sizeshift self.proof.edge_bits
} }
/// Whether this proof of work is for the primary algorithm (as opposed /// Whether this proof of work is for the primary algorithm (as opposed
/// to secondary). Only depends on the size shift at this time. /// to secondary). Only depends on the edge_bits at this time.
pub fn is_primary(&self) -> bool { pub fn is_primary(&self) -> bool {
// 2 conditions are redundant right now but not necessarily in // 2 conditions are redundant right now but not necessarily in
// the future // the future
self.proof.cuckoo_sizeshift != SECOND_POW_SIZESHIFT self.proof.edge_bits != SECOND_POW_EDGE_BITS
&& self.proof.cuckoo_sizeshift >= global::min_sizeshift() && self.proof.edge_bits >= global::min_edge_bits()
} }
/// Whether this proof of work is for the secondary algorithm (as opposed /// Whether this proof of work is for the secondary algorithm (as opposed
/// to primary). Only depends on the size shift at this time. /// to primary). Only depends on the edge_bits at this time.
pub fn is_secondary(&self) -> bool { pub fn is_secondary(&self) -> bool {
self.proof.cuckoo_sizeshift == SECOND_POW_SIZESHIFT self.proof.edge_bits == SECOND_POW_EDGE_BITS
} }
} }
/// A Cuckoo Cycle proof of work, consisting of the shift to get the graph /// A Cuck(at)oo Cycle proof of work, consisting of the edge_bits to get the graph
/// size (i.e. 31 for Cuckoo31 with a 2^31 or 1<<31 graph size) and the nonces /// size (i.e. the 2-log of the number of edges) and the nonces
/// of the graph solution. While being expressed as u64 for simplicity, each /// of the graph solution. While being expressed as u64 for simplicity,
/// nonce is strictly less than half the cycle size (i.e. <2^30 for Cuckoo 31). /// nonces a.k.a. edge indices range from 0 to (1 << edge_bits) - 1
/// ///
/// The hash of the `Proof` is the hash of its packed nonces when serializing /// The hash of the `Proof` is the hash of its packed nonces when serializing
/// them at their exact bit size. The resulting bit sequence is padded to be /// them at their exact bit size. The resulting bit sequence is padded to be
@ -317,14 +321,14 @@ impl ProofOfWork {
#[derive(Clone, PartialOrd, PartialEq)] #[derive(Clone, PartialOrd, PartialEq)]
pub struct Proof { pub struct Proof {
/// Power of 2 used for the size of the cuckoo graph /// Power of 2 used for the size of the cuckoo graph
pub cuckoo_sizeshift: u8, pub edge_bits: u8,
/// The nonces /// The nonces
pub nonces: Vec<u64>, pub nonces: Vec<u64>,
} }
impl fmt::Debug for Proof { impl fmt::Debug for Proof {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Cuckoo{}(", self.cuckoo_sizeshift)?; write!(f, "Cuckoo{}(", self.edge_bits)?;
for (i, val) in self.nonces[..].iter().enumerate() { for (i, val) in self.nonces[..].iter().enumerate() {
write!(f, "{:x}", val)?; write!(f, "{:x}", val)?;
if i < self.nonces.len() - 1 { if i < self.nonces.len() - 1 {
@ -338,11 +342,11 @@ impl fmt::Debug for Proof {
impl Eq for Proof {} impl Eq for Proof {}
impl Proof { impl Proof {
/// Builds a proof with provided nonces at default sizeshift /// Builds a proof with provided nonces at default edge_bits
pub fn new(mut in_nonces: Vec<u64>) -> Proof { pub fn new(mut in_nonces: Vec<u64>) -> Proof {
in_nonces.sort(); in_nonces.sort();
Proof { Proof {
cuckoo_sizeshift: global::min_sizeshift(), edge_bits: global::min_edge_bits(),
nonces: in_nonces, nonces: in_nonces,
} }
} }
@ -350,7 +354,7 @@ impl Proof {
/// Builds a proof with all bytes zeroed out /// Builds a proof with all bytes zeroed out
pub fn zero(proof_size: usize) -> Proof { pub fn zero(proof_size: usize) -> Proof {
Proof { Proof {
cuckoo_sizeshift: global::min_sizeshift(), edge_bits: global::min_edge_bits(),
nonces: vec![0; proof_size], nonces: vec![0; proof_size],
} }
} }
@ -359,17 +363,17 @@ impl Proof {
/// needed so that tests that ignore POW /// needed so that tests that ignore POW
/// don't fail due to duplicate hashes /// don't fail due to duplicate hashes
pub fn random(proof_size: usize) -> Proof { pub fn random(proof_size: usize) -> Proof {
let sizeshift = global::min_sizeshift(); let edge_bits = global::min_edge_bits();
let nonce_mask = (1 << (sizeshift - 1)) - 1; let nonce_mask = (1 << edge_bits) - 1;
let mut rng = thread_rng(); let mut rng = thread_rng();
// force the random num to be within sizeshift bits // force the random num to be within edge_bits bits
let mut v: Vec<u64> = iter::repeat(()) let mut v: Vec<u64> = iter::repeat(())
.map(|()| (rng.gen::<u32>() & nonce_mask) as u64) .map(|()| (rng.gen::<u32>() & nonce_mask) as u64)
.take(proof_size) .take(proof_size)
.collect(); .collect();
v.sort(); v.sort();
Proof { Proof {
cuckoo_sizeshift: global::min_sizeshift(), edge_bits: global::min_edge_bits(),
nonces: v, nonces: v,
} }
} }
@ -387,16 +391,13 @@ impl Proof {
impl Readable for Proof { impl Readable for Proof {
fn read(reader: &mut Reader) -> Result<Proof, ser::Error> { fn read(reader: &mut Reader) -> Result<Proof, ser::Error> {
let cuckoo_sizeshift = reader.read_u8()?; let edge_bits = reader.read_u8()?;
if cuckoo_sizeshift == 0 || cuckoo_sizeshift > 64 { if edge_bits == 0 || edge_bits > 64 {
return Err(ser::Error::CorruptedData); return Err(ser::Error::CorruptedData);
} }
let mut nonces = Vec::with_capacity(global::proofsize()); let mut nonces = Vec::with_capacity(global::proofsize());
let mut nonce_bits = cuckoo_sizeshift as usize; let nonce_bits = edge_bits as usize;
if global::pow_type() == global::PoWContextTypes::Cuckoo {
nonce_bits -= 1;
}
let bytes_len = BitVec::bytes_len(nonce_bits * global::proofsize()); let bytes_len = BitVec::bytes_len(nonce_bits * global::proofsize());
let bits = reader.read_fixed_bytes(bytes_len)?; let bits = reader.read_fixed_bytes(bytes_len)?;
let bitvec = BitVec { bits }; let bitvec = BitVec { bits };
@ -410,7 +411,7 @@ impl Readable for Proof {
nonces.push(nonce); nonces.push(nonce);
} }
Ok(Proof { Ok(Proof {
cuckoo_sizeshift, edge_bits,
nonces, nonces,
}) })
} }
@ -419,13 +420,9 @@ impl Readable for Proof {
impl Writeable for Proof { impl Writeable for Proof {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> { fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
if writer.serialization_mode() != ser::SerializationMode::Hash { if writer.serialization_mode() != ser::SerializationMode::Hash {
writer.write_u8(self.cuckoo_sizeshift)?; writer.write_u8(self.edge_bits)?;
}
let mut nonce_bits = self.cuckoo_sizeshift as usize;
if global::pow_type() == global::PoWContextTypes::Cuckoo {
nonce_bits -= 1;
} }
let nonce_bits = self.edge_bits as usize;
let mut bitvec = BitVec::new(nonce_bits * global::proofsize()); let mut bitvec = BitVec::new(nonce_bits * global::proofsize());
for (n, nonce) in self.nonces.iter().enumerate() { for (n, nonce) in self.nonces.iter().enumerate() {
for bit in 0..nonce_bits { for bit in 0..nonce_bits {

View file

@ -78,7 +78,7 @@ Optionally return results as "compact blocks" by passing `?compact` query.
| - range_proof_root | string | Merklish root of all range proofs in the TxHashSet | | - range_proof_root | string | Merklish root of all range proofs in the TxHashSet |
| - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet | | - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet |
| - nonce | number | Nonce increment used to mine this block | | - nonce | number | Nonce increment used to mine this block |
| - cuckoo_size | number | Size of the cuckoo graph | | - edge_bits | number | Size of the cuckoo graph (2_log of number of edges) |
| - cuckoo_solution | []number | The Cuckoo solution for this block | | - cuckoo_solution | []number | The Cuckoo solution for this block |
| - total_difficulty | number | Total accumulated difficulty since genesis block | | - total_difficulty | number | Total accumulated difficulty since genesis block |
| - total_kernel_offset | string | Total kernel offset since genesis block | | - total_kernel_offset | string | Total kernel offset since genesis block |
@ -163,7 +163,7 @@ Returns data about a block headers given either a hash or height or an output co
| - range_proof_root | string | Merklish root of all range proofs in the TxHashSet | | - range_proof_root | string | Merklish root of all range proofs in the TxHashSet |
| - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet | | - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet |
| - nonce | number | Nonce increment used to mine this block | | - nonce | number | Nonce increment used to mine this block |
| - cuckoo_size | number | Size of the cuckoo graph | | - edge_bits | number | Size of the cuckoo graph (2_log of number of edges) |
| - cuckoo_solution | []number | The Cuckoo solution for this block | | - cuckoo_solution | []number | The Cuckoo solution for this block |
| - total_difficulty | number | Total accumulated difficulty since genesis block | | - total_difficulty | number | Total accumulated difficulty since genesis block |
| - total_kernel_offset | string | Total kernel offset since genesis block | | - total_kernel_offset | string | Total kernel offset since genesis block |

View file

@ -335,9 +335,9 @@ fn headers_header_size(conn: &mut TcpStream, msg_len: u64) -> Result<u64, Error>
} }
let average_header_size = (msg_len - 2) / total_headers; let average_header_size = (msg_len - 2) / total_headers;
// support size of Cuckoo: from Cuckoo 30 to Cuckoo 36, with version 2 // support size of Cuck(at)oo: from Cuck(at)oo 29 to Cuck(at)oo 35, with version 2
// having slightly larger headers // having slightly larger headers
let min_size = core::serialized_size_of_header(1, global::min_sizeshift()); let min_size = core::serialized_size_of_header(1, global::min_edge_bits());
let max_size = min_size + 6; let max_size = min_size + 6;
if average_header_size < min_size as u64 || average_header_size > max_size as u64 { if average_header_size < min_size as u64 || average_header_size > max_size as u64 {
debug!( debug!(

View file

@ -19,6 +19,8 @@ use std::sync::atomic::AtomicBool;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use std::time::SystemTime; use std::time::SystemTime;
use core::pow::Difficulty;
use chrono::prelude::*; use chrono::prelude::*;
use chain; use chain;
@ -98,7 +100,7 @@ pub struct StratumStats {
/// current network difficulty we're working on /// current network difficulty we're working on
pub network_difficulty: u64, pub network_difficulty: u64,
/// cuckoo size used for mining /// cuckoo size used for mining
pub cuckoo_size: u16, pub edge_bits: u16,
/// Individual worker status /// Individual worker status
pub worker_stats: Vec<WorkerStats>, pub worker_stats: Vec<WorkerStats>,
} }
@ -153,7 +155,7 @@ pub struct PeerStats {
impl StratumStats { impl StratumStats {
/// Calculate network hashrate /// Calculate network hashrate
pub fn network_hashrate(&self) -> f64 { pub fn network_hashrate(&self) -> f64 {
42.0 * (self.network_difficulty as f64 / (self.cuckoo_size - 1) as f64) / 60.0 42.0 * (self.network_difficulty as f64 / Difficulty::scale(self.edge_bits as u8) as f64) / 60.0
} }
} }
@ -207,7 +209,7 @@ impl Default for StratumStats {
num_workers: 0, num_workers: 0,
block_height: 0, block_height: 0,
network_difficulty: 1000, network_difficulty: 1000,
cuckoo_size: 30, edge_bits: 29,
worker_stats: Vec::new(), worker_stats: Vec::new(),
} }
} }

View file

@ -313,7 +313,7 @@ impl Server {
/// Start a minimal "stratum" mining service on a separate thread /// Start a minimal "stratum" mining service on a separate thread
pub fn start_stratum_server(&self, config: StratumServerConfig) { pub fn start_stratum_server(&self, config: StratumServerConfig) {
let cuckoo_size = global::min_sizeshift(); let edge_bits = global::min_edge_bits();
let proof_size = global::proofsize(); let proof_size = global::proofsize();
let sync_state = self.sync_state.clone(); let sync_state = self.sync_state.clone();
@ -327,7 +327,7 @@ impl Server {
let _ = thread::Builder::new() let _ = thread::Builder::new()
.name("stratum_server".to_string()) .name("stratum_server".to_string())
.spawn(move || { .spawn(move || {
stratum_server.run_loop(stratum_stats, cuckoo_size as u32, proof_size, sync_state); stratum_server.run_loop(stratum_stats, edge_bits as u32, proof_size, sync_state);
}); });
} }

View file

@ -75,7 +75,7 @@ struct SubmitParams {
height: u64, height: u64,
job_id: u64, job_id: u64,
nonce: u64, nonce: u64,
cuckoo_size: u32, edge_bits: u32,
pow: Vec<u64>, pow: Vec<u64>,
} }
@ -481,7 +481,7 @@ impl StratumServer {
} }
let mut b: Block = b.unwrap().clone(); let mut b: Block = b.unwrap().clone();
// Reconstruct the block header with this nonce and pow added // Reconstruct the block header with this nonce and pow added
b.header.pow.proof.cuckoo_sizeshift = params.cuckoo_size as u8; b.header.pow.proof.edge_bits = params.edge_bits as u8;
b.header.pow.nonce = params.nonce; b.header.pow.nonce = params.nonce;
b.header.pow.proof.nonces = params.pow; b.header.pow.proof.nonces = params.pow;
// Get share difficulty // Get share difficulty
@ -532,7 +532,7 @@ impl StratumServer {
); );
} else { } else {
// Do some validation but dont submit // Do some validation but dont submit
if !pow::verify_size(&b.header, b.header.pow.proof.cuckoo_sizeshift).is_ok() { if !pow::verify_size(&b.header, b.header.pow.proof.edge_bits).is_ok() {
// Return error status // Return error status
error!( error!(
LOGGER, LOGGER,
@ -653,15 +653,15 @@ impl StratumServer {
pub fn run_loop( pub fn run_loop(
&mut self, &mut self,
stratum_stats: Arc<RwLock<StratumStats>>, stratum_stats: Arc<RwLock<StratumStats>>,
cuckoo_size: u32, edge_bits: u32,
proof_size: usize, proof_size: usize,
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
) { ) {
info!( info!(
LOGGER, LOGGER,
"(Server ID: {}) Starting stratum server with cuckoo_size = {}, proof_size = {}", "(Server ID: {}) Starting stratum server with edge_bits = {}, proof_size = {}",
self.id, self.id,
cuckoo_size, edge_bits,
proof_size proof_size
); );
@ -693,7 +693,7 @@ impl StratumServer {
{ {
let mut stratum_stats = stratum_stats.write().unwrap(); let mut stratum_stats = stratum_stats.write().unwrap();
stratum_stats.is_running = true; stratum_stats.is_running = true;
stratum_stats.cuckoo_size = cuckoo_size as u16; stratum_stats.edge_bits = edge_bits as u16;
} }
warn!( warn!(

View file

@ -87,7 +87,7 @@ impl Miner {
LOGGER, LOGGER,
"(Server ID: {}) Mining Cuckoo{} for max {}s on {} @ {} [{}].", "(Server ID: {}) Mining Cuckoo{} for max {}s on {} @ {} [{}].",
self.debug_output_id, self.debug_output_id,
global::min_sizeshift(), global::min_edge_bits(),
attempt_time_per_block, attempt_time_per_block,
b.header.total_difficulty(), b.header.total_difficulty(),
b.header.height, b.header.height,
@ -97,7 +97,7 @@ impl Miner {
while head.hash() == *latest_hash && Utc::now().timestamp() < deadline { while head.hash() == *latest_hash && Utc::now().timestamp() < deadline {
let mut ctx = let mut ctx =
global::create_pow_context::<u32>(global::min_sizeshift(), global::proofsize(), 10) global::create_pow_context::<u32>(global::min_edge_bits(), global::proofsize(), 10)
.unwrap(); .unwrap();
ctx.set_header_nonce(b.header.pre_pow(), None, true) ctx.set_header_nonce(b.header.pre_pow(), None, true)
.unwrap(); .unwrap();

View file

@ -217,7 +217,7 @@ impl TUIStatusListener for TUIMiningView {
) )
.child( .child(
LinearLayout::new(Orientation::Horizontal) LinearLayout::new(Orientation::Horizontal)
.child(TextView::new(" ").with_id("stratum_cuckoo_size_status")), .child(TextView::new(" ").with_id("stratum_edge_bits_status")),
); );
let mining_device_view = LinearLayout::new(Orientation::Vertical) let mining_device_view = LinearLayout::new(Orientation::Vertical)
@ -320,7 +320,7 @@ impl TUIStatusListener for TUIMiningView {
let stratum_block_height = format!("Solving Block Height: {}", stratum_stats.block_height); let stratum_block_height = format!("Solving Block Height: {}", stratum_stats.block_height);
let stratum_network_difficulty = let stratum_network_difficulty =
format!("Network Difficulty: {}", stratum_stats.network_difficulty); format!("Network Difficulty: {}", stratum_stats.network_difficulty);
let stratum_cuckoo_size = format!("Cuckoo Size: {}", stratum_stats.cuckoo_size); let stratum_edge_bits = format!("Cuckoo Size: {}", stratum_stats.edge_bits);
c.call_on_id("stratum_config_status", |t: &mut TextView| { c.call_on_id("stratum_config_status", |t: &mut TextView| {
t.set_content(stratum_enabled); t.set_content(stratum_enabled);
@ -340,8 +340,8 @@ impl TUIStatusListener for TUIMiningView {
c.call_on_id("stratum_network_hashrate", |t: &mut TextView| { c.call_on_id("stratum_network_hashrate", |t: &mut TextView| {
t.set_content(stratum_network_hashrate); t.set_content(stratum_network_hashrate);
}); });
c.call_on_id("stratum_cuckoo_size_status", |t: &mut TextView| { c.call_on_id("stratum_edge_bits_status", |t: &mut TextView| {
t.set_content(stratum_cuckoo_size); t.set_content(stratum_edge_bits);
}); });
let _ = c.call_on_id( let _ = c.call_on_id(
TABLE_MINING_STATUS, TABLE_MINING_STATUS,

View file

@ -201,7 +201,7 @@ impl TUIStatusListener for TUIStatusView {
), ),
format!( format!(
"Cuckoo {} - Network Difficulty {}", "Cuckoo {} - Network Difficulty {}",
stats.mining_stats.cuckoo_size, stats.mining_stats.edge_bits,
stats.mining_stats.network_difficulty.to_string() stats.mining_stats.network_difficulty.to_string()
), ),
) )

View file

@ -103,7 +103,7 @@ pub fn add_block_with_reward(chain: &Chain, txs: Vec<&Transaction>, reward: CbDa
&mut b.header, &mut b.header,
next_header_info.difficulty, next_header_info.difficulty,
global::proofsize(), global::proofsize(),
global::min_sizeshift(), global::min_edge_bits(),
).unwrap(); ).unwrap();
chain.process_block(b, chain::Options::MINE).unwrap(); chain.process_block(b, chain::Options::MINE).unwrap();
chain.validate(false).unwrap(); chain.validate(false).unwrap();