mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
script/research/minerd: handle new request trigger using smol channels
This commit is contained in:
@@ -28,6 +28,7 @@ pub enum RpcError {
|
||||
// Miner errors
|
||||
MiningFailed = -32201,
|
||||
HashingFailed = -32202,
|
||||
StopFailed = -32203,
|
||||
}
|
||||
|
||||
fn to_tuple(e: RpcError) -> (i32, String) {
|
||||
@@ -38,6 +39,7 @@ fn to_tuple(e: RpcError) -> (i32, String) {
|
||||
// Miner errors
|
||||
RpcError::MiningFailed => "Mining block failed",
|
||||
RpcError::HashingFailed => "Hashing block failed",
|
||||
RpcError::StopFailed => "Failed to stop previous request",
|
||||
};
|
||||
|
||||
(e as i32, msg.to_string())
|
||||
|
||||
@@ -19,7 +19,12 @@
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
|
||||
use log::{error, info};
|
||||
use smol::{channel::Receiver, lock::Mutex, stream::StreamExt, Executor};
|
||||
use smol::{
|
||||
channel::{Receiver, Sender},
|
||||
lock::Mutex,
|
||||
stream::StreamExt,
|
||||
Executor,
|
||||
};
|
||||
use structopt_toml::{serde::Deserialize, structopt::StructOpt, StructOptToml};
|
||||
use url::Url;
|
||||
|
||||
@@ -68,6 +73,8 @@ struct Args {
|
||||
pub struct Minerd {
|
||||
/// PoW miner number of threads to use
|
||||
threads: usize,
|
||||
// Sender to stop miner threads
|
||||
sender: Sender<()>,
|
||||
// Receiver to stop miner threads
|
||||
stop_signal: Receiver<()>,
|
||||
/// JSON-RPC connection tracker
|
||||
@@ -75,8 +82,8 @@ pub struct Minerd {
|
||||
}
|
||||
|
||||
impl Minerd {
|
||||
pub fn new(threads: usize, stop_signal: Receiver<()>) -> Self {
|
||||
Self { threads, stop_signal, rpc_connections: Mutex::new(HashSet::new()) }
|
||||
pub fn new(threads: usize, sender: Sender<()>, stop_signal: Receiver<()>) -> Self {
|
||||
Self { threads, sender, stop_signal, rpc_connections: Mutex::new(HashSet::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +91,7 @@ async_daemonize!(realmain);
|
||||
async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
|
||||
info!(target: "minerd", "Starting DarkFi Mining Daemon...");
|
||||
let (sender, recvr) = smol::channel::bounded(1);
|
||||
let minerd = Arc::new(Minerd::new(args.threads, recvr));
|
||||
let minerd = Arc::new(Minerd::new(args.threads, sender.clone(), recvr));
|
||||
|
||||
info!(target: "minerd", "Starting JSON-RPC server on {}", args.rpc_listen);
|
||||
let minerd_ = Arc::clone(&minerd);
|
||||
|
||||
@@ -29,7 +29,7 @@ use darkfi::{
|
||||
server::RequestHandler,
|
||||
util::JsonValue,
|
||||
},
|
||||
system::StoppableTaskPtr,
|
||||
system::{sleep, StoppableTaskPtr},
|
||||
util::encoding::base64,
|
||||
validator::pow::mine_block,
|
||||
};
|
||||
@@ -88,13 +88,36 @@ impl Minerd {
|
||||
return server_error(RpcError::BlockParseError, id, None)
|
||||
};
|
||||
|
||||
// Check if another request is being processed
|
||||
if self.stop_signal.receiver_count() > 1 {
|
||||
info!(target: "minerd::rpc", "Another request is in progress, sending stop signal...");
|
||||
// Send stop signal to other worker
|
||||
if self.sender.send(()).await.is_err() {
|
||||
error!(target: "minerd::rpc", "Failed to stop previous request");
|
||||
return server_error(RpcError::StopFailed, id, None)
|
||||
}
|
||||
|
||||
// Wait for other worker to terminate
|
||||
info!(target: "minerd::rpc", "Waiting for request to terminate...");
|
||||
while self.stop_signal.receiver_count() > 1 {
|
||||
sleep(1).await;
|
||||
}
|
||||
info!(target: "minerd::rpc", "Previous request terminated!");
|
||||
|
||||
// Consume channel item so its empty again
|
||||
if self.stop_signal.recv().await.is_err() {
|
||||
error!(target: "minerd::rpc", "Failed to cleanup stop signal channel");
|
||||
return server_error(RpcError::StopFailed, id, None)
|
||||
}
|
||||
}
|
||||
|
||||
// Mine provided block
|
||||
let Ok(block_hash) = block.hash() else {
|
||||
error!(target: "minerd::rpc", "Failed to hash block");
|
||||
return server_error(RpcError::HashingFailed, id, None)
|
||||
};
|
||||
info!(target: "minerd::rpc", "Mining block {} for target: {}", block_hash, target);
|
||||
if let Err(e) = mine_block(&target, &mut block, self.threads, &self.stop_signal) {
|
||||
if let Err(e) = mine_block(&target, &mut block, self.threads, &self.stop_signal.clone()) {
|
||||
error!(target: "minerd::rpc", "Failed mining block {} with error: {}", block_hash, e);
|
||||
return server_error(RpcError::MiningFailed, id, None)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user