Explorar el Código

mmproxy: Send mining job upon worker stratum login

parazyd hace 2 años
padre
commit
91b5ad6ebd
Se han modificado 4 ficheros con 53 adiciones y 11 borrados
  1. 1 0
      Cargo.lock
  2. 1 0
      bin/darkfi-mmproxy/Cargo.toml
  3. 21 1
      bin/darkfi-mmproxy/src/main.rs
  4. 30 10
      bin/darkfi-mmproxy/src/stratum.rs

+ 1 - 0
Cargo.lock

@@ -1764,6 +1764,7 @@ dependencies = [
  "hex",
  "log",
  "monero",
+ "rand 0.8.5",
  "serde",
  "signal-hook",
  "signal-hook-async-std",

+ 1 - 0
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"]}

+ 21 - 1
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(())
     }
 }
 

+ 30 - 10
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::<HashMap<String, JsonValue>>().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::<String>().unwrap();
+        let target = block_template["wide_difficulty"].get::<String>().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 {