From cc32e5ab9588762ea79502a57808484d8f0409cb Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Tue, 10 Sep 2024 15:56:54 +0200 Subject: [PATCH 01/13] Add clythor to binary resolver --- src-tauri/src/binary_resolver.rs | 45 ++++++++++++++++++++++++++++---- src-tauri/src/main.rs | 11 ++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src-tauri/src/binary_resolver.rs b/src-tauri/src/binary_resolver.rs index 81fa41d47..984d3af52 100644 --- a/src-tauri/src/binary_resolver.rs +++ b/src-tauri/src/binary_resolver.rs @@ -35,7 +35,10 @@ pub struct VersionAsset { #[async_trait] pub trait LatestVersionApiAdapter: Send + Sync + 'static { - async fn fetch_latest_release(&self) -> Result; + async fn fetch_latest_release( + &self, + is_prereleases: bool, + ) -> Result; fn get_binary_folder(&self) -> PathBuf; @@ -49,7 +52,10 @@ pub struct XmrigVersionApiAdapter {} #[async_trait] impl LatestVersionApiAdapter for XmrigVersionApiAdapter { - async fn fetch_latest_release(&self) -> Result { + async fn fetch_latest_release( + &self, + _is_prerelease: bool, + ) -> Result { todo!() } @@ -73,14 +79,20 @@ pub struct GithubReleasesAdapter { #[async_trait] impl LatestVersionApiAdapter for GithubReleasesAdapter { - async fn fetch_latest_release(&self) -> Result { + async fn fetch_latest_release( + &self, + is_prerelease: bool, + ) -> Result { let releases = github::list_releases(&self.owner, &self.repo).await?; // dbg!(&releases); let network = "pre"; let version = releases .iter() .filter_map(|v| { - if v.version.pre.starts_with(network) { + if is_prerelease && v.version.pre.starts_with(network) { + info!(target: LOG_TARGET, "Found candidate version: {}", v.version); + Some(&v.version) + } else if !is_prerelease && v.version.pre.is_empty() { info!(target: LOG_TARGET, "Found candidate version: {}", v.version); Some(&v.version) } else { @@ -150,6 +162,14 @@ impl LatestVersionApiAdapter for GithubReleasesAdapter { impl BinaryResolver { pub fn new() -> Self { let mut adapters = HashMap::>::new(); + adapters.insert( + Binaries::Clythor, + Box::new(GithubReleasesAdapter { + repo: "clythor".to_string(), + owner: "tari-project".to_string(), + specific_name: None, + }), + ); adapters.insert(Binaries::Xmrig, Box::new(XmrigVersionApiAdapter {})); adapters.insert( Binaries::MergeMiningProxy, @@ -203,6 +223,13 @@ impl BinaryResolver { &INSTANCE } + pub fn should_be_prerelease(binary: Binaries) -> bool { + match binary { + Binaries::Clythor => false, + _ => true, + } + } + pub async fn resolve_path(&self, binary: Binaries) -> Result { let adapter = self .adapters @@ -242,7 +269,9 @@ impl BinaryResolver { .adapters .get(&binary) .ok_or_else(|| anyhow!("No latest version adapter for this binary"))?; - let latest_release = adapter.fetch_latest_release().await?; + let latest_release = adapter + .fetch_latest_release(Self::should_be_prerelease(binary)) + .await?; // TODO: validate that version doesn't have any ".." or "/" in it let bin_folder = adapter @@ -401,6 +430,10 @@ impl BinaryResolver { fn get_binary_name(binary: Binaries, base_dir: PathBuf) -> Result { match binary { + Binaries::Clythor => { + let clythor_bin = base_dir.join("clythor"); + Ok(clythor_bin) + } Binaries::Xmrig => { let xmrig_bin = base_dir.join("xmrig"); Ok(xmrig_bin) @@ -431,6 +464,7 @@ fn get_binary_name(binary: Binaries, base_dir: PathBuf) -> Result &str { match self { + Binaries::Clythor => "clythor", Binaries::Xmrig => "xmrig", Binaries::MergeMiningProxy => "mmproxy", Binaries::MinotariNode => "minotari_node", diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 60e2c6300..084d3c3bd 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -215,6 +215,9 @@ async fn setup_inner( .initialize(app.clone(), state.airdrop_access_token.clone()) .await?; + BinaryResolver::current() + .read_current_highest_version(Binaries::Clythor, progress.clone()) + .await?; BinaryResolver::current() .read_current_highest_version(Binaries::MinotariNode, progress.clone()) .await?; @@ -244,6 +247,14 @@ async fn setup_inner( .set_last_binaries_update_timestamp(now) .await?; + progress.set_max(5).await; + progress + .update("checking-latest-version-clythor".to_string(), None, 0) + .await; + BinaryResolver::current() + .ensure_latest(Binaries::Clythor, progress.clone()) + .await?; + progress.set_max(10).await; progress .update("checking-latest-version-node".to_string(), None, 0) From 92bb5225e536759916cdb088b832872b10e5240b Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Tue, 10 Sep 2024 18:46:24 +0200 Subject: [PATCH 02/13] Add clythor adapter --- src-tauri/src/clythor/http_api/mod.rs | 42 +++++++ src-tauri/src/clythor/http_api/models.rs | 36 ++++++ src-tauri/src/clythor/mod.rs | 1 + src-tauri/src/clythor_adapter.rs | 139 +++++++++++++++++++++++ src-tauri/src/main.rs | 2 + 5 files changed, 220 insertions(+) create mode 100644 src-tauri/src/clythor/http_api/mod.rs create mode 100644 src-tauri/src/clythor/http_api/models.rs create mode 100644 src-tauri/src/clythor/mod.rs create mode 100644 src-tauri/src/clythor_adapter.rs diff --git a/src-tauri/src/clythor/http_api/mod.rs b/src-tauri/src/clythor/http_api/mod.rs new file mode 100644 index 000000000..85ae8e8df --- /dev/null +++ b/src-tauri/src/clythor/http_api/mod.rs @@ -0,0 +1,42 @@ +mod models; +use log::{debug, error}; +const LOG_TARGET: &str = "tari::universe::clythor::http_api"; + +pub struct ClythorHttpApiClient { + url: String, + access_token: String, +} + +impl ClythorHttpApiClient { + pub fn new(url: String, access_token: String) -> Self { + Self { url, access_token } + } + + async fn get(&self, path: &str) -> Result { + let url = format!("{}/{}", self.url, path); + reqwest::Client::new() + .get(&url) + .header("Authorization", format!("Bearer {}", self.access_token)) + .send() + .await + } + + pub async fn summary(&self) -> Result { + for _i in 0..3 { + let response = self.get("2/summary").await?; + + let summary = response.text().await?; + let summary: models::Summary = match serde_json::from_str(&summary) { + Ok(summary) => summary, + Err(e) => { + debug!(target: LOG_TARGET, "summary: {:?}", summary); + error!(target: LOG_TARGET, "Failed to parse clythor summary: {}", e); + continue; + } + }; + + return Ok(summary); + } + Err(anyhow::anyhow!("Failed to get clythor summary")) + } +} diff --git a/src-tauri/src/clythor/http_api/models.rs b/src-tauri/src/clythor/http_api/models.rs new file mode 100644 index 000000000..8a562f69b --- /dev/null +++ b/src-tauri/src/clythor/http_api/models.rs @@ -0,0 +1,36 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub(crate) struct Summary { + pub(crate) connection: Connection, + + pub(crate) hashrate: Hashrate, + // hugepages: bool, +} + +#[derive(Deserialize, Debug)] +pub struct Resources {} + +#[derive(Deserialize, Debug)] +pub struct Memory {} + +#[derive(Deserialize, Debug)] +pub struct Results { + // Sometimes this is not present in v6.21.0 + // error_log: Vec, +} + +#[derive(Deserialize, Debug)] +pub struct Connection { + pub(crate) uptime: u64, + // Sometimes doesn't exist + // pub(crate) error_log: Vec, +} + +#[derive(Deserialize, Debug)] +pub struct Cpu {} + +#[derive(Deserialize, Debug)] +pub struct Hashrate { + pub(crate) total: Vec>, +} diff --git a/src-tauri/src/clythor/mod.rs b/src-tauri/src/clythor/mod.rs new file mode 100644 index 000000000..7c1cd8894 --- /dev/null +++ b/src-tauri/src/clythor/mod.rs @@ -0,0 +1 @@ +pub(crate) mod http_api; diff --git a/src-tauri/src/clythor_adapter.rs b/src-tauri/src/clythor_adapter.rs new file mode 100644 index 000000000..6b4544d9c --- /dev/null +++ b/src-tauri/src/clythor_adapter.rs @@ -0,0 +1,139 @@ +use std::path::PathBuf; + +use anyhow::Error; +use async_trait::async_trait; +use log::warn; +use tari_shutdown::Shutdown; + +use crate::clythor::http_api::ClythorHttpApiClient; +use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; +use crate::process_utils; + +const LOG_TARGET: &str = "tari::universe::clythor_adapter"; + +pub struct LocalMmproxy { + host_name: String, + port: u16, +} + +pub struct ClythorAdapter { + version: String, + node_connection: LocalMmproxy, + monero_address: String, + http_api_token: String, + http_api_port: u16, + cache_dir: PathBuf, + mining_threads: usize, + pub client: ClythorHttpApiClient, + // TODO: secure +} + +impl ClythorAdapter { + pub fn new( + node_connection: LocalMmproxy, + monero_address: String, + cache_dir: PathBuf, + mining_threads: usize, + version: String, + ) -> Self { + let http_api_port = 18000; + let http_api_token = "pass".to_string(); + Self { + node_connection, + monero_address, + http_api_token: http_api_token.clone(), + http_api_port, + cache_dir, + mining_threads, + version, + client: ClythorHttpApiClient::new( + format!("http://127.0.0.1:{}", http_api_port).clone(), + http_api_token.clone(), + ), + } + } +} + +impl ProcessAdapter for ClythorAdapter { + type StatusMonitor = ClythorStatusMonitor; + + fn spawn_inner( + &self, + data_dir: PathBuf, + _config_dir: PathBuf, + log_dir: PathBuf, + ) -> Result<(ProcessInstance, Self::StatusMonitor), anyhow::Error> { + self.kill_previous_instances(data_dir.clone())?; + + let cache_dir = self.cache_dir.clone(); + let clythor_shutdown = Shutdown::new(); + let mut shutdown_signal = clythor_shutdown.to_signal(); + let clythor_log_file = log_dir.join("clythor.log"); + std::fs::create_dir_all(clythor_log_file.parent().unwrap())?; + let args = vec![ + format!("--log-path={}", &clythor_log_file.to_str().unwrap()), + format!("--http-port={}", self.http_api_port), + format!("--access-token={}", self.http_api_token), + format!("--user={}", self.monero_address), + format!("--threads={}", self.mining_threads), + format!( + "--monero-base-node-address={}:{}", + self.node_connection.host_name, self.node_connection.port + ), + ]; + + let version = self.version.clone(); + + Ok(( + ProcessInstance { + shutdown: clythor_shutdown, + handle: Some(tokio::spawn(async move { + let clythor_dir = cache_dir + .clone() + .join("clythor") + .join(&version) + .join(format!("clythor-{}", version)); + let clythor_bin = clythor_dir.join("clythor"); + let mut clythor = + process_utils::launch_child_process(&clythor_bin, None, &args)?; + + if let Some(id) = clythor.id() { + std::fs::write(data_dir.join("clythor_pid"), id.to_string())?; + } + shutdown_signal.wait().await; + + clythor.kill().await?; + + match std::fs::remove_file(data_dir.join("clythor_pid")) { + Ok(_) => {} + Err(e) => { + warn!(target: LOG_TARGET, "Could not clear clythor's pid file - {e}"); + } + } + + Ok(0) + })), + }, + ClythorStatusMonitor {}, + )) + } + + fn name(&self) -> &str { + "clythor" + } + + fn pid_file_name(&self) -> &str { + "clythor_pid" + } +} + +pub struct ClythorStatusMonitor {} + +#[async_trait] +impl StatusMonitor for ClythorStatusMonitor { + type Status = (); + + async fn status(&self) -> Result { + todo!() + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 084d3c3bd..4a35a0bac 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,6 +4,8 @@ mod app_config; mod app_in_memory_config; mod binary_resolver; +mod clythor; +mod clythor_adapter; mod consts; mod cpu_miner; mod download_utils; From c9bb769efaee413f2fab3e7ae2e287910622e3f5 Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Wed, 11 Sep 2024 19:36:30 +0200 Subject: [PATCH 03/13] Replace xmrig with clythor randomX miner --- src-tauri/Cargo.lock | 11 ++++ src-tauri/Cargo.toml | 3 ++ src-tauri/src/clythor/http_api/mod.rs | 2 +- src-tauri/src/clythor_adapter.rs | 42 +++++++--------- src-tauri/src/cpu_miner.rs | 72 ++++++++++++++++++--------- src-tauri/src/hardware_monitor.rs | 2 +- src-tauri/src/xmrig/http_api/mod.rs | 2 +- 7 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index b09214275..e15ce9f3b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3565,6 +3565,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.3.1+3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" version = "0.9.103" @@ -3573,6 +3582,7 @@ checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -5514,6 +5524,7 @@ dependencies = [ "nix 0.29.0", "nvml-wrapper", "open 5.3.0", + "openssl", "rand 0.8.5", "regex", "reqwest 0.12.5", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index aad746a15..edb59c38f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -68,6 +68,9 @@ nix = { version = "0.29.0", features = ["signal"] } sha2 = "0.10.8" regex = "1.10.5" +[target.'cfg(unix)'.dependencies] +openssl = { version = "0.10.66", features = ["vendored"] } + # static bind lzma xz2 = { version = "0.1.7", features = ["static"] } # humantime = "2.1.0" diff --git a/src-tauri/src/clythor/http_api/mod.rs b/src-tauri/src/clythor/http_api/mod.rs index 85ae8e8df..fcd5cc93a 100644 --- a/src-tauri/src/clythor/http_api/mod.rs +++ b/src-tauri/src/clythor/http_api/mod.rs @@ -1,4 +1,4 @@ -mod models; +use crate::xmrig::http_api::models; use log::{debug, error}; const LOG_TARGET: &str = "tari::universe::clythor::http_api"; diff --git a/src-tauri/src/clythor_adapter.rs b/src-tauri/src/clythor_adapter.rs index 6b4544d9c..c34401ea0 100644 --- a/src-tauri/src/clythor_adapter.rs +++ b/src-tauri/src/clythor_adapter.rs @@ -5,6 +5,7 @@ use async_trait::async_trait; use log::warn; use tari_shutdown::Shutdown; +use crate::binary_resolver::{Binaries, BinaryResolver}; use crate::clythor::http_api::ClythorHttpApiClient; use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; use crate::process_utils; @@ -12,17 +13,15 @@ use crate::process_utils; const LOG_TARGET: &str = "tari::universe::clythor_adapter"; pub struct LocalMmproxy { - host_name: String, - port: u16, + pub host_name: String, + pub port: u16, } pub struct ClythorAdapter { - version: String, node_connection: LocalMmproxy, monero_address: String, http_api_token: String, http_api_port: u16, - cache_dir: PathBuf, mining_threads: usize, pub client: ClythorHttpApiClient, // TODO: secure @@ -32,9 +31,7 @@ impl ClythorAdapter { pub fn new( node_connection: LocalMmproxy, monero_address: String, - cache_dir: PathBuf, mining_threads: usize, - version: String, ) -> Self { let http_api_port = 18000; let http_api_token = "pass".to_string(); @@ -43,9 +40,7 @@ impl ClythorAdapter { monero_address, http_api_token: http_api_token.clone(), http_api_port, - cache_dir, mining_threads, - version, client: ClythorHttpApiClient::new( format!("http://127.0.0.1:{}", http_api_port).clone(), http_api_token.clone(), @@ -65,13 +60,15 @@ impl ProcessAdapter for ClythorAdapter { ) -> Result<(ProcessInstance, Self::StatusMonitor), anyhow::Error> { self.kill_previous_instances(data_dir.clone())?; - let cache_dir = self.cache_dir.clone(); let clythor_shutdown = Shutdown::new(); let mut shutdown_signal = clythor_shutdown.to_signal(); let clythor_log_file = log_dir.join("clythor.log"); std::fs::create_dir_all(clythor_log_file.parent().unwrap())?; let args = vec![ - format!("--log-path={}", &clythor_log_file.to_str().unwrap()), + format!( + "--log-path={}", + &clythor_log_file.parent().unwrap().to_str().unwrap() + ), format!("--http-port={}", self.http_api_port), format!("--access-token={}", self.http_api_token), format!("--user={}", self.monero_address), @@ -82,27 +79,24 @@ impl ProcessAdapter for ClythorAdapter { ), ]; - let version = self.version.clone(); - Ok(( ProcessInstance { shutdown: clythor_shutdown, handle: Some(tokio::spawn(async move { - let clythor_dir = cache_dir - .clone() - .join("clythor") - .join(&version) - .join(format!("clythor-{}", version)); - let clythor_bin = clythor_dir.join("clythor"); - let mut clythor = - process_utils::launch_child_process(&clythor_bin, None, &args)?; - - if let Some(id) = clythor.id() { - std::fs::write(data_dir.join("clythor_pid"), id.to_string())?; + let clythor_bin = BinaryResolver::current() + .resolve_path(Binaries::Clythor) + .await?; + + crate::download_utils::set_permissions(&clythor_bin).await?; + let mut child = process_utils::launch_child_process(&clythor_bin, None, &args)?; + + if let Some(id) = child.id() { + let pid_file_path = data_dir.join("clythor_pid"); + std::fs::write(pid_file_path, id.to_string())?; } shutdown_signal.wait().await; - clythor.kill().await?; + child.kill().await?; match std::fs::remove_file(data_dir.join("clythor_pid")) { Ok(_) => {} diff --git a/src-tauri/src/cpu_miner.rs b/src-tauri/src/cpu_miner.rs index 54d26e0f2..cc1bbde6b 100644 --- a/src-tauri/src/cpu_miner.rs +++ b/src-tauri/src/cpu_miner.rs @@ -1,9 +1,12 @@ use crate::app_config::MiningMode; +use crate::clythor::http_api::ClythorHttpApiClient; +use crate::clythor_adapter::{ClythorAdapter, LocalMmproxy}; use crate::process_adapter::ProcessAdapter; -use crate::xmrig::http_api::XmrigHttpApiClient; +use crate::xmrig::http_api::{models, XmrigHttpApiClient}; use crate::xmrig_adapter::{XmrigAdapter, XmrigNodeConnection}; use crate::{ - CpuMinerConfig, CpuMinerConnection, CpuMinerConnectionStatus, CpuMinerStatus, ProgressTracker, + binary_resolver, CpuMinerConfig, CpuMinerConnection, CpuMinerConnectionStatus, CpuMinerStatus, + ProgressTracker, }; use log::{debug, error, info, warn}; use std::path::PathBuf; @@ -17,10 +20,24 @@ use tokio::time::MissedTickBehavior; const RANDOMX_BLOCKS_PER_DAY: u64 = 360; const LOG_TARGET: &str = "tari::universe::cpu_miner"; +pub enum ApiClient { + Xmrig(XmrigHttpApiClient), + Clythor(ClythorHttpApiClient), +} + +impl ApiClient { + pub async fn summary(&self) -> Result { + match self { + ApiClient::Xmrig(client) => client.summary().await, + ApiClient::Clythor(client) => client.summary().await, + } + } +} + pub(crate) struct CpuMiner { watcher_task: Option>>, miner_shutdown: Shutdown, - api_client: Option, + api_client: Option, is_mining: bool, } @@ -55,15 +72,21 @@ impl CpuMiner { self.miner_shutdown = Shutdown::new(); let mut inner_shutdown = self.miner_shutdown.to_signal(); - let xmrig_node_connection = match cpu_miner_config.node_connection { - CpuMinerConnection::BuiltInProxy => { - XmrigNodeConnection::LocalMmproxy { - host_name: "127.0.0.1".to_string(), - // port: local_mm_proxy.try_get_listening_port().await? - // TODO: Replace with actual port - port: monero_port, - } - } + // let xmrig_node_connection = match cpu_miner_config.node_connection { + // CpuMinerConnection::BuiltInProxy => { + // XmrigNodeConnection::LocalMmproxy { + // host_name: "127.0.0.1".to_string(), + // // port: local_mm_proxy.try_get_listening_port().await? + // // TODO: Replace with actual port + // port: monero_port, + // } + // } + // }; + let node_connection = match cpu_miner_config.node_connection { + CpuMinerConnection::BuiltInProxy => LocalMmproxy { + host_name: "http://127.0.0.1".to_string(), + port: monero_port, + }, }; let max_cpu_available = thread::available_parallelism(); let max_cpu_available = match max_cpu_available { @@ -76,22 +99,23 @@ impl CpuMiner { 1 } }; - let cpu_max_percentage = match mode { + let mining_threads = match mode { MiningMode::Eco => (30 * max_cpu_available) / 100, MiningMode::Ludicrous => max_cpu_available, }; - let xmrig_version = - XmrigAdapter::ensure_latest(cache_dir.clone(), false, progress_tracker.clone()).await?; - let xmrig = XmrigAdapter::new( - xmrig_node_connection, - monero_address.clone(), - cache_dir, - cpu_max_percentage, - xmrig_version, - ); + // let xmrig_version = + // XmrigAdapter::ensure_latest(cache_dir.clone(), false, progress_tracker.clone()).await?; + // let xmrig = XmrigAdapter::new( + // xmrig_node_connection, + // monero_address.clone(), + // cache_dir, + // cpu_max_percentage, + // xmrig_version, + // ); + let clythor = ClythorAdapter::new(node_connection, monero_address.clone(), mining_threads); let (mut xmrig_child, _xmrig_status_monitor) = - xmrig.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; - self.api_client = Some(xmrig.client); + clythor.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; + self.api_client = Some(ApiClient::Clythor(clythor.client)); self.watcher_task = Some(tauri::async_runtime::spawn(async move { let mut watch_timer = tokio::time::interval(tokio::time::Duration::from_secs(1)); diff --git a/src-tauri/src/hardware_monitor.rs b/src-tauri/src/hardware_monitor.rs index d3a1b4585..d72b7822e 100644 --- a/src-tauri/src/hardware_monitor.rs +++ b/src-tauri/src/hardware_monitor.rs @@ -316,7 +316,7 @@ impl HardwareMonitorImpl for LinuxHardwareMonitor { let nvml: &Nvml = match &self.nvml { Some(nvml) => nvml, None => { - println!("Failed to get NVML"); + // println!("Failed to get NVML"); return HardwareParameters { label: "N/A".to_string(), usage_percentage: 0.0, diff --git a/src-tauri/src/xmrig/http_api/mod.rs b/src-tauri/src/xmrig/http_api/mod.rs index 6d72e237f..7b3a65623 100644 --- a/src-tauri/src/xmrig/http_api/mod.rs +++ b/src-tauri/src/xmrig/http_api/mod.rs @@ -1,4 +1,4 @@ -mod models; +pub mod models; use log::{debug, error}; const LOG_TARGET: &str = "tari::universe::xmrig::http_api"; From 397c2dd863b962a75e354ecd0fa7717919ac7730 Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Thu, 12 Sep 2024 13:38:29 +0200 Subject: [PATCH 04/13] Refactor Clythor adapter --- src-tauri/Cargo.lock | 11 --- src-tauri/Cargo.toml | 3 - src-tauri/src/clythor/http_api/mod.rs | 42 ---------- src-tauri/src/clythor/http_api/models.rs | 36 -------- src-tauri/src/clythor/mod.rs | 1 - src-tauri/src/clythor_adapter.rs | 11 +-- src-tauri/src/cpu_miner.rs | 102 ++++++----------------- src-tauri/src/main.rs | 1 - 8 files changed, 32 insertions(+), 175 deletions(-) delete mode 100644 src-tauri/src/clythor/http_api/mod.rs delete mode 100644 src-tauri/src/clythor/http_api/models.rs delete mode 100644 src-tauri/src/clythor/mod.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index e15ce9f3b..b09214275 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3565,15 +3565,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.3.1+3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.103" @@ -3582,7 +3573,6 @@ checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -5524,7 +5514,6 @@ dependencies = [ "nix 0.29.0", "nvml-wrapper", "open 5.3.0", - "openssl", "rand 0.8.5", "regex", "reqwest 0.12.5", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index edb59c38f..aad746a15 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -68,9 +68,6 @@ nix = { version = "0.29.0", features = ["signal"] } sha2 = "0.10.8" regex = "1.10.5" -[target.'cfg(unix)'.dependencies] -openssl = { version = "0.10.66", features = ["vendored"] } - # static bind lzma xz2 = { version = "0.1.7", features = ["static"] } # humantime = "2.1.0" diff --git a/src-tauri/src/clythor/http_api/mod.rs b/src-tauri/src/clythor/http_api/mod.rs deleted file mode 100644 index fcd5cc93a..000000000 --- a/src-tauri/src/clythor/http_api/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::xmrig::http_api::models; -use log::{debug, error}; -const LOG_TARGET: &str = "tari::universe::clythor::http_api"; - -pub struct ClythorHttpApiClient { - url: String, - access_token: String, -} - -impl ClythorHttpApiClient { - pub fn new(url: String, access_token: String) -> Self { - Self { url, access_token } - } - - async fn get(&self, path: &str) -> Result { - let url = format!("{}/{}", self.url, path); - reqwest::Client::new() - .get(&url) - .header("Authorization", format!("Bearer {}", self.access_token)) - .send() - .await - } - - pub async fn summary(&self) -> Result { - for _i in 0..3 { - let response = self.get("2/summary").await?; - - let summary = response.text().await?; - let summary: models::Summary = match serde_json::from_str(&summary) { - Ok(summary) => summary, - Err(e) => { - debug!(target: LOG_TARGET, "summary: {:?}", summary); - error!(target: LOG_TARGET, "Failed to parse clythor summary: {}", e); - continue; - } - }; - - return Ok(summary); - } - Err(anyhow::anyhow!("Failed to get clythor summary")) - } -} diff --git a/src-tauri/src/clythor/http_api/models.rs b/src-tauri/src/clythor/http_api/models.rs deleted file mode 100644 index 8a562f69b..000000000 --- a/src-tauri/src/clythor/http_api/models.rs +++ /dev/null @@ -1,36 +0,0 @@ -use serde::Deserialize; - -#[derive(Deserialize, Debug)] -pub(crate) struct Summary { - pub(crate) connection: Connection, - - pub(crate) hashrate: Hashrate, - // hugepages: bool, -} - -#[derive(Deserialize, Debug)] -pub struct Resources {} - -#[derive(Deserialize, Debug)] -pub struct Memory {} - -#[derive(Deserialize, Debug)] -pub struct Results { - // Sometimes this is not present in v6.21.0 - // error_log: Vec, -} - -#[derive(Deserialize, Debug)] -pub struct Connection { - pub(crate) uptime: u64, - // Sometimes doesn't exist - // pub(crate) error_log: Vec, -} - -#[derive(Deserialize, Debug)] -pub struct Cpu {} - -#[derive(Deserialize, Debug)] -pub struct Hashrate { - pub(crate) total: Vec>, -} diff --git a/src-tauri/src/clythor/mod.rs b/src-tauri/src/clythor/mod.rs deleted file mode 100644 index 7c1cd8894..000000000 --- a/src-tauri/src/clythor/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod http_api; diff --git a/src-tauri/src/clythor_adapter.rs b/src-tauri/src/clythor_adapter.rs index c34401ea0..35f5ceea1 100644 --- a/src-tauri/src/clythor_adapter.rs +++ b/src-tauri/src/clythor_adapter.rs @@ -6,9 +6,9 @@ use log::warn; use tari_shutdown::Shutdown; use crate::binary_resolver::{Binaries, BinaryResolver}; -use crate::clythor::http_api::ClythorHttpApiClient; use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; use crate::process_utils; +use crate::xmrig::http_api::XmrigHttpApiClient; const LOG_TARGET: &str = "tari::universe::clythor_adapter"; @@ -23,7 +23,7 @@ pub struct ClythorAdapter { http_api_token: String, http_api_port: u16, mining_threads: usize, - pub client: ClythorHttpApiClient, + pub client: XmrigHttpApiClient, // TODO: secure } @@ -41,7 +41,7 @@ impl ClythorAdapter { http_api_token: http_api_token.clone(), http_api_port, mining_threads, - client: ClythorHttpApiClient::new( + client: XmrigHttpApiClient::new( format!("http://127.0.0.1:{}", http_api_port).clone(), http_api_token.clone(), ), @@ -78,6 +78,7 @@ impl ProcessAdapter for ClythorAdapter { self.node_connection.host_name, self.node_connection.port ), ]; + let pid_file_path = data_dir.join(&self.pid_file_name()); Ok(( ProcessInstance { @@ -91,14 +92,14 @@ impl ProcessAdapter for ClythorAdapter { let mut child = process_utils::launch_child_process(&clythor_bin, None, &args)?; if let Some(id) = child.id() { - let pid_file_path = data_dir.join("clythor_pid"); + let pid_file_path = data_dir.join(&pid_file_path); std::fs::write(pid_file_path, id.to_string())?; } shutdown_signal.wait().await; child.kill().await?; - match std::fs::remove_file(data_dir.join("clythor_pid")) { + match std::fs::remove_file(data_dir.join(&pid_file_path)) { Ok(_) => {} Err(e) => { warn!(target: LOG_TARGET, "Could not clear clythor's pid file - {e}"); diff --git a/src-tauri/src/cpu_miner.rs b/src-tauri/src/cpu_miner.rs index cc1bbde6b..cbf382496 100644 --- a/src-tauri/src/cpu_miner.rs +++ b/src-tauri/src/cpu_miner.rs @@ -1,5 +1,4 @@ use crate::app_config::MiningMode; -use crate::clythor::http_api::ClythorHttpApiClient; use crate::clythor_adapter::{ClythorAdapter, LocalMmproxy}; use crate::process_adapter::ProcessAdapter; use crate::xmrig::http_api::{models, XmrigHttpApiClient}; @@ -20,24 +19,10 @@ use tokio::time::MissedTickBehavior; const RANDOMX_BLOCKS_PER_DAY: u64 = 360; const LOG_TARGET: &str = "tari::universe::cpu_miner"; -pub enum ApiClient { - Xmrig(XmrigHttpApiClient), - Clythor(ClythorHttpApiClient), -} - -impl ApiClient { - pub async fn summary(&self) -> Result { - match self { - ApiClient::Xmrig(client) => client.summary().await, - ApiClient::Clythor(client) => client.summary().await, - } - } -} - pub(crate) struct CpuMiner { watcher_task: Option>>, miner_shutdown: Shutdown, - api_client: Option, + api_client: Option, is_mining: bool, } @@ -72,16 +57,6 @@ impl CpuMiner { self.miner_shutdown = Shutdown::new(); let mut inner_shutdown = self.miner_shutdown.to_signal(); - // let xmrig_node_connection = match cpu_miner_config.node_connection { - // CpuMinerConnection::BuiltInProxy => { - // XmrigNodeConnection::LocalMmproxy { - // host_name: "127.0.0.1".to_string(), - // // port: local_mm_proxy.try_get_listening_port().await? - // // TODO: Replace with actual port - // port: monero_port, - // } - // } - // }; let node_connection = match cpu_miner_config.node_connection { CpuMinerConnection::BuiltInProxy => LocalMmproxy { host_name: "http://127.0.0.1".to_string(), @@ -103,19 +78,10 @@ impl CpuMiner { MiningMode::Eco => (30 * max_cpu_available) / 100, MiningMode::Ludicrous => max_cpu_available, }; - // let xmrig_version = - // XmrigAdapter::ensure_latest(cache_dir.clone(), false, progress_tracker.clone()).await?; - // let xmrig = XmrigAdapter::new( - // xmrig_node_connection, - // monero_address.clone(), - // cache_dir, - // cpu_max_percentage, - // xmrig_version, - // ); let clythor = ClythorAdapter::new(node_connection, monero_address.clone(), mining_threads); let (mut xmrig_child, _xmrig_status_monitor) = clythor.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; - self.api_client = Some(ApiClient::Clythor(clythor.client)); + self.api_client = Some(clythor.client); self.watcher_task = Some(tauri::async_runtime::spawn(async move { let mut watch_timer = tokio::time::interval(tokio::time::Duration::from_secs(1)); @@ -123,47 +89,31 @@ impl CpuMiner { // read events such as stdout loop { select! { - _ = watch_timer.tick() => { - if !xmrig_child.ping() - { - warn!(target: LOG_TARGET, "xmrig is not running"); - match xmrig_child.stop().await { - Ok(_) => { - info!(target: LOG_TARGET, "xmrig exited successfully"); - } - Err(e) => { - error!(target: LOG_TARGET, "xmrig exited with error: {}", e); - return Err(e) - } - } - break; - } - }, - // event = rx.recv() => { - // if let Some(event) = event { - // - // // if let CommandEvent::Stdout(line) = event { - // // window - // // .emit("message", Some(format!("'{}'", line))) - // // .expect("failed to emit event"); - // // write to stdin - // //child.write("message from Rust\n".as_bytes()).unwrap(); - // - // } - // else { - // break; - // } - // }, - // - _ = inner_shutdown.wait() => { - xmrig_child.stop().await?; - break; - }, - _ = app_shutdown.wait() => { - xmrig_child.stop().await?; - break; + _ = watch_timer.tick() => { + if !xmrig_child.ping() + { + warn!(target: LOG_TARGET, "xmrig is not running"); + match xmrig_child.stop().await { + Ok(_) => { + info!(target: LOG_TARGET, "xmrig exited successfully"); + } + Err(e) => { + error!(target: LOG_TARGET, "xmrig exited with error: {}", e); + return Err(e) + } + } + break; } - } + }, + _ = inner_shutdown.wait() => { + xmrig_child.stop().await?; + break; + }, + _ = app_shutdown.wait() => { + xmrig_child.stop().await?; + break; + } + } } Ok(()) })); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 4a35a0bac..cb266f559 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,7 +4,6 @@ mod app_config; mod app_in_memory_config; mod binary_resolver; -mod clythor; mod clythor_adapter; mod consts; mod cpu_miner; From 80878db21298c0ae94ab716ba2623f7c7b66d8cf Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Thu, 12 Sep 2024 16:28:33 +0200 Subject: [PATCH 05/13] Separate mining for Clythor and Xmrig --- src-tauri/src/cpu_miner.rs | 126 +++++++++++++++++++++++--- src-tauri/src/main.rs | 51 +++++++---- src/hooks/mining/useMiningControls.ts | 2 +- src/types/invoke.ts | 3 +- src/types/mining.ts | 2 + 5 files changed, 152 insertions(+), 32 deletions(-) diff --git a/src-tauri/src/cpu_miner.rs b/src-tauri/src/cpu_miner.rs index cbf382496..ee19e97b2 100644 --- a/src-tauri/src/cpu_miner.rs +++ b/src-tauri/src/cpu_miner.rs @@ -1,13 +1,13 @@ use crate::app_config::MiningMode; use crate::clythor_adapter::{ClythorAdapter, LocalMmproxy}; use crate::process_adapter::ProcessAdapter; -use crate::xmrig::http_api::{models, XmrigHttpApiClient}; +use crate::xmrig::http_api::XmrigHttpApiClient; use crate::xmrig_adapter::{XmrigAdapter, XmrigNodeConnection}; use crate::{ - binary_resolver, CpuMinerConfig, CpuMinerConnection, CpuMinerConnectionStatus, CpuMinerStatus, - ProgressTracker, + CpuMinerConfig, CpuMinerConnection, CpuMinerConnectionStatus, CpuMinerStatus, ProgressTracker, }; use log::{debug, error, info, warn}; +use serde::{Deserialize, Serialize}; use std::path::PathBuf; use std::thread; use tari_core::transactions::tari_amount::MicroMinotari; @@ -19,6 +19,12 @@ use tokio::time::MissedTickBehavior; const RANDOMX_BLOCKS_PER_DAY: u64 = 360; const LOG_TARGET: &str = "tari::universe::cpu_miner"; +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] +pub enum RandomXMiner { + Xmrig, + Clythor, +} + pub(crate) struct CpuMiner { watcher_task: Option>>, miner_shutdown: Shutdown, @@ -37,7 +43,7 @@ impl CpuMiner { } #[allow(clippy::too_many_arguments)] - pub async fn start( + pub async fn start_xmrig( &mut self, mut app_shutdown: ShutdownSignal, cpu_miner_config: &CpuMinerConfig, @@ -57,11 +63,15 @@ impl CpuMiner { self.miner_shutdown = Shutdown::new(); let mut inner_shutdown = self.miner_shutdown.to_signal(); - let node_connection = match cpu_miner_config.node_connection { - CpuMinerConnection::BuiltInProxy => LocalMmproxy { - host_name: "http://127.0.0.1".to_string(), - port: monero_port, - }, + let xmrig_node_connection = match cpu_miner_config.node_connection { + CpuMinerConnection::BuiltInProxy => { + XmrigNodeConnection::LocalMmproxy { + host_name: "127.0.0.1".to_string(), + // port: local_mm_proxy.try_get_listening_port().await? + // TODO: Replace with actual port + port: monero_port, + } + } }; let max_cpu_available = thread::available_parallelism(); let max_cpu_available = match max_cpu_available { @@ -74,14 +84,22 @@ impl CpuMiner { 1 } }; - let mining_threads = match mode { + let cpu_max_percentage = match mode { MiningMode::Eco => (30 * max_cpu_available) / 100, MiningMode::Ludicrous => max_cpu_available, }; - let clythor = ClythorAdapter::new(node_connection, monero_address.clone(), mining_threads); + let xmrig_version = + XmrigAdapter::ensure_latest(cache_dir.clone(), false, progress_tracker.clone()).await?; + let xmrig = XmrigAdapter::new( + xmrig_node_connection, + monero_address.clone(), + cache_dir, + cpu_max_percentage, + xmrig_version, + ); let (mut xmrig_child, _xmrig_status_monitor) = - clythor.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; - self.api_client = Some(clythor.client); + xmrig.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; + self.api_client = Some(xmrig.client); self.watcher_task = Some(tauri::async_runtime::spawn(async move { let mut watch_timer = tokio::time::interval(tokio::time::Duration::from_secs(1)); @@ -134,6 +152,88 @@ impl CpuMiner { Ok(()) } + #[allow(clippy::too_many_arguments)] + pub async fn start_clythor( + &mut self, + mut app_shutdown: ShutdownSignal, + cpu_miner_config: &CpuMinerConfig, + monero_address: String, + monero_port: u16, + base_path: PathBuf, + config_path: PathBuf, + log_dir: PathBuf, + mode: MiningMode, + ) -> Result<(), anyhow::Error> { + if self.watcher_task.is_some() { + warn!(target: LOG_TARGET, "Tried to start mining twice"); + return Ok(()); + } + self.miner_shutdown = Shutdown::new(); + let mut inner_shutdown = self.miner_shutdown.to_signal(); + + let node_connection = match cpu_miner_config.node_connection { + CpuMinerConnection::BuiltInProxy => LocalMmproxy { + host_name: "http://127.0.0.1".to_string(), + port: monero_port, + }, + }; + let max_cpu_available = thread::available_parallelism(); + let max_cpu_available = match max_cpu_available { + Ok(available_cpus) => { + debug!(target:LOG_TARGET, "Available CPUs: {}", available_cpus); + available_cpus.get() + } + Err(err) => { + error!("Available CPUs: Unknown, error: {}", err); + 1 + } + }; + let mining_threads = match mode { + MiningMode::Eco => (30 * max_cpu_available) / 100, + MiningMode::Ludicrous => max_cpu_available, + }; + let clythor = ClythorAdapter::new(node_connection, monero_address.clone(), mining_threads); + let (mut clythor_child, _clythor_status_monitor) = + clythor.spawn_inner(base_path.clone(), config_path.clone(), log_dir.clone())?; + self.api_client = Some(clythor.client); + + self.watcher_task = Some(tauri::async_runtime::spawn(async move { + let mut watch_timer = tokio::time::interval(tokio::time::Duration::from_secs(1)); + watch_timer.set_missed_tick_behavior(MissedTickBehavior::Skip); + // read events such as stdout + loop { + select! { + _ = watch_timer.tick() => { + if !clythor_child.ping() + { + warn!(target: LOG_TARGET, "clythor is not running"); + match clythor_child.stop().await { + Ok(_) => { + info!(target: LOG_TARGET, "clythor exited successfully"); + } + Err(e) => { + error!(target: LOG_TARGET, "clythor exited with error: {}", e); + return Err(e) + } + } + break; + } + }, + _ = inner_shutdown.wait() => { + clythor_child.stop().await?; + break; + }, + _ = app_shutdown.wait() => { + clythor_child.stop().await?; + break; + } + } + } + Ok(()) + })); + Ok(()) + } + pub async fn status( &mut self, network_hash_rate: u64, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index cb266f559..c32952d95 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -46,6 +46,7 @@ use crate::xmrig_adapter::XmrigAdapter; use app_config::{AppConfig, MiningMode}; use app_in_memory_config::{AirdropInMemoryConfig, AppInMemoryConfig}; use binary_resolver::{Binaries, BinaryResolver}; +use cpu_miner::RandomXMiner; use gpu_miner_adapter::{GpuMinerStatus, GpuNodeSource}; use hardware_monitor::{HardwareMonitor, HardwareStatus}; use log::{debug, error, info, warn}; @@ -531,6 +532,7 @@ async fn start_mining<'r>( window: tauri::Window, state: tauri::State<'_, UniverseAppState>, app: tauri::AppHandle, + miner: RandomXMiner, ) -> Result<(), String> { let config = state.config.read().await; let cpu_mining_enabled = config.cpu_mining_enabled; @@ -547,23 +549,38 @@ async fn start_mining<'r>( .await .map_err(|e| e.to_string())?; - let res = state - .cpu_miner - .write() - .await - .start( - state.shutdown.to_signal(), - &cpu_miner_config, - monero_address, - mm_proxy_port, - app.path_resolver().app_local_data_dir().unwrap(), - app.path_resolver().app_cache_dir().unwrap(), - app.path_resolver().app_config_dir().unwrap(), - app.path_resolver().app_log_dir().unwrap(), - progress_tracker, - mode, - ) - .await; + let mut res = state.cpu_miner.write().await; + + let res = match miner { + cpu_miner::RandomXMiner::Clythor => { + res.start_clythor( + state.shutdown.to_signal(), + &cpu_miner_config, + monero_address, + mm_proxy_port, + app.path_resolver().app_local_data_dir().unwrap(), + app.path_resolver().app_config_dir().unwrap(), + app.path_resolver().app_log_dir().unwrap(), + mode, + ) + .await + } + cpu_miner::RandomXMiner::Xmrig => { + res.start_xmrig( + state.shutdown.to_signal(), + &cpu_miner_config, + monero_address, + mm_proxy_port, + app.path_resolver().app_local_data_dir().unwrap(), + app.path_resolver().app_cache_dir().unwrap(), + app.path_resolver().app_config_dir().unwrap(), + app.path_resolver().app_log_dir().unwrap(), + progress_tracker, + mode, + ) + .await + } + }; if let Err(e) = res { error!(target: LOG_TARGET, "Could not start mining: {:?}", e); diff --git a/src/hooks/mining/useMiningControls.ts b/src/hooks/mining/useMiningControls.ts index c572a5dc3..1ee14773e 100644 --- a/src/hooks/mining/useMiningControls.ts +++ b/src/hooks/mining/useMiningControls.ts @@ -8,7 +8,7 @@ export function useMiningControls() { const handleStart = useCallback(async () => { console.info('Mining starting....'); try { - await invoke('start_mining', {}) + await invoke('start_mining', { miner: 'Clythor' }) .then(async () => { console.info('Mining started.'); }) diff --git a/src/types/invoke.ts b/src/types/invoke.ts index 07667a4f8..25cdcaeee 100644 --- a/src/types/invoke.ts +++ b/src/types/invoke.ts @@ -1,11 +1,12 @@ import { modeType } from '@app/store/types'; import { ApplicationsVersions, AppStatus } from './app-status'; +import { CpuMiner } from './mining'; declare module '@tauri-apps/api/tauri' { function invoke(param: 'setup_application'): Promise; function invoke(param: 'open_log_dir'): Promise; function invoke(param: 'status'): Promise; - function invoke(param: 'start_mining'): Promise; + function invoke(param: 'start_mining', payload: { miner: CpuMiner }): Promise; function invoke(param: 'stop_mining'): Promise; function invoke(param: 'set_telemetry_mode', payload: { telemetryMode: boolean }): Promise; function invoke(param: 'get_telemetry_mode'): Promise; diff --git a/src/types/mining.ts b/src/types/mining.ts index db5e18097..2fc81c633 100644 --- a/src/types/mining.ts +++ b/src/types/mining.ts @@ -6,3 +6,5 @@ export interface BlockTimeData { minutes?: string; seconds?: string; } + +export type CpuMiner = 'Clythor' | 'Xmrig'; From cbe5ae3d8dc35896c64e675ca8fb7025a34ebec8 Mon Sep 17 00:00:00 2001 From: brianp Date: Thu, 12 Sep 2024 17:36:55 +0200 Subject: [PATCH 06/13] Make clythor use a data dir --- src-tauri/src/clythor_adapter.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src-tauri/src/clythor_adapter.rs b/src-tauri/src/clythor_adapter.rs index 35f5ceea1..ee8c68ae3 100644 --- a/src-tauri/src/clythor_adapter.rs +++ b/src-tauri/src/clythor_adapter.rs @@ -64,7 +64,10 @@ impl ProcessAdapter for ClythorAdapter { let mut shutdown_signal = clythor_shutdown.to_signal(); let clythor_log_file = log_dir.join("clythor.log"); std::fs::create_dir_all(clythor_log_file.parent().unwrap())?; + let clythor_data_dir = data_dir.join("clythor"); + std::fs::create_dir_all(&clythor_data_dir)?; let args = vec![ + format!("-b {}", clythor_data_dir.to_str().unwrap()), format!( "--log-path={}", &clythor_log_file.parent().unwrap().to_str().unwrap() From 717904532cd9e498b20914f64b1d1ab0e069751d Mon Sep 17 00:00:00 2001 From: Maciej Kozuszek Date: Fri, 13 Sep 2024 11:32:15 +0200 Subject: [PATCH 07/13] Add randomX cpu miner option to the frontend --- src/components/elements/inputs/Select.tsx | 2 +- .../SideBar/components/Settings/Settings.tsx | 27 ++++++++++++++++++- src/hooks/mining/useMiningControls.ts | 6 +++-- src/store/useMiningStore.ts | 6 ++++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/components/elements/inputs/Select.tsx b/src/components/elements/inputs/Select.tsx index 5f526d15b..5a7f3ee66 100644 --- a/src/components/elements/inputs/Select.tsx +++ b/src/components/elements/inputs/Select.tsx @@ -15,7 +15,7 @@ import { import { useClick, useDismiss, useFloating, useInteractions, useRole } from '@floating-ui/react'; import { LayoutGroup } from 'framer-motion'; -interface Option { +export interface Option { label: string; selectedLabel?: string; iconSrc?: string; diff --git a/src/containers/SideBar/components/Settings/Settings.tsx b/src/containers/SideBar/components/Settings/Settings.tsx index e05f91ae3..211c396aa 100644 --- a/src/containers/SideBar/components/Settings/Settings.tsx +++ b/src/containers/SideBar/components/Settings/Settings.tsx @@ -44,6 +44,8 @@ import { useMiningStore } from '@app/store/useMiningStore.ts'; import { useGPUStatusStore } from '@app/store/useGPUStatusStore.ts'; import { SeedWords } from './SeedWords'; import { CardComponent } from '@app/containers/SideBar/components/Settings/Card.component.tsx'; +import { Option, Select } from '@app/components/elements/inputs/Select'; +import { CpuMiner } from '@app/types/mining'; enum FormFields { MONERO_ADDRESS = 'moneroAddress', @@ -53,6 +55,17 @@ interface FormState { [FormFields.MONERO_ADDRESS]: string; } +const CpuMinerOptions: Option[] = [ + { + label: 'Clythor', + value: 'Clythor', + }, + { + label: 'Xmrig', + value: 'Xmrig', + }, +]; + export default function Settings() { const { t } = useTranslation(['common', 'settings'], { useSuspense: false }); @@ -107,10 +120,20 @@ export default function Settings() { const isCPUMining = useCPUStatusStore(useShallow((s) => s.is_mining)); const isGPUMining = useGPUStatusStore(useShallow((s) => s.is_mining)); const isMiningInProgress = isCPUMining || isGPUMining; - const miningInitiated = useMiningStore(useShallow((s) => s.miningInitiated)); + const { miningInitiated, cpuMiner, setCpuMiner } = useMiningStore( + useShallow((s) => ({ + miningInitiated: s.miningInitiated, + cpuMiner: s.cpuMiner, + setCpuMiner: s.setCpuMiner, + })) + ); const miningLoading = (miningInitiated && !isMiningInProgress) || (!miningInitiated && isMiningInProgress); const [open, setOpen] = useState(false); + const handleMinerChange = (miner: string) => { + setCpuMiner(miner as CpuMiner); + }; + const handleClose = () => { setShowSeedWords(false); }; @@ -392,6 +415,8 @@ export default function Settings() { {gpuEnabledMarkup} + setCpuMiner(miner as CpuMiner)} selectedValue={cpuMiner} />; + const isMiningControlsEnabled = useMiningStore(useShallow((s) => s.miningControlsEnabled)); + const isChangingMode = useMiningStore((s) => s.isChangingMode); + + const { isMiningLoading } = useMiningControls(); + + return ( + + {t('randomX-miner')} +