mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Support shares (#1132)
* Support logging miner shares and minimum mining difficulty configuration * rust formatting * fix test
This commit is contained in:
parent
0ecadd3486
commit
c34da9598d
5 changed files with 81 additions and 16 deletions
|
@ -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"
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
// 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: {}) Found POW for block at height: {} - but too late",
|
||||
"(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 {
|
||||
// Return error status
|
||||
error!(
|
||||
LOGGER,
|
||||
"(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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue