Jelajahi Sumber

darkfid/rpc_xmr: check request job still extends current best fork

skoupidi 8 bulan lalu
induk
melakukan
92f0c7ccf6
1 mengubah file dengan 33 tambahan dan 21 penghapusan
  1. 33 21
      bin/darkfid/src/rpc_xmr.rs

+ 33 - 21
bin/darkfid/src/rpc_xmr.rs

@@ -183,15 +183,41 @@ impl DarkfiNode {
         };
         let prev_id = monero::Hash::from_slice(&prev_id);
 
-        // Method params format is correct. Let's check if we provided this
-        // mining job already. If so, we can just return an empty response.
-        // We'll also obtain a lock here to avoid getting polled multiple
-        // times and potentially missing a job. The lock is released when
-        // this function exits.
+        // Now that method params format is correct, we can check if we
+        // already have this mining job. If we already have it, we
+        // check if the fork it extends is still the best one. If both
+        // checks pass, we can just return an empty response. In case
+        // the best fork has changed, we drop this job and generate a
+        // new one. We'll also obtain a lock here to avoid getting
+        // polled multiple times and potentially missing a job. The
+        // lock is released when this function exits.
         let template_key = BlockTemplateHash::new(&address, &aux_hash);
         let mut mm_blocktemplates = self.mm_blocktemplates.lock().await;
-        if mm_blocktemplates.contains_key(&template_key) {
-            return JsonResponse::new(JsonValue::from(HashMap::new()), id).into()
+        let mut extended_fork = match self.best_current_fork().await {
+            Ok(f) => f,
+            Err(e) => {
+                error!(
+                    target: "darkfid::rpc_xmr::xmr_merge_mining_get_aux_block",
+                    "[RPC-XMR] Finding best fork index failed: {e}",
+                );
+                return JsonError::new(ErrorCode::InternalError, None, id).into()
+            }
+        };
+        if let Some((block, _)) = mm_blocktemplates.get(&template_key) {
+            let last_proposal = match extended_fork.last_proposal() {
+                Ok(p) => p,
+                Err(e) => {
+                    error!(
+                        target: "darkfid::rpc_xmr::xmr_merge_mining_get_aux_block",
+                        "[RPC-XMR] Retrieving best fork last proposal failed: {e}",
+                    );
+                    return JsonError::new(ErrorCode::InternalError, None, id).into()
+                }
+            };
+            if last_proposal.hash == block.header.previous {
+                return JsonResponse::new(JsonValue::from(HashMap::new()), id).into()
+            }
+            mm_blocktemplates.remove(&template_key);
         }
 
         info!(
@@ -199,9 +225,6 @@ impl DarkfiNode {
             "[RPC-XMR] Got blocktemplate request: address={address}, aux_hash={aux_hash}, height={height}, prev_id={prev_id}"
         );
 
-        // If it's a new job, clear the previous one(s).
-        mm_blocktemplates.clear();
-
         // At this point, we should query the Validator for a new blocktemplate.
         // We first need to construct `MinerRewardsRecipientConfig` from the
         // address provided to us through the RPC.
@@ -209,17 +232,6 @@ impl DarkfiNode {
             MinerRewardsRecipientConfig { recipient: address, spend_hook: None, user_data: None };
 
         // Now let's try to construct the blocktemplate.
-        let mut extended_fork = match self.best_current_fork().await {
-            Ok(f) => f,
-            Err(e) => {
-                error!(
-                    target: "darkfid::rpc_xmr::xmr_merge_mining_get_aux_block",
-                    "[RPC-XMR] Finding best fork index failed: {e}",
-                );
-                return JsonError::new(ErrorCode::InternalError, None, id).into()
-            }
-        };
-
         // Find the difficulty. Note we cast it to f64 here.
         let difficulty: f64 = match extended_fork.module.next_difficulty() {
             Ok(v) => {