Просмотр исходного кода

mmproxy: Add more helpful log messages

parazyd 2 лет назад
Родитель
Сommit
579a45cbb5
4 измененных файлов с 58 добавлено и 17 удалено
  1. 8 0
      Makefile
  2. 4 1
      bin/darkfi-mmproxy/Makefile
  3. 3 6
      bin/darkfi-mmproxy/src/main.rs
  4. 43 10
      bin/darkfi-mmproxy/src/stratum.rs

+ 8 - 0
Makefile

@@ -63,6 +63,13 @@ darkirc:
 		RUST_TARGET="$(RUST_TARGET)" \
 		RUSTFLAGS="$(RUSTFLAGS)"
 
+darkfi-mmproxy:
+	$(MAKE) -C bin/darkfi-mmproxy \
+		PREFIX="$(PREFIX)" \
+		CARGO="$(CARGO)" \
+		RUST_TARGET="$(RUST_TARGET)" \
+		RUSTFLAGS="$(RUSTFLAGS)"
+
 genev:
 	$(MAKE) -C bin/genev/genev-cli
 
@@ -110,6 +117,7 @@ clean:
 	$(MAKE) -C bin/zkas clean
 	$(MAKE) -C bin/darkfid clean
 	$(MAKE) -C bin/darkfid2 clean
+	$(MAKE) -C bin/darkfi-mmproxy clean
 	$(MAKE) -C bin/faucetd clean
 	$(MAKE) -C bin/darkirc clean
 	$(MAKE) -C bin/genev/genev-cli clean

+ 4 - 1
bin/darkfi-mmproxy/Makefile

@@ -6,6 +6,9 @@ PREFIX = $(HOME)/.cargo
 # Cargo binary
 CARGO = cargo +nightly
 
+# Compile target
+RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut  -d' ' -f2)
+
 SRC = \
 	Cargo.toml \
 	../../Cargo.toml \
@@ -17,7 +20,7 @@ BIN = ../../darkfi-mmproxy
 all: $(BIN)
 
 $(BIN): $(SRC)
-	$(CARGO) build $(TARGET_PRFX)$(RUST_TARGET) --release --package darkfi-mmproxy
+	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --target=$(RUST_TARGET) --release --package darkfi-mmproxy
 	cp -f ../../target/$(RUST_TARGET)/release/darkfi-mmproxy $@
 
 clean:

+ 3 - 6
bin/darkfi-mmproxy/src/main.rs

@@ -115,12 +115,9 @@ impl MiningProxy {
         };
 
         // Test that monerod RPC is reachable
-        match TcpStream::connect(monerod.rpc.socket_addrs(|| None)?[0]).await {
-            Ok(_) => {}
-            Err(e) => {
-                error!("Failed connecting to monerod RPC: {}", e);
-                return Err(e.into())
-            }
+        if let Err(e) = TcpStream::connect(monerod.rpc.socket_addrs(|| None)?[0]).await {
+            error!("Failed connecting to monerod RPC: {}", e);
+            return Err(e.into())
         }
 
         let workers = Arc::new(RwLock::new(HashMap::new()));

+ 43 - 10
bin/darkfi-mmproxy/src/stratum.rs

@@ -180,6 +180,7 @@ async fn getblocktemplate(endpoint: &Url, wallet_address: &monero::Address) -> R
     );
 
     // Get block template from monerod
+    info!(target: "stratum::getblocktemplate", "[STRATUM] Sending getblocktemplate to monero");
     let rep = match monerod_request(endpoint, req).await {
         Ok(v) => v,
         Err(e) => {
@@ -213,16 +214,19 @@ async fn getblocktemplate(endpoint: &Url, wallet_address: &monero::Address) -> R
         .to_string();
 
     // Needed because hex::decode doesn't accept odd-length
-    if difficulty_hex.len() % 2 == 0 {
+    if difficulty_hex.len() % 2 != 0 {
         difficulty_hex = format!("0{}", difficulty_hex);
     }
 
-    // TODO: Check if this is little or big-endian
     let difficulty_raw = hex::decode(&difficulty_hex).unwrap();
-    let difficulty = BigUint::from_radix_le(&difficulty_raw, 16).unwrap();
+    let difficulty = BigUint::from_radix_be(&difficulty_raw, 16).unwrap();
 
-    // Calculate the target
-    let target = (BigUint::from_bytes_be(&[0xFF; 32]) / &difficulty).to_str_radix(16);
+    // Calculate the target. XMRig expects the 64 least significant bits.
+    let target_raw = BigUint::from_bytes_be(&[0xFF; 32]) / &difficulty;
+    // This iterator is ordered least significant first
+    let target_lsb: u64 = target_raw.iter_u64_digits().take(1).next().unwrap();
+    let target = hex::encode(target_lsb.to_be_bytes());
+    assert!(target.len() == 16);
 
     info!(target: "stratum::getblocktemplate", "[STRATUM] Difficulty: {}", difficulty_hex);
     info!(target: "stratum::getblocktemplate", "[STRATUM] Target: {}", target);
@@ -303,7 +307,7 @@ impl MiningProxy {
         const POLL_INTERVAL: Duration = Duration::from_secs(60);
 
         // Comfy wait for settling the Stratum login RPC call
-        sleep(2).await;
+        sleep(5).await;
 
         // In this loop, we'll be getting the block template for mining.
         // At the beginning of the loop, we'll perform a getblocktemplate,
@@ -313,7 +317,10 @@ impl MiningProxy {
         // order to get the next mining job.
         loop {
             // Get the workers lock and the worker reference
+            debug!(target: "stratum::job_task", "Acquiring workers write lock...");
             let mut workers_ptr = workers.write().await;
+            debug!(target: "stratum::job_task", "Acquired workers write lock");
+
             let Some(worker) = workers_ptr.get_mut(&uuid) else {
                 info!(
                     target: "stratum::job_task",
@@ -359,6 +366,7 @@ impl MiningProxy {
                 break
             }
 
+            debug!(target: "stratum::job_task", "Dropped workers write lock");
             drop(workers_ptr);
 
             // Now poll or wait for a trigger for a new job.
@@ -588,54 +596,79 @@ impl MiningProxy {
         if !params.contains_key("id") ||
             !params.contains_key("job_id") ||
             !params.contains_key("nonce") ||
-            !params.contains_key("result")
+            !params.contains_key("result") ||
+            !params.contains_key("algo")
         {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
         // Validate all the parameters
         let Some(worker_uuid) = params["id"].get::<String>() else {
-            return JsonError::new(InvalidParams, Some("Invalid \"id\" field".to_string()), id)
+            error!(target: "stratum::submit", "[STRATUM] Missing \"id\" field for stratum::submit");
+            return JsonError::new(InvalidParams, Some("Missing \"id\" field".to_string()), id)
                 .into()
         };
 
         let Ok(worker_uuid) = Uuid::try_from(worker_uuid.as_str()) else {
+            error!(target: "stratum::submit", "[STRATUM] Invalid \"id\" field for stratum::submit");
             return JsonError::new(InvalidParams, Some("Invalid \"id\" field".to_string()), id)
                 .into()
         };
 
         let Some(job_id) = params["job_id"].get::<String>() else {
-            return JsonError::new(InvalidParams, Some("Invalid \"job_id\" field".to_string()), id)
+            error!(target: "stratum::submit", "[STRATUM] Missing \"job_id\" field for stratum::submit");
+            return JsonError::new(InvalidParams, Some("Missing \"job_id\" field".to_string()), id)
                 .into()
         };
 
         let Ok(job_id) = blake3::Hash::from_str(job_id) else {
+            error!(target: "stratum::submit", "[STRATUM] Invalid \"job_id\" field for stratum::submit");
             return JsonError::new(InvalidParams, Some("Invalid \"job_id\" field".to_string()), id)
                 .into()
         };
 
         let Some(nonce) = params["nonce"].get::<String>() else {
-            return JsonError::new(InvalidParams, Some("Invalid \"nonce\" field".to_string()), id)
+            error!(target: "stratum::submit", "[STRATUM] Missing \"nonce\" field for stratum::submit");
+            return JsonError::new(InvalidParams, Some("Missing \"nonce\" field".to_string()), id)
                 .into()
         };
 
         let Ok(nonce) = u32::from_str_radix(nonce, 16) else {
+            error!(target: "stratum::submit", "[STRATUM] Invalid \"nonce\" field for stratum::submit");
             return JsonError::new(InvalidParams, Some("Invalid \"nonce\" field".to_string()), id)
                 .into()
         };
 
         let Some(_result) = params["result"].get::<String>() else {
+            error!(target: "stratum::submit", "[STRATUM] Missing \"result\" field for stratum::submit");
             return JsonError::new(InvalidParams, Some("Invalid \"result\" field".to_string()), id)
                 .into()
         };
 
+        let Some(algo) = params["algo"].get::<String>() else {
+            error!(target: "stratum::submit", "[STRATUM] Missing \"algo\" field for stratum::submit");
+            return JsonError::new(InvalidParams, Some("Missing \"algo\" field".to_string()), id)
+                .into()
+        };
+
+        if algo != RANDOMX_ALGO {
+            error!(target: "stratum::submit", "[STRATUM] Invalid \"algo\" field for stratum::submit");
+            return JsonError::new(InvalidParams, Some("Invalid \"algo\" field".to_string()), id)
+                .into()
+        }
+
         // Get the worker reference and confirm this is submitted for the current job
+        debug!(target: "stratum::submit", "Acquiring workers read lock...");
         let workers_ptr = self.workers.read().await;
+        debug!(target: "stratum::submit", "Acquired workers read lock");
+
         let Some(worker) = workers_ptr.get(&worker_uuid) else {
+            error!(target: "stratum::submit", "[STRATUM] Unknown worker UUID for stratum::submit");
             return JsonError::new(InvalidParams, Some("Unknown worker UUID".to_string()), id).into()
         };
 
         if worker.mining_job.job_id != job_id {
+            error!(target: "stratum::submit", "[STRATUM] Job ID mismatch for stratum::submit");
             return JsonError::new(InvalidParams, Some("Job ID mismatch".to_string()), id).into()
         }