From 91b5ad6ebd1c1758a347db0b5323927ceb0a3745 Mon Sep 17 00:00:00 2001 From: parazyd Date: Wed, 8 Nov 2023 12:26:25 +0100 Subject: [PATCH] mmproxy: Send mining job upon worker stratum login --- Cargo.lock | 1 + bin/darkfi-mmproxy/Cargo.toml | 1 + bin/darkfi-mmproxy/src/main.rs | 22 ++++++++++++++++- bin/darkfi-mmproxy/src/stratum.rs | 40 +++++++++++++++++++++++-------- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff1bc5dec2e6..c2bedbeb4a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1764,6 +1764,7 @@ dependencies = [ "hex", "log", "monero", + "rand 0.8.5", "serde", "signal-hook", "signal-hook-async-std", diff --git a/bin/darkfi-mmproxy/Cargo.toml b/bin/darkfi-mmproxy/Cargo.toml index 95e69b3d452a..e00740f297b7 100644 --- a/bin/darkfi-mmproxy/Cargo.toml +++ b/bin/darkfi-mmproxy/Cargo.toml @@ -14,6 +14,7 @@ darkfi-serial = {path = "../../src/serial", features = ["async"]} # Misc log = "0.4.20" +rand = "0.8.5" # Monero epee-encoding = {version = "0.5.0", features = ["derive"]} diff --git a/bin/darkfi-mmproxy/src/main.rs b/bin/darkfi-mmproxy/src/main.rs index 6a7f818542aa..7337ff474e97 100644 --- a/bin/darkfi-mmproxy/src/main.rs +++ b/bin/darkfi-mmproxy/src/main.rs @@ -26,6 +26,7 @@ use darkfi::{ rpc::{ jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResult, JsonSubscriber}, server::{listen_and_serve, RequestHandler}, + util::JsonValue, }, system::{StoppableTask, StoppableTaskPtr}, Error, Result, @@ -94,6 +95,8 @@ struct Monerod { struct Worker { /// JSON-RPC notification subscriber, used to send job notifications job_sub: JsonSubscriber, + /// Current job ID for the worker + job_id: Uuid, /// Keepalive sender channel, pinged from stratum keepalived ka_send: channel::Sender<()>, /// Background keepalive task reference @@ -106,7 +109,24 @@ impl Worker { ka_send: channel::Sender<()>, ka_task: StoppableTaskPtr, ) -> Self { - Self { job_sub, ka_send, ka_task } + Self { job_sub, job_id: Uuid::new_v4(), ka_send, ka_task } + } + + async fn send_job(&mut self, blob: String, target: String) -> Result<()> { + // Update job id + self.job_id = Uuid::new_v4(); + + let params: JsonValue = HashMap::from([ + ("blob".to_string(), blob.into()), + ("job_id".to_string(), self.job_id.to_string().into()), + ("target".to_string(), target.into()), + ]) + .into(); + + info!("Sending mining job notification to worker"); + self.job_sub.notify(params).await; + + Ok(()) } } diff --git a/bin/darkfi-mmproxy/src/stratum.rs b/bin/darkfi-mmproxy/src/stratum.rs index 5a7f4d967f3f..f78029e59504 100644 --- a/bin/darkfi-mmproxy/src/stratum.rs +++ b/bin/darkfi-mmproxy/src/stratum.rs @@ -27,6 +27,7 @@ use darkfi::{ Error, Result, }; use log::{debug, error, info, warn}; +use rand::{rngs::OsRng, Rng}; use smol::{channel, lock::RwLock}; use uuid::Uuid; @@ -159,7 +160,7 @@ impl MiningProxy { let ka_task = StoppableTask::new(); // Create worker - let worker = Worker::new(job_sub, ka_send, ka_task.clone()); + let worker = Worker::new(job_sub.clone(), ka_send, ka_task.clone()); // Insert into connections map self.workers.write().await.insert(uuid, worker); @@ -174,15 +175,34 @@ impl MiningProxy { info!("Added worker {} ({})", login, uuid); - // TODO: Send current job - JsonResponse::new( - JsonValue::Object(HashMap::from([( - "status".to_string(), - JsonValue::String("KEEPALIVED".to_string()), - )])), - id, - ) - .into() + // Get block template for mining + let gbt_params: JsonValue = HashMap::from([ + ("wallet_address".to_string(), self.monerod.wallet_address.clone().into()), + ("reserve_size".to_string(), (0_f64).into()), + ]) + .into(); + + let block_template = match self.monero_get_block_template(OsRng.gen(), gbt_params).await { + JsonResult::Response(resp) => { + resp.result.get::>().unwrap().clone() + } + _ => { + error!("[STRATUM] Failed getting block template from monerod"); + return JsonError::new(ErrorCode::InternalError, None, id).into() + } + }; + + // Send the job to the worker + let mut workers = self.workers.write().await; + let worker = workers.get_mut(&uuid).unwrap(); + let blob = block_template["blockhashing_blob"].get::().unwrap(); + let target = block_template["wide_difficulty"].get::().unwrap(); + if let Err(e) = worker.send_job(blob.clone(), target.clone()).await { + error!("[STRATUM] Failed sending job to {}: {}", uuid, e); + return JsonError::new(ErrorCode::InternalError, None, id).into() + } + + job_sub.into() } pub async fn stratum_submit(&self, id: u16, params: JsonValue) -> JsonResult {