diff --git a/api/src/types.rs b/api/src/types.rs index eefd39896..ca37e8b06 100644 --- a/api/src/types.rs +++ b/api/src/types.rs @@ -502,7 +502,7 @@ pub struct BlockHeaderPrintable { /// Nonce increment used to mine this block. pub nonce: u64, /// Size of the cuckoo graph - pub cuckoo_size: u8, + pub edge_bits: u8, pub cuckoo_solution: Vec, /// Total accumulated difficulty since genesis block pub total_difficulty: u64, @@ -522,7 +522,7 @@ 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.pow.nonce, - cuckoo_size: h.pow.cuckoo_sizeshift(), + edge_bits: h.pow.edge_bits(), cuckoo_solution: h.pow.proof.nonces.clone(), total_difficulty: h.pow.total_difficulty.to_num(), total_kernel_offset: h.total_kernel_offset.to_hex(), diff --git a/chain/src/error.rs b/chain/src/error.rs index f3c6975a8..133a2bdd1 100644 --- a/chain/src/error.rs +++ b/chain/src/error.rs @@ -45,9 +45,9 @@ pub enum ErrorKind { /// Addition of difficulties on all previous block is wrong #[fail(display = "Addition of difficulties on all previous blocks is wrong")] WrongTotalDifficulty, - /// Block header sizeshift is incorrect - #[fail(display = "Cuckoo size shift is invalid")] - InvalidSizeshift, + /// Block header edge_bits is lower than our min + #[fail(display = "Cuckoo Size too small")] + LowEdgebits, /// Scaling factor between primary and secondary PoW is invalid #[fail(display = "Wrong scaling factor")] InvalidScaling, diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 523cb56e3..3a2fa2386 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -371,13 +371,13 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E if !ctx.opts.contains(Options::SKIP_POW) { 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(); - if !(ctx.pow_verifier)(header, shift).is_ok() { + let edge_bits = header.pow.edge_bits(); + if !(ctx.pow_verifier)(header, edge_bits).is_ok() { error!( 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()); } diff --git a/chain/tests/data_file_integrity.rs b/chain/tests/data_file_integrity.rs index 16506bfcc..f80a87386 100644 --- a/chain/tests/data_file_integrity.rs +++ b/chain/tests/data_file_integrity.rs @@ -97,7 +97,7 @@ fn data_files() { &mut b.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); let _bhash = b.hash(); diff --git a/chain/tests/mine_simple_chain.rs b/chain/tests/mine_simple_chain.rs index 121532c1d..095d89dbd 100644 --- a/chain/tests/mine_simple_chain.rs +++ b/chain/tests/mine_simple_chain.rs @@ -75,19 +75,19 @@ fn mine_empty_chain() { chain.set_txhashset_roots(&mut b, false).unwrap(); - let sizeshift = if n == 2 { - global::min_sizeshift() + 1 + let edge_bits = if n == 2 { + global::min_edge_bits() + 1 } 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( &mut b.header, next_header_info.difficulty, global::proofsize(), - sizeshift, + edge_bits, ).unwrap(); - b.header.pow.proof.cuckoo_sizeshift = sizeshift; + b.header.pow.proof.edge_bits = edge_bits; let bhash = b.hash(); chain.process_block(b, chain::Options::MINE).unwrap(); @@ -399,19 +399,19 @@ fn output_header_mappings() { chain.set_txhashset_roots(&mut b, false).unwrap(); - let sizeshift = if n == 2 { - global::min_sizeshift() + 1 + let edge_bits = if n == 2 { + global::min_edge_bits() + 1 } 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( &mut b.header, next_header_info.difficulty, global::proofsize(), - sizeshift, + edge_bits, ).unwrap(); - b.header.pow.proof.cuckoo_sizeshift = sizeshift; + b.header.pow.proof.edge_bits = edge_bits; chain.process_block(b, chain::Options::MINE).unwrap(); diff --git a/chain/tests/test_coinbase_maturity.rs b/chain/tests/test_coinbase_maturity.rs index 7a268d0cc..52215bd9d 100644 --- a/chain/tests/test_coinbase_maturity.rs +++ b/chain/tests/test_coinbase_maturity.rs @@ -80,7 +80,7 @@ fn test_coinbase_maturity() { &mut block.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); assert_eq!(block.outputs().len(), 1); @@ -137,7 +137,7 @@ fn test_coinbase_maturity() { &mut block.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); // mine enough blocks to increase the height sufficiently for @@ -160,7 +160,7 @@ fn test_coinbase_maturity() { &mut block.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); chain.process_block(block, chain::Options::MINE).unwrap(); @@ -187,7 +187,7 @@ fn test_coinbase_maturity() { &mut block.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); let result = chain.process_block(block, chain::Options::MINE); diff --git a/core/src/consensus.rs b/core/src/consensus.rs index b966b0eaa..2d3d90827 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -62,19 +62,20 @@ pub fn secondary_pow_ratio(height: u64) -> u64 { /// Cuckoo-cycle proof size (cycle length) pub const PROOFSIZE: usize = 42; -/// Default Cuckoo Cycle size shift used for mining and validating. -pub const DEFAULT_MIN_SIZESHIFT: u8 = 30; +/// Default Cuckoo Cycle edge_bits, used for mining and validating. +pub const DEFAULT_MIN_EDGE_BITS: u8 = 30; -/// Secondary proof-of-work size shift, meant to be ASIC resistant. -pub const SECOND_POW_SIZESHIFT: u8 = 29; +/// Secondary proof-of-work edge_bits, meant to be ASIC resistant. +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 -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 -/// a solution. -pub const EASINESS: u32 = 50; +/// maximum scaling factor for secondary pow, enforced in diff retargetting +/// increasing scaling factor increases frequency of secondary blocks +/// 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 /// happening. Needs to be long enough to not overlap with a long reorg. diff --git a/core/src/core/block.rs b/core/src/core/block.rs index fccb52e6a..dff2f86ee 100644 --- a/core/src/core/block.rs +++ b/core/src/core/block.rs @@ -158,11 +158,11 @@ fn fixed_size_of_serialized_header(_version: u16) -> usize { } /// 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); - size += mem::size_of::(); // pow.cuckoo_sizeshift - let nonce_bits = cuckoo_sizeshift as usize - 1; + size += mem::size_of::(); // pow.edge_bits + let nonce_bits = edge_bits as usize; let bitvec_len = global::proofsize() * nonce_bits; size += bitvec_len / 8; // pow.nonces if bitvec_len % 8 != 0 { @@ -306,8 +306,8 @@ impl BlockHeader { pub fn serialized_size(&self) -> usize { let mut size = fixed_size_of_serialized_header(self.version); - size += mem::size_of::(); // pow.cuckoo_sizeshift - let nonce_bits = self.pow.cuckoo_sizeshift() as usize - 1; + size += mem::size_of::(); // pow.edge_bits + let nonce_bits = self.pow.edge_bits() as usize; let bitvec_len = global::proofsize() * nonce_bits; size += bitvec_len / 8; // pow.nonces if bitvec_len % 8 != 0 { diff --git a/core/src/global.rs b/core/src/global.rs index f2248b0ff..7c9a24dfc 100644 --- a/core/src/global.rs +++ b/core/src/global.rs @@ -18,12 +18,11 @@ use consensus::HeaderInfo; 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, - REFERENCE_SIZESHIFT, + BASE_EDGE_BITS, }; use pow::{self, CuckatooContext, EdgeType, PoWContext}; - /// An enum collecting sets of parameters used throughout the /// code wherever mining is needed. This should allow for /// 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 /// by users -/// Automated testing sizeshift -pub const AUTOMATED_TESTING_MIN_SIZESHIFT: u8 = 10; +/// Automated testing edge_bits +pub const AUTOMATED_TESTING_MIN_EDGE_BITS: u8 = 9; /// Automated testing proof size pub const AUTOMATED_TESTING_PROOF_SIZE: usize = 4; -/// User testing sizeshift -pub const USER_TESTING_MIN_SIZESHIFT: u8 = 19; +/// User testing edge_bits +pub const USER_TESTING_MIN_EDGE_BITS: u8 = 15; /// User testing proof size pub const USER_TESTING_PROOF_SIZE: usize = 42; @@ -147,27 +146,27 @@ pub fn pow_type() -> PoWContextTypes { PoWContextTypes::Cuckatoo } -/// The minimum acceptable sizeshift -pub fn min_sizeshift() -> u8 { +/// The minimum acceptable edge_bits +pub fn min_edge_bits() -> u8 { let param_ref = CHAIN_TYPE.read().unwrap(); match *param_ref { - ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_SIZESHIFT, - ChainTypes::UserTesting => USER_TESTING_MIN_SIZESHIFT, - ChainTypes::Testnet1 => USER_TESTING_MIN_SIZESHIFT, - _ => DEFAULT_MIN_SIZESHIFT, + ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS, + ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS, + ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS, + _ => DEFAULT_MIN_EDGE_BITS, } } -/// Reference sizeshift used to compute factor on higher Cuckoo graph sizes, -/// while the min_sizeshift can be changed on a soft fork, changing -/// ref_sizeshift is a hard fork. -pub fn ref_sizeshift() -> u8 { +/// Reference edge_bits used to compute factor on higher Cuck(at)oo graph sizes, +/// while the min_edge_bits can be changed on a soft fork, changing +/// base_edge_bits is a hard fork. +pub fn base_edge_bits() -> u8 { let param_ref = CHAIN_TYPE.read().unwrap(); match *param_ref { - ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_SIZESHIFT, - ChainTypes::UserTesting => USER_TESTING_MIN_SIZESHIFT, - ChainTypes::Testnet1 => USER_TESTING_MIN_SIZESHIFT, - _ => REFERENCE_SIZESHIFT, + ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS, + ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS, + ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS, + _ => BASE_EDGE_BITS, } } @@ -250,9 +249,9 @@ pub fn get_genesis_nonce() -> u64 { match *param_ref { // won't make a difference ChainTypes::AutomatedTesting => 0, - // Magic nonce for current genesis block at cuckoo16 + // Magic nonce for current genesis block at cuckatoo15 ChainTypes::UserTesting => 27944, - // Magic nonce for genesis block for testnet2 (cuckoo30) + // Magic nonce for genesis block for testnet2 (cuckatoo29) _ => panic!("Pre-set"), } } diff --git a/core/src/pow/common.rs b/core/src/pow/common.rs index c3f73ca96..692670d32 100644 --- a/core/src/pow/common.rs +++ b/core/src/pow/common.rs @@ -130,7 +130,7 @@ macro_rules! to_edge { } /// Utility struct to calculate commonly used Cuckoo parameters calculated -/// from header, nonce, sizeshift, etc. +/// from header, nonce, edge_bits, etc. pub struct CuckooParams where T: EdgeType, diff --git a/core/src/pow/cuckoo.rs b/core/src/pow/cuckoo.rs index 8ea7c509d..afe863ece 100644 --- a/core/src/pow/cuckoo.rs +++ b/core/src/pow/cuckoo.rs @@ -246,7 +246,7 @@ where match sol { Ok(s) => { 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]); } Err(e) => match e.kind() { @@ -398,21 +398,21 @@ mod test { cuckoo_ctx.set_header_nonce(header.clone(), Some(39), true)?; let res = cuckoo_ctx.find_cycles()?; let mut proof = Proof::new(V1.to_vec()); - proof.cuckoo_sizeshift = 20; + proof.edge_bits = 20; assert_eq!(proof, res[0]); let mut cuckoo_ctx = CuckooContext::::new(20, 42, 10)?; cuckoo_ctx.set_header_nonce(header.clone(), Some(56), true)?; let res = cuckoo_ctx.find_cycles()?; let mut proof = Proof::new(V2.to_vec()); - proof.cuckoo_sizeshift = 20; + proof.edge_bits = 20; assert_eq!(proof, res[0]); //re-use context cuckoo_ctx.set_header_nonce(header, Some(66), true)?; let res = cuckoo_ctx.find_cycles()?; let mut proof = Proof::new(V3.to_vec()); - proof.cuckoo_sizeshift = 20; + proof.edge_bits = 20; assert_eq!(proof, res[0]); Ok(()) } diff --git a/core/src/pow/mod.rs b/core/src/pow/mod.rs index f9f7b0001..97f8f3ad6 100644 --- a/core/src/pow/mod.rs +++ b/core/src/pow/mod.rs @@ -79,7 +79,7 @@ pub fn mine_genesis_block() -> Result { // total_difficulty on the genesis header *is* the difficulty of that block 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(); pow_size(&mut gen.header, genesis_difficulty, proof_size, sz)?; @@ -143,10 +143,10 @@ mod test { &mut b.header, Difficulty::one(), global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); assert!(b.header.pow.nonce != 310); 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()); } } diff --git a/core/src/pow/types.rs b/core/src/pow/types.rs index 076a768b8..5d39a3462 100644 --- a/core/src/pow/types.rs +++ b/core/src/pow/types.rs @@ -21,7 +21,7 @@ use std::{fmt, iter}; use rand::{thread_rng, Rng}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; -use consensus::SECOND_POW_SIZESHIFT; +use consensus::SECOND_POW_EDGE_BITS; use core::hash::Hashed; use global; use ser::{self, Readable, Reader, Writeable, Writer}; @@ -80,16 +80,20 @@ impl Difficulty { 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 - /// 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). fn from_proof_adjusted(proof: &Proof) -> Difficulty { // Adjust the difficulty based on a 2^(N-M)*(N-1) factor, with M being - // the minimum sizeshift and N the provided sizeshift - let shift = proof.cuckoo_sizeshift; - let adjust_factor = (1 << (shift - global::ref_sizeshift()) as u64) * (shift as u64 - 1); + // the minimum edge_bits and N the provided edge_bits + let edge_bits = proof.edge_bits; - 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 @@ -277,38 +281,38 @@ impl ProofOfWork { pub fn to_difficulty(&self) -> Difficulty { // 2 proof of works, Cuckoo29 (for now) and Cuckoo30+, which are scaled // 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) } else { Difficulty::from_proof_adjusted(&self.proof) } } - /// The shift used for the cuckoo cycle size on this proof - pub fn cuckoo_sizeshift(&self) -> u8 { - self.proof.cuckoo_sizeshift + /// The edge_bits used for the cuckoo cycle size on this proof + pub fn edge_bits(&self) -> u8 { + self.proof.edge_bits } /// 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 { // 2 conditions are redundant right now but not necessarily in // the future - self.proof.cuckoo_sizeshift != SECOND_POW_SIZESHIFT - && self.proof.cuckoo_sizeshift >= global::min_sizeshift() + self.proof.edge_bits != SECOND_POW_EDGE_BITS + && self.proof.edge_bits >= global::min_edge_bits() } /// 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 { - 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 -/// size (i.e. 31 for Cuckoo31 with a 2^31 or 1<<31 graph size) and the nonces -/// of the graph solution. While being expressed as u64 for simplicity, each -/// nonce is strictly less than half the cycle size (i.e. <2^30 for Cuckoo 31). +/// A Cuck(at)oo Cycle proof of work, consisting of the edge_bits to get the graph +/// 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, +/// 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 /// them at their exact bit size. The resulting bit sequence is padded to be @@ -317,14 +321,14 @@ impl ProofOfWork { #[derive(Clone, PartialOrd, PartialEq)] pub struct Proof { /// Power of 2 used for the size of the cuckoo graph - pub cuckoo_sizeshift: u8, + pub edge_bits: u8, /// The nonces pub nonces: Vec, } impl fmt::Debug for Proof { 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() { write!(f, "{:x}", val)?; if i < self.nonces.len() - 1 { @@ -338,11 +342,11 @@ impl fmt::Debug for Proof { impl Eq for 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) -> Proof { in_nonces.sort(); Proof { - cuckoo_sizeshift: global::min_sizeshift(), + edge_bits: global::min_edge_bits(), nonces: in_nonces, } } @@ -350,7 +354,7 @@ impl Proof { /// Builds a proof with all bytes zeroed out pub fn zero(proof_size: usize) -> Proof { Proof { - cuckoo_sizeshift: global::min_sizeshift(), + edge_bits: global::min_edge_bits(), nonces: vec![0; proof_size], } } @@ -359,17 +363,17 @@ impl Proof { /// needed so that tests that ignore POW /// don't fail due to duplicate hashes pub fn random(proof_size: usize) -> Proof { - let sizeshift = global::min_sizeshift(); - let nonce_mask = (1 << (sizeshift - 1)) - 1; + let edge_bits = global::min_edge_bits(); + let nonce_mask = (1 << edge_bits) - 1; 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 = iter::repeat(()) .map(|()| (rng.gen::() & nonce_mask) as u64) .take(proof_size) .collect(); v.sort(); Proof { - cuckoo_sizeshift: global::min_sizeshift(), + edge_bits: global::min_edge_bits(), nonces: v, } } @@ -387,16 +391,13 @@ impl Proof { impl Readable for Proof { fn read(reader: &mut Reader) -> Result { - let cuckoo_sizeshift = reader.read_u8()?; - if cuckoo_sizeshift == 0 || cuckoo_sizeshift > 64 { + let edge_bits = reader.read_u8()?; + if edge_bits == 0 || edge_bits > 64 { return Err(ser::Error::CorruptedData); } let mut nonces = Vec::with_capacity(global::proofsize()); - let mut nonce_bits = cuckoo_sizeshift as usize; - if global::pow_type() == global::PoWContextTypes::Cuckoo { - nonce_bits -= 1; - } + let nonce_bits = edge_bits as usize; let bytes_len = BitVec::bytes_len(nonce_bits * global::proofsize()); let bits = reader.read_fixed_bytes(bytes_len)?; let bitvec = BitVec { bits }; @@ -410,7 +411,7 @@ impl Readable for Proof { nonces.push(nonce); } Ok(Proof { - cuckoo_sizeshift, + edge_bits, nonces, }) } @@ -419,13 +420,9 @@ impl Readable for Proof { impl Writeable for Proof { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { if writer.serialization_mode() != ser::SerializationMode::Hash { - writer.write_u8(self.cuckoo_sizeshift)?; - } - - let mut nonce_bits = self.cuckoo_sizeshift as usize; - if global::pow_type() == global::PoWContextTypes::Cuckoo { - nonce_bits -= 1; + writer.write_u8(self.edge_bits)?; } + let nonce_bits = self.edge_bits as usize; let mut bitvec = BitVec::new(nonce_bits * global::proofsize()); for (n, nonce) in self.nonces.iter().enumerate() { for bit in 0..nonce_bits { diff --git a/doc/api/node_api.md b/doc/api/node_api.md index 09e44f4db..c72c4005c 100644 --- a/doc/api/node_api.md +++ b/doc/api/node_api.md @@ -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 | | - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet | | - 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 | | - total_difficulty | number | Total accumulated difficulty 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 | | - kernel_root | string | Merklish root of all transaction kernels in the TxHashSet | | - 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 | | - total_difficulty | number | Total accumulated difficulty since genesis block | | - total_kernel_offset | string | Total kernel offset since genesis block | @@ -1146,4 +1146,4 @@ Retrieves information about a specific peer. console.log(r); } }); - ``` \ No newline at end of file + ``` diff --git a/p2p/src/protocol.rs b/p2p/src/protocol.rs index 9a1d3da05..7d9c1038b 100644 --- a/p2p/src/protocol.rs +++ b/p2p/src/protocol.rs @@ -335,9 +335,9 @@ fn headers_header_size(conn: &mut TcpStream, msg_len: u64) -> Result } 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 - 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; if average_header_size < min_size as u64 || average_header_size > max_size as u64 { debug!( diff --git a/servers/src/common/stats.rs b/servers/src/common/stats.rs index c1d75b4e0..cfee09aef 100644 --- a/servers/src/common/stats.rs +++ b/servers/src/common/stats.rs @@ -19,6 +19,8 @@ use std::sync::atomic::AtomicBool; use std::sync::{Arc, RwLock}; use std::time::SystemTime; +use core::pow::Difficulty; + use chrono::prelude::*; use chain; @@ -98,7 +100,7 @@ pub struct StratumStats { /// current network difficulty we're working on pub network_difficulty: u64, /// cuckoo size used for mining - pub cuckoo_size: u16, + pub edge_bits: u16, /// Individual worker status pub worker_stats: Vec, } @@ -153,7 +155,7 @@ pub struct PeerStats { impl StratumStats { /// Calculate network hashrate 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, block_height: 0, network_difficulty: 1000, - cuckoo_size: 30, + edge_bits: 29, worker_stats: Vec::new(), } } diff --git a/servers/src/grin/server.rs b/servers/src/grin/server.rs index ee595288c..685106ee6 100644 --- a/servers/src/grin/server.rs +++ b/servers/src/grin/server.rs @@ -313,7 +313,7 @@ impl Server { /// Start a minimal "stratum" mining service on a separate thread 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 sync_state = self.sync_state.clone(); @@ -327,7 +327,7 @@ impl Server { let _ = thread::Builder::new() .name("stratum_server".to_string()) .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); }); } diff --git a/servers/src/mining/stratumserver.rs b/servers/src/mining/stratumserver.rs index 6f12a487c..2979765bc 100644 --- a/servers/src/mining/stratumserver.rs +++ b/servers/src/mining/stratumserver.rs @@ -75,7 +75,7 @@ struct SubmitParams { height: u64, job_id: u64, nonce: u64, - cuckoo_size: u32, + edge_bits: u32, pow: Vec, } @@ -481,7 +481,7 @@ impl StratumServer { } let mut b: Block = b.unwrap().clone(); // 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.proof.nonces = params.pow; // Get share difficulty @@ -532,7 +532,7 @@ impl StratumServer { ); } else { // 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 error!( LOGGER, @@ -653,15 +653,15 @@ impl StratumServer { pub fn run_loop( &mut self, stratum_stats: Arc>, - cuckoo_size: u32, + edge_bits: u32, proof_size: usize, sync_state: Arc, ) { info!( LOGGER, - "(Server ID: {}) Starting stratum server with cuckoo_size = {}, proof_size = {}", + "(Server ID: {}) Starting stratum server with edge_bits = {}, proof_size = {}", self.id, - cuckoo_size, + edge_bits, proof_size ); @@ -693,7 +693,7 @@ impl StratumServer { { let mut stratum_stats = stratum_stats.write().unwrap(); stratum_stats.is_running = true; - stratum_stats.cuckoo_size = cuckoo_size as u16; + stratum_stats.edge_bits = edge_bits as u16; } warn!( diff --git a/servers/src/mining/test_miner.rs b/servers/src/mining/test_miner.rs index 125d821a3..f328dc48e 100644 --- a/servers/src/mining/test_miner.rs +++ b/servers/src/mining/test_miner.rs @@ -87,7 +87,7 @@ impl Miner { LOGGER, "(Server ID: {}) Mining Cuckoo{} for max {}s on {} @ {} [{}].", self.debug_output_id, - global::min_sizeshift(), + global::min_edge_bits(), attempt_time_per_block, b.header.total_difficulty(), b.header.height, @@ -97,7 +97,7 @@ impl Miner { while head.hash() == *latest_hash && Utc::now().timestamp() < deadline { let mut ctx = - global::create_pow_context::(global::min_sizeshift(), global::proofsize(), 10) + global::create_pow_context::(global::min_edge_bits(), global::proofsize(), 10) .unwrap(); ctx.set_header_nonce(b.header.pre_pow(), None, true) .unwrap(); diff --git a/src/bin/tui/mining.rs b/src/bin/tui/mining.rs index 32729864e..d06d970a0 100644 --- a/src/bin/tui/mining.rs +++ b/src/bin/tui/mining.rs @@ -217,7 +217,7 @@ impl TUIStatusListener for TUIMiningView { ) .child( 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) @@ -320,7 +320,7 @@ impl TUIStatusListener for TUIMiningView { let stratum_block_height = format!("Solving Block Height: {}", stratum_stats.block_height); let stratum_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| { t.set_content(stratum_enabled); @@ -340,8 +340,8 @@ impl TUIStatusListener for TUIMiningView { c.call_on_id("stratum_network_hashrate", |t: &mut TextView| { t.set_content(stratum_network_hashrate); }); - c.call_on_id("stratum_cuckoo_size_status", |t: &mut TextView| { - t.set_content(stratum_cuckoo_size); + c.call_on_id("stratum_edge_bits_status", |t: &mut TextView| { + t.set_content(stratum_edge_bits); }); let _ = c.call_on_id( TABLE_MINING_STATUS, diff --git a/src/bin/tui/status.rs b/src/bin/tui/status.rs index 6f078efb7..0b0db2420 100644 --- a/src/bin/tui/status.rs +++ b/src/bin/tui/status.rs @@ -201,7 +201,7 @@ impl TUIStatusListener for TUIStatusView { ), format!( "Cuckoo {} - Network Difficulty {}", - stats.mining_stats.cuckoo_size, + stats.mining_stats.edge_bits, stats.mining_stats.network_difficulty.to_string() ), ) diff --git a/wallet/tests/common/mod.rs b/wallet/tests/common/mod.rs index ef2f029ae..07cf75ff8 100644 --- a/wallet/tests/common/mod.rs +++ b/wallet/tests/common/mod.rs @@ -103,7 +103,7 @@ pub fn add_block_with_reward(chain: &Chain, txs: Vec<&Transaction>, reward: CbDa &mut b.header, next_header_info.difficulty, global::proofsize(), - global::min_sizeshift(), + global::min_edge_bits(), ).unwrap(); chain.process_block(b, chain::Options::MINE).unwrap(); chain.validate(false).unwrap();