From 92f826a917ce540d608ce74bc2dc56ab7ed0989e Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 10 Oct 2018 10:09:44 +0100 Subject: [PATCH] [T4 ONLY] T4 PoW changes (#1663) * T4 PoW changes * rustfmt * adjust sizeshift depending on pow type during ser/deser * update block size tests for cuckatoo sizeshift --- chain/src/pipe.rs | 2 +- config/src/comments.rs | 2 ++ core/src/genesis.rs | 22 ++++++++++++++++++++++ core/src/global.rs | 25 ++++++++++++++++--------- core/src/pow/types.rs | 10 ++++++++-- core/tests/block.rs | 16 ++++++++-------- servers/src/grin/server.rs | 1 + servers/src/mining/stratumserver.rs | 9 ++++++--- 8 files changed, 64 insertions(+), 23 deletions(-) diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 92839e894..cd3589c42 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -377,7 +377,7 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E if !(ctx.pow_verifier)(header, shift).is_ok() { error!( LOGGER, - "pipe: validate_header bad cuckoo shift size {}", shift + "pipe: error validating header with cuckoo shift size {}", shift ); return Err(ErrorKind::InvalidPow.into()); } diff --git a/config/src/comments.rs b/config/src/comments.rs index dc984dbdd..7af80c278 100644 --- a/config/src/comments.rs +++ b/config/src/comments.rs @@ -71,6 +71,8 @@ fn comments() -> HashMap { #UserTesting - For regular user testing (cuckoo 16) #Testnet1 - Testnet1 genesis block (cuckoo 16) #Testnet2 - Testnet2 genesis block (cuckoo 30) +#Testnet3 - Testnet3 genesis block (cuckoo 30) +#Testnet4 - Testnet4 genesis block (cuckatoo 29+) ".to_string(), ); diff --git a/core/src/genesis.rs b/core/src/genesis.rs index b50e1c50c..b0f72b79e 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -105,6 +105,28 @@ pub fn genesis_testnet3() -> core::Block { }) } +/// 4th testnet genesis block (cuckatoo29 AR, 30+ AF). Temporary values for now (Pow won't verify) +pub fn genesis_testnet4() -> core::Block { + core::Block::with_header(core::BlockHeader { + height: 0, + previous: core::hash::Hash([0xff; 32]), + timestamp: Utc.ymd(2018, 8, 30).and_hms(18, 0, 0), + pow: ProofOfWork { + total_difficulty: Difficulty::from_num(global::initial_block_difficulty()), + scaling_difficulty: 1, + nonce: 4956988373127691, + proof: Proof::new(vec![ + 0xa420dc, 0xc8ffee, 0x10e433e, 0x1de9428, 0x2ed4cea, 0x52d907b, 0x5af0e3f, + 0x6b8fcae, 0x8319b53, 0x845ca8c, 0x8d2a13e, 0x8d6e4cc, 0x9349e8d, 0xa7a33c5, + 0xaeac3cb, 0xb193e23, 0xb502e19, 0xb5d9804, 0xc9ac184, 0xd4f4de3, 0xd7a23b8, + 0xf1d8660, 0xf443756, 0x10b833d2, 0x11418fc5, 0x11b8aeaf, 0x131836ec, 0x132ab818, + 0x13a46a55, 0x13df89fe, 0x145d65b5, 0x166f9c3a, 0x166fe0ef, 0x178cb36f, 0x185baf68, + 0x1bbfe563, 0x1bd637b4, 0x1cfc8382, 0x1d1ed012, 0x1e391ca5, 0x1e999b4c, 0x1f7c6d21, + ]), + }, + ..Default::default() + }) +} /// Placeholder for mainnet genesis block, will definitely change before /// release so no use trying to pre-mine it. pub fn genesis_main() -> core::Block { diff --git a/core/src/global.rs b/core/src/global.rs index 299476e2f..51c71f866 100644 --- a/core/src/global.rs +++ b/core/src/global.rs @@ -22,7 +22,7 @@ use consensus::{ DIFFICULTY_ADJUST_WINDOW, EASINESS, INITIAL_DIFFICULTY, MEDIAN_TIME_WINDOW, PROOFSIZE, REFERENCE_SIZESHIFT, }; -use pow::{self, CuckooContext, Difficulty, EdgeType, PoWContext}; +use pow::{self, CuckatooContext, Difficulty, 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, @@ -39,7 +39,7 @@ pub const AUTOMATED_TESTING_MIN_SIZESHIFT: u8 = 10; pub const AUTOMATED_TESTING_PROOF_SIZE: usize = 4; /// User testing sizeshift -pub const USER_TESTING_MIN_SIZESHIFT: u8 = 16; +pub const USER_TESTING_MIN_SIZESHIFT: u8 = 19; /// User testing proof size pub const USER_TESTING_PROOF_SIZE: usize = 42; @@ -69,6 +69,9 @@ pub const TESTNET2_INITIAL_DIFFICULTY: u64 = 1000; /// a 30x Cuckoo adjustment factor pub const TESTNET3_INITIAL_DIFFICULTY: u64 = 30000; +/// Testnet 4 initial block difficulty +pub const TESTNET4_INITIAL_DIFFICULTY: u64 = 1; + /// Types of chain a server can run with, dictates the genesis block and /// and mining parameters used. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -83,13 +86,15 @@ pub enum ChainTypes { Testnet2, /// Third test network Testnet3, + /// Fourth test network + Testnet4, /// Main production network Mainnet, } impl Default for ChainTypes { fn default() -> ChainTypes { - ChainTypes::Testnet3 + ChainTypes::Testnet4 } } @@ -128,12 +133,12 @@ pub fn create_pow_context( where T: EdgeType, { - // Perform whatever tests, configuration etc are needed to determine desired context + edge size - // + params - // Hardcode to regular cuckoo for now - CuckooContext::::new(edge_bits, proof_size, EASINESS, max_sols) - // Or switch to cuckatoo as follows: - // CuckatooContext::::new(edge_bits, proof_size, easiness_pct, max_sols) + CuckatooContext::::new(edge_bits, proof_size, EASINESS, max_sols) +} + +/// Return the type of the pos +pub fn pow_type() -> PoWContextTypes { + PoWContextTypes::Cuckatoo } /// The minimum acceptable sizeshift @@ -193,6 +198,7 @@ pub fn initial_block_difficulty() -> u64 { ChainTypes::Testnet1 => TESTING_INITIAL_DIFFICULTY, ChainTypes::Testnet2 => TESTNET2_INITIAL_DIFFICULTY, ChainTypes::Testnet3 => TESTNET3_INITIAL_DIFFICULTY, + ChainTypes::Testnet4 => TESTNET4_INITIAL_DIFFICULTY, ChainTypes::Mainnet => INITIAL_DIFFICULTY, } } @@ -225,6 +231,7 @@ pub fn is_production_mode() -> bool { ChainTypes::Testnet1 == *param_ref || ChainTypes::Testnet2 == *param_ref || ChainTypes::Testnet3 == *param_ref + || ChainTypes::Testnet4 == *param_ref || ChainTypes::Mainnet == *param_ref } diff --git a/core/src/pow/types.rs b/core/src/pow/types.rs index 0669da4ad..8a08536a8 100644 --- a/core/src/pow/types.rs +++ b/core/src/pow/types.rs @@ -385,7 +385,10 @@ impl Readable for Proof { } let mut nonces = Vec::with_capacity(global::proofsize()); - let nonce_bits = cuckoo_sizeshift as usize - 1; + let mut nonce_bits = cuckoo_sizeshift as usize; + if global::pow_type() == global::PoWContextTypes::Cuckoo { + nonce_bits -= 1; + } let bytes_len = BitVec::bytes_len(nonce_bits * global::proofsize()); let bits = reader.read_fixed_bytes(bytes_len)?; let bitvec = BitVec { bits }; @@ -411,7 +414,10 @@ impl Writeable for Proof { writer.write_u8(self.cuckoo_sizeshift)?; } - let nonce_bits = self.cuckoo_sizeshift as usize - 1; + let mut nonce_bits = self.cuckoo_sizeshift as usize; + if global::pow_type() == global::PoWContextTypes::Cuckoo { + nonce_bits -= 1; + } 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/core/tests/block.rs b/core/tests/block.rs index 857faac27..ff3adf05f 100644 --- a/core/tests/block.rs +++ b/core/tests/block.rs @@ -264,7 +264,7 @@ fn empty_block_serialized_size() { let b = new_block(vec![], &keychain, &prev, &key_id); let mut vec = Vec::new(); ser::serialize(&mut vec, &b).expect("serialization failed"); - let target_len = 1_252; + let target_len = 1_257; assert_eq!(vec.len(), target_len); } @@ -277,7 +277,7 @@ fn block_single_tx_serialized_size() { let b = new_block(vec![&tx1], &keychain, &prev, &key_id); let mut vec = Vec::new(); ser::serialize(&mut vec, &b).expect("serialization failed"); - let target_len = 2_834; + let target_len = 2_839; assert_eq!(vec.len(), target_len); } @@ -290,7 +290,7 @@ fn empty_compact_block_serialized_size() { let cb: CompactBlock = b.into(); let mut vec = Vec::new(); ser::serialize(&mut vec, &cb).expect("serialization failed"); - let target_len = 1_260; + let target_len = 1_265; assert_eq!(vec.len(), target_len); } @@ -304,7 +304,7 @@ fn compact_block_single_tx_serialized_size() { let cb: CompactBlock = b.into(); let mut vec = Vec::new(); ser::serialize(&mut vec, &cb).expect("serialization failed"); - let target_len = 1_266; + let target_len = 1_271; assert_eq!(vec.len(), target_len); } @@ -323,7 +323,7 @@ fn block_10_tx_serialized_size() { let b = new_block(txs.iter().collect(), &keychain, &prev, &key_id); let mut vec = Vec::new(); ser::serialize(&mut vec, &b).expect("serialization failed"); - let target_len = 17_072; + let target_len = 17_077; assert_eq!(vec.len(), target_len,); } @@ -342,7 +342,7 @@ fn compact_block_10_tx_serialized_size() { let cb: CompactBlock = b.into(); let mut vec = Vec::new(); ser::serialize(&mut vec, &cb).expect("serialization failed"); - let target_len = 1_320; + let target_len = 1_325; assert_eq!(vec.len(), target_len,); } @@ -446,7 +446,7 @@ fn empty_block_v2_switch() { let b = new_block(vec![], &keychain, &prev, &key_id); let mut vec = Vec::new(); ser::serialize(&mut vec, &b).expect("serialization failed"); - let target_len = 1_260; + let target_len = 1_265; assert_eq!(b.header.version, 2); assert_eq!(vec.len(), target_len); @@ -455,7 +455,7 @@ fn empty_block_v2_switch() { let b = new_block(vec![], &keychain, &prev, &key_id); let mut vec = Vec::new(); ser::serialize(&mut vec, &b).expect("serialization failed"); - let target_len = 1_252; + let target_len = 1_257; assert_eq!(b.header.version, 1); assert_eq!(vec.len(), target_len); } diff --git a/servers/src/grin/server.rs b/servers/src/grin/server.rs index 31fac890b..0d0733d4c 100644 --- a/servers/src/grin/server.rs +++ b/servers/src/grin/server.rs @@ -150,6 +150,7 @@ impl Server { global::ChainTypes::Testnet1 => genesis::genesis_testnet1(), global::ChainTypes::Testnet2 => genesis::genesis_testnet2(), global::ChainTypes::Testnet3 => genesis::genesis_testnet3(), + global::ChainTypes::Testnet4 => genesis::genesis_testnet4(), global::ChainTypes::AutomatedTesting => genesis::genesis_dev(), global::ChainTypes::UserTesting => genesis::genesis_dev(), global::ChainTypes::Mainnet => genesis::genesis_testnet2(), //TODO: Fix, obviously diff --git a/servers/src/mining/stratumserver.rs b/servers/src/mining/stratumserver.rs index 1b8892748..524859d7d 100644 --- a/servers/src/mining/stratumserver.rs +++ b/servers/src/mining/stratumserver.rs @@ -75,6 +75,7 @@ struct SubmitParams { height: u64, job_id: u64, nonce: u64, + cuckoo_size: u32, pow: Vec, } @@ -480,6 +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.nonce = params.nonce; b.header.pow.proof.nonces = params.pow; // Get share difficulty @@ -509,10 +511,11 @@ impl StratumServer { // Return error status error!( LOGGER, - "(Server ID: {}) Failed to validate solution at height {}: {:?}", + "(Server ID: {}) Failed to validate solution at height {}: {}: {}", self.id, params.height, - e + e, + e.backtrace().unwrap(), ); worker_stats.num_rejected += 1; let e = RpcError { @@ -529,7 +532,7 @@ impl StratumServer { ); } else { // Do some validation but dont submit - if !pow::verify_size(&b.header, global::min_sizeshift()).is_ok() { + if !pow::verify_size(&b.header, b.header.pow.proof.cuckoo_sizeshift).is_ok() { // Return error status error!( LOGGER,