Support shares (#1132)

* Support logging miner shares and minimum mining difficulty configuration

* rust formatting

* fix test
This commit is contained in:
Blade Doyle 2018-06-04 03:22:42 -07:00 committed by Yeastplume
parent 0ecadd3486
commit c34da9598d
5 changed files with 81 additions and 16 deletions

View file

@ -124,6 +124,9 @@ stratum_server_addr = "127.0.0.1:13416"
#header before stopping and re-collecting transactions from the pool
attempt_time_per_block = 90
#The minimum acceptable share difficulty to request from miners
minimum_share_difficulty = 1
#the wallet reciever to which coinbase rewards will be sent
wallet_listener_url = "http://127.0.0.1:13415"

View file

@ -227,6 +227,9 @@ pub struct StratumServerConfig {
/// and starting again
pub attempt_time_per_block: u32,
/// Minimum difficulty for worker shares
pub minimum_share_difficulty: u64,
/// Base address to the HTTP wallet receiver
pub wallet_listener_url: String,
@ -240,7 +243,8 @@ impl Default for StratumServerConfig {
StratumServerConfig {
wallet_listener_url: "http://localhost:13415".to_string(),
burn_reward: false,
attempt_time_per_block: 2,
attempt_time_per_block: <u32>::max_value(),
minimum_share_difficulty: 1,
enable_stratum_server: None,
stratum_server_addr: None,
}

View file

@ -279,7 +279,6 @@ impl Server {
.name("stratum_server".to_string())
.spawn(move || {
stratum_server.run_loop(
config.clone(),
stratum_stats,
cuckoo_size as u32,
proof_size,
@ -304,6 +303,7 @@ impl Server {
enable_stratum_server: None,
stratum_server_addr: None,
wallet_listener_url: config_wallet_url,
minimum_share_difficulty: 1,
};
let mut miner = Miner::new(

View file

@ -15,6 +15,7 @@
//! Mining Stratum Server
use bufstream::BufStream;
use serde_json;
use std::cmp;
use std::error::Error;
use std::io::BufRead;
use std::io::{ErrorKind, Write};
@ -25,7 +26,6 @@ use std::thread;
use std::time::Duration;
use std::time::SystemTime;
use time;
use util::LOGGER;
use chain;
use common::adapters::PoolToChainAdapter;
@ -35,6 +35,7 @@ use core::core::{Block, BlockHeader};
use keychain;
use mining::mine_block;
use pool;
use util::LOGGER;
// Max number of transactions this miner will assemble in a block
const MAX_TX: u32 = 5000;
@ -231,6 +232,7 @@ pub struct StratumServer {
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
current_block: Block,
current_difficulty: u64,
minimum_share_difficulty: u64,
current_key_id: Option<keychain::Identifier>,
workers: Arc<Mutex<Vec<Worker>>>,
currently_syncing: Arc<AtomicBool>,
@ -245,6 +247,7 @@ impl StratumServer {
) -> StratumServer {
StratumServer {
id: String::from("StratumServer"),
minimum_share_difficulty: config.minimum_share_difficulty,
config: config,
chain: chain_ref,
tx_pool: tx_pool,
@ -264,7 +267,7 @@ impl StratumServer {
let pre = pre_pow_writer.as_hex_string(false);
let job_template = JobTemplate {
height: bh.height,
difficulty: self.current_difficulty,
difficulty: self.minimum_share_difficulty,
pre_pow: pre,
};
return job_template;
@ -421,7 +424,9 @@ impl StratumServer {
// Handle SUBMIT message
// params contains a solved block header
// we are expecting real solutions at the full difficulty.
// We accept and log valid shares of all difficulty above configured minimum
// Accepted shares that are full solutions will also be submitted to the
// network
fn handle_submit(
&self,
params: Option<String>,
@ -442,26 +447,69 @@ impl StratumServer {
};
let mut b: Block;
let share_difficulty: u64;
if submit_params.height == self.current_block.header.height {
// Reconstruct the block header with this nonce and pow added
b = self.current_block.clone();
b.header.nonce = submit_params.nonce;
b.header.pow.nonces = submit_params.pow;
let res = self.chain.process_block(b.clone(), chain::Options::MINE);
if let Err(e) = res {
// Get share difficulty
share_difficulty = b.header.pow.to_difficulty().to_num();
// If the difficulty is too low its an error
if share_difficulty < self.minimum_share_difficulty {
// Return error status
error!(
LOGGER,
"(Server ID: {}) Error validating mined block: {:?}", self.id, e
"(Server ID: {}) Share rejected due to low difficulty: {}/{}",
self.id,
share_difficulty,
self.minimum_share_difficulty,
);
worker_stats.num_rejected += 1;
let e = r#"{"code": -1, "message": "Solution validation failed"}"#;
let e = r#"{"code": -1, "message": "Share rejected due to low difficulty"}"#;
let err = e.to_string();
return (err, true);
}
// If the difficulty is high enough, submit it (which also validates it)
if share_difficulty >= self.current_difficulty {
let res = self.chain.process_block(b.clone(), chain::Options::MINE);
if let Err(e) = res {
// Return error status
error!(
LOGGER,
"(Server ID: {}) Failed to validate solution at height {}: {:?}",
self.id,
submit_params.height,
e
);
worker_stats.num_rejected += 1;
let e = r#"{"code": -1, "message": "Failed to validate solution"}"#;
let err = e.to_string();
return (err, true);
}
// Success case falls through to be logged
} else {
// Do some validation but dont submit
if self.current_block.header.pre_pow_hash() != b.header.pre_pow_hash() {
// Return error status
error!(
LOGGER,
"(Server ID: {}) Failed to validate share at height {} with nonce {}",
self.id,
submit_params.height,
b.header.nonce
);
worker_stats.num_rejected += 1;
let e = r#"{"code": -1, "message": "Failed to validate share"}"#;
let err = e.to_string();
return (err, true);
}
}
} else {
warn!(
// Return error status
error!(
LOGGER,
"(Server ID: {}) Found POW for block at height: {} - but too late",
"(Server ID: {}) Share at height {} submitted too late",
self.id,
submit_params.height
);
@ -470,17 +518,20 @@ impl StratumServer {
let err = e.to_string();
return (err, true);
}
// Log this as a valid share
let submitted_by = match worker.login.clone() {
None => worker.id.to_string(),
Some(login) => login.clone(),
};
info!(
LOGGER,
"(Server ID: {}) Found POW for block with hash {} at height {} using nonce {} submitted by worker {}",
"(Server ID: {}) Got share for block: hash {}, height {}, nonce {}, difficulty {}/{}, submitted by {}",
self.id,
b.hash(),
b.header.height,
b.header.nonce,
share_difficulty,
self.current_difficulty,
submitted_by,
);
worker_stats.num_accepted += 1;
@ -544,6 +595,8 @@ impl StratumServer {
let job_request_json = serde_json::to_string(&job_request).unwrap();
// Push the new block to all connected clients
// NOTE: We do not give a uniqe nonce (should we?) so miners need
// to choose one for themselves
let mut workers_l = self.workers.lock().unwrap();
for num in 0..workers_l.len() {
workers_l[num].write_message(job_request_json.clone());
@ -557,7 +610,6 @@ impl StratumServer {
/// be submitted.
pub fn run_loop(
&mut self,
miner_config: StratumServerConfig,
stratum_stats: Arc<RwLock<StratumStats>>,
cuckoo_size: u32,
proof_size: usize,
@ -574,7 +626,7 @@ impl StratumServer {
self.currently_syncing = currently_syncing;
// "globals" for this function
let attempt_time_per_block = miner_config.attempt_time_per_block;
let attempt_time_per_block = self.config.attempt_time_per_block;
let mut deadline: i64 = 0;
// to prevent the wallet from generating a new HD key derivation for each
// iteration, we keep the returned derivation to provide it back when
@ -584,7 +636,7 @@ impl StratumServer {
let mut head = self.chain.head().unwrap();
let mut current_hash = head.prev_block_h;
let mut latest_hash;
let listen_addr = miner_config.stratum_server_addr.clone().unwrap();
let listen_addr = self.config.stratum_server_addr.clone().unwrap();
// Start a thread to accept new worker connections
let mut workers_th = self.workers.clone();
@ -604,7 +656,7 @@ impl StratumServer {
warn!(
LOGGER,
"Stratum server started on {}",
miner_config.stratum_server_addr.unwrap()
self.config.stratum_server_addr.clone().unwrap()
);
// Main Loop
@ -646,6 +698,11 @@ impl StratumServer {
.to_num();
self.current_key_id = block_fees.key_id();
current_hash = latest_hash;
// set the minimum acceptable share difficulty for this block
self.minimum_share_difficulty = cmp::min(
self.config.minimum_share_difficulty,
self.current_difficulty,
);
// set a new deadline for rebuilding with fresh transactions
deadline = time::get_time().sec + attempt_time_per_block as i64;

View file

@ -579,6 +579,7 @@ pub fn stratum_config() -> servers::common::types::StratumServerConfig {
enable_stratum_server: Some(true),
stratum_server_addr: Some(String::from("127.0.0.1:13416")),
attempt_time_per_block: 60,
minimum_share_difficulty: 1,
wallet_listener_url: String::from("http://127.0.0.1:13415"),
burn_reward: false,
}