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
|
#header before stopping and re-collecting transactions from the pool
|
||||||
attempt_time_per_block = 90
|
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
|
#the wallet reciever to which coinbase rewards will be sent
|
||||||
wallet_listener_url = "http://127.0.0.1:13415"
|
wallet_listener_url = "http://127.0.0.1:13415"
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,9 @@ pub struct StratumServerConfig {
|
||||||
/// and starting again
|
/// and starting again
|
||||||
pub attempt_time_per_block: u32,
|
pub attempt_time_per_block: u32,
|
||||||
|
|
||||||
|
/// Minimum difficulty for worker shares
|
||||||
|
pub minimum_share_difficulty: u64,
|
||||||
|
|
||||||
/// Base address to the HTTP wallet receiver
|
/// Base address to the HTTP wallet receiver
|
||||||
pub wallet_listener_url: String,
|
pub wallet_listener_url: String,
|
||||||
|
|
||||||
|
@ -240,7 +243,8 @@ impl Default for StratumServerConfig {
|
||||||
StratumServerConfig {
|
StratumServerConfig {
|
||||||
wallet_listener_url: "http://localhost:13415".to_string(),
|
wallet_listener_url: "http://localhost:13415".to_string(),
|
||||||
burn_reward: false,
|
burn_reward: false,
|
||||||
attempt_time_per_block: 2,
|
attempt_time_per_block: <u32>::max_value(),
|
||||||
|
minimum_share_difficulty: 1,
|
||||||
enable_stratum_server: None,
|
enable_stratum_server: None,
|
||||||
stratum_server_addr: None,
|
stratum_server_addr: None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,6 @@ impl Server {
|
||||||
.name("stratum_server".to_string())
|
.name("stratum_server".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
stratum_server.run_loop(
|
stratum_server.run_loop(
|
||||||
config.clone(),
|
|
||||||
stratum_stats,
|
stratum_stats,
|
||||||
cuckoo_size as u32,
|
cuckoo_size as u32,
|
||||||
proof_size,
|
proof_size,
|
||||||
|
@ -304,6 +303,7 @@ impl Server {
|
||||||
enable_stratum_server: None,
|
enable_stratum_server: None,
|
||||||
stratum_server_addr: None,
|
stratum_server_addr: None,
|
||||||
wallet_listener_url: config_wallet_url,
|
wallet_listener_url: config_wallet_url,
|
||||||
|
minimum_share_difficulty: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut miner = Miner::new(
|
let mut miner = Miner::new(
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
//! Mining Stratum Server
|
//! Mining Stratum Server
|
||||||
use bufstream::BufStream;
|
use bufstream::BufStream;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use std::cmp;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::io::{ErrorKind, Write};
|
use std::io::{ErrorKind, Write};
|
||||||
|
@ -25,7 +26,6 @@ use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use time;
|
use time;
|
||||||
use util::LOGGER;
|
|
||||||
|
|
||||||
use chain;
|
use chain;
|
||||||
use common::adapters::PoolToChainAdapter;
|
use common::adapters::PoolToChainAdapter;
|
||||||
|
@ -35,6 +35,7 @@ use core::core::{Block, BlockHeader};
|
||||||
use keychain;
|
use keychain;
|
||||||
use mining::mine_block;
|
use mining::mine_block;
|
||||||
use pool;
|
use pool;
|
||||||
|
use util::LOGGER;
|
||||||
|
|
||||||
// Max number of transactions this miner will assemble in a block
|
// Max number of transactions this miner will assemble in a block
|
||||||
const MAX_TX: u32 = 5000;
|
const MAX_TX: u32 = 5000;
|
||||||
|
@ -231,6 +232,7 @@ pub struct StratumServer {
|
||||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||||
current_block: Block,
|
current_block: Block,
|
||||||
current_difficulty: u64,
|
current_difficulty: u64,
|
||||||
|
minimum_share_difficulty: u64,
|
||||||
current_key_id: Option<keychain::Identifier>,
|
current_key_id: Option<keychain::Identifier>,
|
||||||
workers: Arc<Mutex<Vec<Worker>>>,
|
workers: Arc<Mutex<Vec<Worker>>>,
|
||||||
currently_syncing: Arc<AtomicBool>,
|
currently_syncing: Arc<AtomicBool>,
|
||||||
|
@ -245,6 +247,7 @@ impl StratumServer {
|
||||||
) -> StratumServer {
|
) -> StratumServer {
|
||||||
StratumServer {
|
StratumServer {
|
||||||
id: String::from("StratumServer"),
|
id: String::from("StratumServer"),
|
||||||
|
minimum_share_difficulty: config.minimum_share_difficulty,
|
||||||
config: config,
|
config: config,
|
||||||
chain: chain_ref,
|
chain: chain_ref,
|
||||||
tx_pool: tx_pool,
|
tx_pool: tx_pool,
|
||||||
|
@ -264,7 +267,7 @@ impl StratumServer {
|
||||||
let pre = pre_pow_writer.as_hex_string(false);
|
let pre = pre_pow_writer.as_hex_string(false);
|
||||||
let job_template = JobTemplate {
|
let job_template = JobTemplate {
|
||||||
height: bh.height,
|
height: bh.height,
|
||||||
difficulty: self.current_difficulty,
|
difficulty: self.minimum_share_difficulty,
|
||||||
pre_pow: pre,
|
pre_pow: pre,
|
||||||
};
|
};
|
||||||
return job_template;
|
return job_template;
|
||||||
|
@ -421,7 +424,9 @@ impl StratumServer {
|
||||||
|
|
||||||
// Handle SUBMIT message
|
// Handle SUBMIT message
|
||||||
// params contains a solved block header
|
// 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(
|
fn handle_submit(
|
||||||
&self,
|
&self,
|
||||||
params: Option<String>,
|
params: Option<String>,
|
||||||
|
@ -442,26 +447,69 @@ impl StratumServer {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut b: Block;
|
let mut b: Block;
|
||||||
|
let share_difficulty: u64;
|
||||||
if submit_params.height == self.current_block.header.height {
|
if submit_params.height == self.current_block.header.height {
|
||||||
// Reconstruct the block header with this nonce and pow added
|
// Reconstruct the block header with this nonce and pow added
|
||||||
b = self.current_block.clone();
|
b = self.current_block.clone();
|
||||||
b.header.nonce = submit_params.nonce;
|
b.header.nonce = submit_params.nonce;
|
||||||
b.header.pow.nonces = submit_params.pow;
|
b.header.pow.nonces = submit_params.pow;
|
||||||
let res = self.chain.process_block(b.clone(), chain::Options::MINE);
|
// Get share difficulty
|
||||||
if let Err(e) = res {
|
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!(
|
error!(
|
||||||
LOGGER,
|
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;
|
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();
|
let err = e.to_string();
|
||||||
return (err, true);
|
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 {
|
} else {
|
||||||
warn!(
|
// Return error status
|
||||||
|
error!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"(Server ID: {}) Found POW for block at height: {} - but too late",
|
"(Server ID: {}) Share at height {} submitted too late",
|
||||||
self.id,
|
self.id,
|
||||||
submit_params.height
|
submit_params.height
|
||||||
);
|
);
|
||||||
|
@ -470,17 +518,20 @@ impl StratumServer {
|
||||||
let err = e.to_string();
|
let err = e.to_string();
|
||||||
return (err, true);
|
return (err, true);
|
||||||
}
|
}
|
||||||
|
// Log this as a valid share
|
||||||
let submitted_by = match worker.login.clone() {
|
let submitted_by = match worker.login.clone() {
|
||||||
None => worker.id.to_string(),
|
None => worker.id.to_string(),
|
||||||
Some(login) => login.clone(),
|
Some(login) => login.clone(),
|
||||||
};
|
};
|
||||||
info!(
|
info!(
|
||||||
LOGGER,
|
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,
|
self.id,
|
||||||
b.hash(),
|
b.hash(),
|
||||||
b.header.height,
|
b.header.height,
|
||||||
b.header.nonce,
|
b.header.nonce,
|
||||||
|
share_difficulty,
|
||||||
|
self.current_difficulty,
|
||||||
submitted_by,
|
submitted_by,
|
||||||
);
|
);
|
||||||
worker_stats.num_accepted += 1;
|
worker_stats.num_accepted += 1;
|
||||||
|
@ -544,6 +595,8 @@ impl StratumServer {
|
||||||
let job_request_json = serde_json::to_string(&job_request).unwrap();
|
let job_request_json = serde_json::to_string(&job_request).unwrap();
|
||||||
|
|
||||||
// Push the new block to all connected clients
|
// 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();
|
let mut workers_l = self.workers.lock().unwrap();
|
||||||
for num in 0..workers_l.len() {
|
for num in 0..workers_l.len() {
|
||||||
workers_l[num].write_message(job_request_json.clone());
|
workers_l[num].write_message(job_request_json.clone());
|
||||||
|
@ -557,7 +610,6 @@ impl StratumServer {
|
||||||
/// be submitted.
|
/// be submitted.
|
||||||
pub fn run_loop(
|
pub fn run_loop(
|
||||||
&mut self,
|
&mut self,
|
||||||
miner_config: StratumServerConfig,
|
|
||||||
stratum_stats: Arc<RwLock<StratumStats>>,
|
stratum_stats: Arc<RwLock<StratumStats>>,
|
||||||
cuckoo_size: u32,
|
cuckoo_size: u32,
|
||||||
proof_size: usize,
|
proof_size: usize,
|
||||||
|
@ -574,7 +626,7 @@ impl StratumServer {
|
||||||
self.currently_syncing = currently_syncing;
|
self.currently_syncing = currently_syncing;
|
||||||
|
|
||||||
// "globals" for this function
|
// "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;
|
let mut deadline: i64 = 0;
|
||||||
// to prevent the wallet from generating a new HD key derivation for each
|
// to prevent the wallet from generating a new HD key derivation for each
|
||||||
// iteration, we keep the returned derivation to provide it back when
|
// 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 head = self.chain.head().unwrap();
|
||||||
let mut current_hash = head.prev_block_h;
|
let mut current_hash = head.prev_block_h;
|
||||||
let mut latest_hash;
|
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
|
// Start a thread to accept new worker connections
|
||||||
let mut workers_th = self.workers.clone();
|
let mut workers_th = self.workers.clone();
|
||||||
|
@ -604,7 +656,7 @@ impl StratumServer {
|
||||||
warn!(
|
warn!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"Stratum server started on {}",
|
"Stratum server started on {}",
|
||||||
miner_config.stratum_server_addr.unwrap()
|
self.config.stratum_server_addr.clone().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Main Loop
|
// Main Loop
|
||||||
|
@ -646,6 +698,11 @@ impl StratumServer {
|
||||||
.to_num();
|
.to_num();
|
||||||
self.current_key_id = block_fees.key_id();
|
self.current_key_id = block_fees.key_id();
|
||||||
current_hash = latest_hash;
|
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
|
// set a new deadline for rebuilding with fresh transactions
|
||||||
deadline = time::get_time().sec + attempt_time_per_block as i64;
|
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),
|
enable_stratum_server: Some(true),
|
||||||
stratum_server_addr: Some(String::from("127.0.0.1:13416")),
|
stratum_server_addr: Some(String::from("127.0.0.1:13416")),
|
||||||
attempt_time_per_block: 60,
|
attempt_time_per_block: 60,
|
||||||
|
minimum_share_difficulty: 1,
|
||||||
wallet_listener_url: String::from("http://127.0.0.1:13415"),
|
wallet_listener_url: String::from("http://127.0.0.1:13415"),
|
||||||
burn_reward: false,
|
burn_reward: false,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue