diff --git a/applications/randomx_miner/src/config.rs b/applications/randomx_miner/src/config.rs index 71b6bd4b255..ceebbe6224f 100644 --- a/applications/randomx_miner/src/config.rs +++ b/applications/randomx_miner/src/config.rs @@ -25,7 +25,6 @@ use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; use tari_common::{configuration::Network, SubConfigPath}; -use tari_comms::multiaddr::Multiaddr; #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] diff --git a/applications/randomx_miner/src/error.rs b/applications/randomx_miner/src/error.rs index 5622ea93872..34d4ea72e07 100644 --- a/applications/randomx_miner/src/error.rs +++ b/applications/randomx_miner/src/error.rs @@ -28,8 +28,6 @@ pub enum Error { CommonConfig(#[from] tari_common::configuration::error::ConfigError), #[error("Reqwest error: {0}")] Reqwest(#[from] reqwest::Error), - #[error("General error: {0}")] - General(String), #[error("Request error: {0}")] Request(#[from] RequestError), } diff --git a/applications/randomx_miner/src/json_rpc/get_block_count.rs b/applications/randomx_miner/src/json_rpc/get_block_count.rs new file mode 100644 index 00000000000..bd0af965b1d --- /dev/null +++ b/applications/randomx_miner/src/json_rpc/get_block_count.rs @@ -0,0 +1,78 @@ +// Copyright 2024. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use std::sync::Arc; + +use log::{debug, error}; +use reqwest::Client; +use serde::Deserialize; +use tokio::sync::Mutex; + +use crate::{ + error::{Error, RequestError}, + Request, +}; + +pub const LOG_TARGET: &str = "minotari::randomx_miner::json_rpc::get_block_count"; + +#[allow(dead_code)] // jsonrpc and id fields +#[derive(Deserialize, Debug)] +pub struct GetBlockCountResponse { + jsonrpc: String, + id: String, + pub result: BlockCount, +} + +#[derive(Deserialize, Debug)] +pub struct BlockCount { + pub count: u64, + pub status: String, +} + +pub async fn get_block_count(client: &Client, node_address: &String, tip: Arc>) -> Result<(), Error> { + let response = client + .post(format!("{}/json_rpc", &node_address.to_string())) + .json(&Request::new("get_block_count", serde_json::Value::Null)) + .send() + .await + .map_err(|e| { + error!(target: LOG_TARGET, "Reqwest error: {:?}", e); + Error::from(RequestError::GetBlockCount(e.to_string())) + })? + .json::() + .await?; + debug!(target: LOG_TARGET, "`get_block_count` Response: {:?}", response); + + if response.result.status == "OK" { + debug!(target: LOG_TARGET, "`get_block_count` Blockchain tip (block height): {}", response.result.count); + *tip.lock().await = response.result.count; + } else { + debug!(target: LOG_TARGET, "Failed to get the block count. Status: {}", response.result.status); + return Err(RequestError::GetBlockCount(format!( + "Failed to get the block count. Status: {}", + response.result.status + )) + .into()); + } + + Ok(()) +} diff --git a/applications/randomx_miner/src/json_rpc/get_block_template.rs b/applications/randomx_miner/src/json_rpc/get_block_template.rs new file mode 100644 index 00000000000..ca267d93a99 --- /dev/null +++ b/applications/randomx_miner/src/json_rpc/get_block_template.rs @@ -0,0 +1,89 @@ +// Copyright 2024. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use log::{debug, error}; +use reqwest::Client; +use serde::Deserialize; +use serde_json::json; + +use crate::{ + error::{Error, RequestError}, + Request, +}; + +pub const LOG_TARGET: &str = "minotari::randomx_miner::json_rpc::get_block_template"; + +#[allow(dead_code)] // jsonrpc and id fields +#[derive(Deserialize, Debug)] +pub struct GetBlockTemplateResponse { + jsonrpc: String, + id: String, + pub result: BlockTemplate, +} + +#[allow(dead_code)] // not all fields are used currently +#[derive(Deserialize, Debug)] +pub struct BlockTemplate { + pub blocktemplate_blob: String, + pub blockhashing_blob: String, + pub difficulty: u64, + pub height: u64, + pub prev_hash: String, + pub reserved_offset: u64, + pub status: String, +} + +pub async fn get_block_template( + client: &Client, + node_address: &String, + monero_wallet_address: &String, +) -> Result { + let response = client + .post(format!("{}/json_rpc", &node_address.to_string())) + .json(&Request::new( + "get_block_template", + json!({ + "wallet_address": monero_wallet_address, + "reserve_size": 60, + }), + )) + .send() + .await + .map_err(|e| { + error!(target: LOG_TARGET, "Reqwest error: {:?}", e); + Error::from(RequestError::GetBlockTemplate(e.to_string())) + })? + .json::() + .await?; + debug!(target: LOG_TARGET, "`get_block_template` Response: {:?}", response); + + if response.result.status == "OK" { + Ok(response.result) + } else { + debug!(target: LOG_TARGET, "Failed to get the block template. Status: {}", response.result.status); + Err(RequestError::GetBlockCount(format!( + "Failed to get the block template. Status: {}", + response.result.status + )) + .into()) + } +} diff --git a/applications/randomx_miner/src/json_rpc/mod.rs b/applications/randomx_miner/src/json_rpc/mod.rs index 8fd1be8a143..6407dc4896e 100644 --- a/applications/randomx_miner/src/json_rpc/mod.rs +++ b/applications/randomx_miner/src/json_rpc/mod.rs @@ -20,7 +20,12 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use serde::{Deserialize, Serialize}; +use serde::Serialize; + +mod get_block_count; +mod get_block_template; +pub use get_block_count::get_block_count; +pub use get_block_template::get_block_template; #[derive(Serialize)] pub struct Request<'a> { @@ -40,34 +45,3 @@ impl Request<'_> { } } } - -#[derive(Deserialize, Debug)] -pub struct GetBlockCountResponse { - jsonrpc: String, - id: String, - pub result: GetBlockCountResult, -} - -#[derive(Deserialize, Debug)] -pub struct GetBlockCountResult { - pub count: u64, - pub status: String, -} - -#[derive(Deserialize, Debug)] -pub struct GetBlockTemplateResponse { - jsonrpc: String, - id: String, - pub result: GetBlockTemplateResult, -} - -#[derive(Deserialize, Debug)] -pub struct GetBlockTemplateResult { - pub blocktemplate_blob: String, - pub blockhashing_blob: String, - pub difficulty: u64, - pub height: u64, - pub prev_hash: String, - pub reserved_offset: u64, - pub status: String, -} diff --git a/applications/randomx_miner/src/run_miner.rs b/applications/randomx_miner/src/run_miner.rs index 60c2bb20f93..e99a711ef8b 100644 --- a/applications/randomx_miner/src/run_miner.rs +++ b/applications/randomx_miner/src/run_miner.rs @@ -22,23 +22,19 @@ use std::{sync::Arc, time::Duration}; -use log::{debug, error, info}; -use minotari_app_utilities::parse_miner_input::wallet_payment_address; +use log::info; use reqwest::Client; -use serde::{Deserialize, Serialize}; -use serde_json::json; use tari_common::{load_configuration, DefaultConfigLoader}; use tokio::{sync::Mutex, time::sleep}; use crate::{ cli::Cli, config::RandomXMinerConfig, - error::{ConfigError, Error, RequestError}, - json_rpc::{GetBlockCountResponse, GetBlockTemplateResponse, Request}, + error::{ConfigError, Error}, + json_rpc::{get_block_count, get_block_template}, }; pub const LOG_TARGET: &str = "minotari::randomx_miner::main"; -pub const LOG_TARGET_FILE: &str = "minotari::logging::randomx_miner::main"; pub async fn start_miner(cli: Cli) -> Result<(), Error> { let config_path = cli.common.config_path(); @@ -61,66 +57,9 @@ pub async fn start_miner(cli: Cli) -> Result<(), Error> { loop { info!(target: LOG_TARGET, "Starting new mining cycle"); - get_tip_info(&client, &node_address, tip.clone()).await?; - get_block_template(&client, &node_address, &monero_wallet_address).await?; - sleep(Duration::from_secs(15)).await - } -} - -async fn get_tip_info(client: &Client, node_address: &String, tip: Arc>) -> Result<(), Error> { - let response = client - .post(format!("{}/json_rpc", &node_address.to_string())) // Replace with your node's address - .json(&Request::new("get_block_count", serde_json::Value::Null)) - .send().await.map_err(|e| { - error!(target: LOG_TARGET, "Reqwest error: {:?}", e); - Error::from(RequestError::GetBlockCount(e.to_string())) - })? - .json::().await?; - debug!(target: LOG_TARGET, "`get_block_count` Response: {:?}", response); - - if response.result.status == "OK" { - debug!(target: LOG_TARGET, "`get_block_count` Blockchain tip (block height): {}", response.result.count); - *tip.lock().await = response.result.count; - } else { - debug!(target: LOG_TARGET, "Failed to get the block count. Status: {}", response.result.status); - return Err(RequestError::GetBlockCount(format!( - "Failed to get the block count. Status: {}", - response.result.status - )) - .into()); - } + get_block_count(&client, &node_address, tip.clone()).await?; + let block_template = get_block_template(&client, &node_address, &monero_wallet_address).await?; - Ok(()) -} - -async fn get_block_template( - client: &Client, - node_address: &String, - monero_wallet_address: &String, -) -> Result<(), Error> { - let response = client - .post(format!("{}/json_rpc", &node_address.to_string())) // Replace with your node's address - .json(&Request::new("get_block_template", json!({ - "wallet_address": monero_wallet_address, - "reserve_size": 60, - }))) - .send().await.map_err(|e| { - error!(target: LOG_TARGET, "Reqwest error: {:?}", e); - Error::from(RequestError::GetBlockTemplate(e.to_string())) - })? - .json::().await?; - debug!(target: LOG_TARGET, "`get_block_template` Response: {:?}", response); - - if response.result.status == "OK" { - debug!(target: LOG_TARGET, "`get_block_template` Block template: {:?}", response.result); - } else { - debug!(target: LOG_TARGET, "Failed to get the block template. Status: {}", response.result.status); - return Err(RequestError::GetBlockCount(format!( - "Failed to get the block template. Status: {}", - response.result.status - )) - .into()); + sleep(Duration::from_secs(15)).await } - - Ok(()) }