Selaa lähdekoodia

mmproxy: Deduplicate and clean up code

parazyd 2 vuotta sitten
vanhempi
sitoutus
df0992b5f7
3 muutettua tiedostoa jossa 86 lisäystä ja 123 poistoa
  1. 1 1
      Cargo.toml
  2. 25 12
      bin/darkfi-mmproxy/src/main.rs
  3. 60 110
      bin/darkfi-mmproxy/src/monerod.rs

+ 1 - 1
Cargo.toml

@@ -319,4 +319,4 @@ zkas = [
 [patch.crates-io]
 halo2_proofs = {git="https://github.com/parazyd/halo2", branch="v4"}
 halo2_gadgets = {git="https://github.com/parazyd/halo2", branch="v4"}
-monero = {git="https://github.com/parazyd/monero-rs", branch="blockhashing_blob-fix"}
+monero = {git="https://github.com/monero-rs/monero-rs", branch="main"}

+ 25 - 12
bin/darkfi-mmproxy/src/main.rs

@@ -39,6 +39,7 @@ const CONFIG_FILE_CONTENTS: &str = include_str!("../darkfi_mmproxy.toml");
 
 /// Monero RPC functions
 mod monerod;
+use monerod::MonerodRequest;
 
 #[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
 #[serde(default)]
@@ -110,8 +111,8 @@ impl MiningProxy {
         // with the matching network
         let self_ = Self { monero_network, monero_rpc: monerod.monero_rpc };
 
-        let req = JsonRequest::new("get_info", vec![].into());
-        let rep: JsonResponse = match self_.monero_post_request(req).await {
+        let req = JsonRequest::new("getinfo", vec![].into());
+        let rep: JsonResponse = match self_.monero_request(MonerodRequest::Post(req)).await {
             Ok(v) => JsonResponse::try_from(&v)?,
             Err(e) => {
                 error!("Failed connecting to monerod RPC: {}", e);
@@ -157,8 +158,9 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
     let mmproxy = Arc::new(MiningProxy::new(args.monerod).await?);
     let mut app = tide::with_state(mmproxy);
 
-    // monerod `/getheight` endpoint proxy
+    // monerod `/getheight` endpoint proxy [HTTP GET]
     app.at("/getheight").get(|req: tide::Request<Arc<MiningProxy>>| async move {
+        debug!(target: "monerod::getheight", "--> /getheight");
         let mmproxy = req.state();
         let return_data = mmproxy.monerod_get_height().await?;
         let return_data = return_data.stringify()?;
@@ -166,8 +168,9 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
         Ok(return_data)
     });
 
-    // monerod `/getinfo` endpoint proxy
+    // monerod `/getinfo` endpoint proxy [HTTP GET]
     app.at("/getinfo").get(|req: tide::Request<Arc<MiningProxy>>| async move {
+        debug!(target: "monerod::getinfo", "--> /getinfo");
         let mmproxy = req.state();
         let return_data = mmproxy.monerod_get_info().await?;
         let return_data = return_data.stringify()?;
@@ -175,11 +178,23 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
         Ok(return_data)
     });
 
-    // monerod `/json_rpc` endpoint proxy
+    // monerod `/json_rpc` endpoint proxy [HTTP POST]
     app.at("/json_rpc").post(|mut req: tide::Request<Arc<MiningProxy>>| async move {
-        let json_str: JsonValue = match req.body_string().await {
-            Ok(v) => v.parse()?,
-            Err(e) => return Err(e),
+        let body_string = match req.body_string().await {
+            Ok(v) => v,
+            Err(e) => {
+                error!(target: "monerod::json_rpc", "Failed reading request body: {}", e);
+                return Err(surf::Error::new(StatusCode::BadRequest, Error::Custom(e.to_string())))
+            }
+        };
+        debug!(target: "monerod::json_rpc", "--> {}", body_string);
+
+        let json_str: JsonValue = match body_string.parse() {
+            Ok(v) => v,
+            Err(e) => {
+                error!(target: "monerod::json_rpc", "Failed parsing JSON body: {}", e);
+                return Err(surf::Error::new(StatusCode::BadRequest, Error::Custom(e.to_string())))
+            }
         };
 
         let JsonValue::Object(ref request) = json_str else {
@@ -197,10 +212,9 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
         }
 
         let mmproxy = req.state();
-        let method = request["method"].get::<String>().unwrap();
 
         // For XMRig we only have to handle 2 methods:
-        let return_data = match method.as_str() {
+        let return_data: JsonValue = match request["method"].get::<String>().unwrap().as_str() {
             "getblocktemplate" => mmproxy.monerod_getblocktemplate(&json_str).await?,
             "submitblock" => mmproxy.monerod_submit_block(&json_str).await?,
             _ => {
@@ -212,8 +226,7 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
         };
 
         let return_data = return_data.stringify()?;
-        let log_tgt = format!("monerod::{}", method);
-        debug!(target: &log_tgt,  "<-- {}", return_data);
+        debug!(target: "monerod::json_rpc",  "<-- {}", return_data);
         Ok(return_data)
     });
 

+ 60 - 110
bin/darkfi-mmproxy/src/monerod.rs

@@ -25,143 +25,91 @@ use darkfi::{
     },
     Error, Result,
 };
-use log::{debug, error};
+use log::{debug, error, info};
 use monero::blockdata::transaction::{ExtraField, RawExtraField, SubField::MergeMining};
 
 use super::MiningProxy;
 
-impl MiningProxy {
-    /// Perform a JSON-RPC GET request to monerod's endpoint with the given method
-    async fn monero_get_request(&self, method: &str) -> Result<JsonValue> {
-        let endpoint = format!("{}{}", self.monero_rpc, method);
-        debug!(target: "monerod::monero_get_request", "--> {}", endpoint);
+/// Types of requests that can be sent to monerod
+pub(crate) enum MonerodRequest {
+    Get(String),
+    Post(JsonRequest),
+}
 
-        let mut rep = match surf::get(&endpoint).await {
-            Ok(v) => v,
-            Err(e) => {
-                error!(
-                    target: "monerod::monero_get_request",
-                    "Failed sending GET request to monerod: {}", e,
-                );
-                return Err(Error::Custom(format!("Failed sending GET request to monerod: {}", e)))
+impl MiningProxy {
+    /// Perform a JSON-RPC request to monerod's endpoint with the given method
+    pub(crate) async fn monero_request(&self, req: MonerodRequest) -> Result<JsonValue> {
+        let mut rep = match req {
+            MonerodRequest::Get(method) => {
+                let endpoint = format!("{}{}", self.monero_rpc, method);
+
+                match surf::get(&endpoint).await {
+                    Ok(v) => v,
+                    Err(e) => {
+                        let e = format!("Failed sending monerod GET request: {}", e);
+                        error!(target: "monerod::monero_request", "{}", e);
+                        return Err(Error::Custom(e))
+                    }
+                }
+            }
+            MonerodRequest::Post(data) => {
+                let endpoint = format!("{}json_rpc", self.monero_rpc);
+                let client = surf::Client::new();
+
+                match client
+                    .get(endpoint)
+                    .header("Content-Type", "application/json")
+                    .body(data.stringify().unwrap())
+                    .send()
+                    .await
+                {
+                    Ok(v) => v,
+                    Err(e) => {
+                        let e = format!("Failed sending monerod POST request: {}", e);
+                        error!(target: "monerod::monero_request", "{}", e);
+                        return Err(Error::Custom(e))
+                    }
+                }
             }
         };
 
-        let json_str: JsonValue = match rep.body_string().await {
+        let json_rep: JsonValue = match rep.body_string().await {
             Ok(v) => match v.parse() {
                 Ok(v) => v,
                 Err(e) => {
-                    error!(
-                        target: "monerod::monero_get_request",
-                        "Failed parsing JSON body string from monerod GET request response: {}", e,
-                    );
-                    return Err(Error::Custom(format!(
-                        "Failed parsing JSON body string from monerod GET request response: {}",
-                        e
-                    )))
+                    let e = format!("Failed parsing JSON string from monerod response: {}", e);
+                    error!(target: "monerod::monero_request", "{}", e);
+                    return Err(Error::Custom(e))
                 }
             },
             Err(e) => {
-                error!(
-                   target: "monerod::monero_get_request",
-                   "Failed parsing body string from monerod GET request response: {}", e,
-                );
-                return Err(Error::Custom(format!(
-                    "Failed parsing body string from monerod GET request response: {}",
-                    e
-                )))
-            }
-        };
-
-        Ok(json_str)
-    }
-
-    /// Perform a JSON-RPC POST request to monerod's endpoint with the given method
-    /// and JSON-RPC request
-    pub async fn monero_post_request(&self, req: JsonRequest) -> Result<JsonValue> {
-        let endpoint = format!("{}json_rpc", self.monero_rpc);
-        debug!(target: "monerod::monero_post_request", "--> {}", endpoint);
-
-        let client = surf::Client::new();
-
-        let mut response = match client
-            .get(endpoint)
-            .header("Content-Type", "application/json")
-            .body(req.stringify()?)
-            .send()
-            .await
-        {
-            Ok(v) => v,
-            Err(e) => {
-                error!(
-                    target: "monerod::monero_post_request",
-                    "Failed sending monerod RPC POST request: {}", e,
-                );
-                return Err(Error::Custom(format!("Failed sending monerod RPC POST request: {}", e)))
-            }
-        };
-
-        let response_bytes = match response.body_bytes().await {
-            Ok(v) => v,
-            Err(e) => {
-                error!(
-                    target: "monerod::monero_post_request",
-                    "Failed decoding monerod RPC POST response body: {}", e,
-                );
-                return Err(Error::Custom(format!(
-                    "Failed decoding monerod RPC POST response body: {}",
-                    e,
-                )))
-            }
-        };
-
-        let response_string = match String::from_utf8(response_bytes) {
-            Ok(v) => v,
-            Err(e) => {
-                error!(
-                    target: "monerod::monero_post_request",
-                    "Failed decoding UTF8 string from monerod RPC POST response body: {}", e,
-                );
-                return Err(Error::Custom(format!(
-                    "Failed decoding UTF8 string from monerod RPC POST response body: {}",
-                    e,
-                )))
-            }
-        };
-
-        let response_json: JsonValue = match response_string.parse() {
-            Ok(v) => v,
-            Err(e) => {
-                error!(
-                    target: "monerod::monero_post_request",
-                    "Failed parsing JSON string from monerod RPC POST response body: {}", e,
-                );
-                return Err(Error::Custom(format!(
-                    "Failed parsing JSON string from monerod RPC POST response body: {}",
-                    e
-                )))
+                let e = format!("Failed parsing body string from monerod response:  {}", e);
+                error!(target: "monerod::monero_request", "{}", e);
+                return Err(Error::Custom(e))
             }
         };
 
-        Ok(response_json)
+        Ok(json_rep)
     }
 
-    /// Proxy the `getheight` RPC request
+    /// Proxy the `/getheight` RPC request
     pub async fn monerod_get_height(&self) -> Result<JsonValue> {
-        let rep = self.monero_get_request("getheight").await?;
+        info!(target: "monerod::getheight", "Proxying /getheight request");
+        let rep = self.monero_request(MonerodRequest::Get("getheight".to_string())).await?;
         Ok(rep)
     }
 
-    /// Proxy the `getinfo` RPC request
+    /// Proxy the `/getinfo` RPC request
     pub async fn monerod_get_info(&self) -> Result<JsonValue> {
-        let rep = self.monero_get_request("getinfo").await?;
+        info!(target: "monerod::getinfo", "Proxying /getinfo request");
+        let rep = self.monero_request(MonerodRequest::Get("getinfo".to_string())).await?;
         Ok(rep)
     }
 
     /// Proxy the `submitblock` RPC request
     pub async fn monerod_submit_block(&self, req: &JsonValue) -> Result<JsonValue> {
+        info!(target: "monerod::submitblock", "Proxying submitblock request");
         let request = JsonRequest::try_from(req)?;
-        debug!(target: "monerod::submitblock", "--> {}", req.stringify()?);
 
         if !request.params.is_array() {
             return Err(Error::Custom("Invalid request".to_string()))
@@ -178,15 +126,15 @@ impl MiningProxy {
             );
         }
 
-        let response = self.monero_post_request(request).await?;
+        let response = self.monero_request(MonerodRequest::Post(request)).await?;
         Ok(response)
     }
 
     /// Perform the `getblocktemplate` request and modify it with the necessary
     /// merge mining data.
     pub async fn monerod_getblocktemplate(&self, req: &JsonValue) -> Result<JsonValue> {
+        info!(target: "monerod::getblocktemplate", "Proxying getblocktemplate request");
         let mut request = JsonRequest::try_from(req)?;
-        debug!(target: "monerod::getblocktemplate", "--> {}", req.stringify()?);
 
         if !request.params.is_object() {
             return Err(Error::Custom("Invalid request".to_string()))
@@ -214,6 +162,8 @@ impl MiningProxy {
         }
 
         // Create the Merge Mining data
+        // TODO: This is where we're gonna include the necessary DarkFi data
+        // that has to end up in Monero blocks.
         let mm_tag = MergeMining(Some(monero::VarInt(32)), monero::Hash([0_u8; 32]));
 
         // Construct `tx_extra` from all the extra fields we have to add to
@@ -228,7 +178,7 @@ impl MiningProxy {
         params.remove("extra_nonce");
 
         // Perform the `getblocktemplate` call:
-        let gbt_response = self.monero_post_request(request).await?;
+        let gbt_response = self.monero_request(MonerodRequest::Post(request)).await?;
         debug!(target: "monerod::getblocktemplate", "Got {}", gbt_response.stringify()?);
         let mut gbt_response = JsonResponse::try_from(&gbt_response)?;
         let gbt_result: &mut HashMap<String, JsonValue> = gbt_response.result.get_mut().unwrap();