diff --git a/README.md b/README.md index d5d562b..bba4b3b 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ Gupax (*guh-picks*) is a (Windows|macOS|Linux) GUI for mining [**Monero**](https - [Advanced](#Advanced) - [Verifying](#Verifying) - [Command Line](#Command-Line) - - [Tor/Arti](#Tor-Arti) + - [Tor/Arti](#TorArti) - [Logs](#Logs) - [Disk](#Disk) - - [Swapping P2Pool/XMRig](#Swapping-P2Pool-XMRig) + - [Swapping P2Pool/XMRig](#Swapping-P2PoolXMRig) - [Gupax](#Gupax) - [P2Pool](#P2Pool) - [XMRig](#XMRig) @@ -109,6 +109,10 @@ With Monero GUI managing the Monero node on one side and Gupax managing P2Pool/X --- +### Swapping P2Pool/XMRig + +--- + ### Gupax --- diff --git a/src/constants.rs b/src/constants.rs index 11acba7..f7ea51b 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -118,6 +118,14 @@ pub const STATUS_GUPAX_MEMORY_USAGE: &str = "How much memory Gupax is currently pub const STATUS_GUPAX_SYSTEM_CPU_USAGE: &str = "How much CPU your entire system is currently using. This accounts for all your threads (it is out of 100%)"; pub const STATUS_GUPAX_SYSTEM_MEMORY: &str = "How much memory your entire system has (including swap) and is currently using in Gigabytes"; pub const STATUS_GUPAX_SYSTEM_CPU_MODEL: &str = "The detected model of your system's CPU and its current frequency"; +//-- +pub const STATUS_P2POOL_UPTIME: &str = "How long P2Pool has been online"; +pub const STATUS_P2POOL_PAYOUTS: &str = "The total amount of payouts received and an extrapolated estimate of how many you will receive. Warning: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time!"; +pub const STATUS_P2POOL_XMR: &str = "The total amount of XMR mined via P2Pool and an extrapolated estimate of how many you will mine in the future. Warning: these stats will be quite inaccurate if your P2Pool hasn't been running for a long time!"; +pub const STATUS_P2POOL_HASHRATE: &str = "The total amount of hashrate your P2Pool has pointed at it in 15 minute, 1 hour, and 24 hour averages"; +pub const STATUS_P2POOL_SHARES: &str = "The total amount of shares found on P2Pool"; +pub const STATUS_P2POOL_EFFORT: &str = "The average amount of effort needed to find a share, and the current effort"; +pub const STATUS_P2POOL_CONNECTIONS: &str = "The total amount of miner connections on this P2Pool"; // Gupax pub const GUPAX_UPDATE: &str = "Check for updates on Gupax, P2Pool, and XMRig via GitHub's API and upgrade automatically"; diff --git a/src/helper.rs b/src/helper.rs index 8ca64e3..d273067 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -453,6 +453,20 @@ impl Helper { path.pop(); path.push(P2POOL_API_PATH); + // Attempt to remove stale API file + match std::fs::remove_file(&path) { + Ok(_) => info!("P2Pool | Attempting to remove stale API file ... OK"), + Err(e) => warn!("P2Pool | Attempting to remove stale API file ... FAIL ... {}", e), + } + // Attempt to create a default empty one. + use std::io::Write; + if let Ok(_) = std::fs::File::create(&path) { + let text = r#"{"hashrate_15m":0,"hashrate_1h":0,"hashrate_24h":0,"shares_found":0,"average_effort":0.0,"current_effort":0.0,"connections":0}"#; + match std::fs::write(&path, text) { + Ok(_) => info!("P2Pool | Creating default empty API file ... OK"), + Err(e) => warn!("P2Pool | Creating default empty API file ... FAIL ... {}", e), + } + } let regex = P2poolRegex::new(); let start = process.lock().unwrap().start; @@ -528,7 +542,7 @@ impl Helper { // Deserialize if let Ok(s) = PrivP2poolApi::str_to_priv_p2pool_api(&string) { // Update the structs. - PubP2poolApi::update_from_priv(&pub_api, &priv_api); + PubP2poolApi::update_from_priv(&pub_api, s); } } @@ -1319,9 +1333,8 @@ impl PubP2poolApi { } // Mutate [PubP2poolApi] with data from a [PrivP2poolApi] and the process output. - fn update_from_priv(public: &Arc>, private: &Arc>) { + fn update_from_priv(public: &Arc>, private: PrivP2poolApi) { // priv -> pub conversion - let private = private.lock().unwrap(); let mut public = public.lock().unwrap(); *public = Self { hashrate_15m: HumanNumber::from_u128(private.hashrate_15m), @@ -1331,8 +1344,8 @@ impl PubP2poolApi { average_effort: HumanNumber::to_percent(private.average_effort), current_effort: HumanNumber::to_percent(private.current_effort), connections: HumanNumber::from_u16(private.connections), - ..public.clone() - } + ..std::mem::take(&mut *public) + }; } // Essentially greps the output for [x.xxxxxxxxxxxx XMR] where x = a number. diff --git a/src/main.rs b/src/main.rs index 8965da9..4a934e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1041,7 +1041,7 @@ impl eframe::App for App { let color = if hide { BLACK } else { BRIGHT_YELLOW }; if ui.add_sized([box_width, height], Button::new(RichText::new("👁").color(color))).on_hover_text(PASSWORD_HIDE).clicked() { sudo.hide = !sudo.hide; } }); - if esc || ui.add_sized([width, height*4.0], Button::new("Leave")).clicked() { self.error_state.reset(); }; + if (esc && !sudo.testing) || ui.add_sized([width, height*4.0], Button::new("Leave")).clicked() { self.error_state.reset(); }; // If [test_sudo()] finished, reset error state. if sudo.success { self.error_state.reset(); @@ -1336,7 +1336,7 @@ impl eframe::App for App { }); } Tab::Status => { - Status::show(&self.pub_sys, &self.p2pool_api, &self.xmrig_api, &self.p2pool_img, &self.xmrig_img, self.width, self.height, ctx, ui); + Status::show(&self.pub_sys, &self.p2pool_api, &self.xmrig_api, &self.p2pool_img, &self.xmrig_img, self.p2pool.lock().unwrap().is_alive(), self.xmrig.lock().unwrap().is_alive(), self.width, self.height, ctx, ui); } Tab::Gupax => { Gupax::show(&mut self.state.gupax, &self.og, &self.state_path, &self.update, &self.file_window, &mut self.error_state, &self.restart, self.width, self.height, frame, ctx, ui); diff --git a/src/status.rs b/src/status.rs index 8101212..babcdfe 100644 --- a/src/status.rs +++ b/src/status.rs @@ -35,41 +35,60 @@ use egui::{ pub struct Status {} impl Status { -pub fn show(sys: &Arc>, p2pool_api: &Arc>, xmrig_api: &Arc>, p2pool_img: &Arc>, xmrig_img: &Arc>, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) { +pub fn show(sys: &Arc>, p2pool_api: &Arc>, xmrig_api: &Arc>, p2pool_img: &Arc>, xmrig_img: &Arc>, p2pool_online: bool, xmrig_online: bool, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) { let width = (width/3.0)-(SPACE*1.666); let min_height = height/1.14; - let height = height/20.0; + let height = height/25.0; ui.horizontal(|ui| { // [Gupax] ui.group(|ui| { ui.vertical(|ui| { ui.set_min_height(min_height); - ui.add_sized([width, height*2.0], Label::new(RichText::new("[Gupax]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))); + ui.add_sized([width, height*2.0], Label::new(RichText::new("[Gupax]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))).on_hover_text("Gupax is online"); // Uptime + let sys = sys.lock().unwrap(); ui.add_sized([width, height], Label::new(RichText::new("Uptime").underline().color(BONE))).on_hover_text(STATUS_GUPAX_UPTIME); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().gupax_uptime))); + ui.add_sized([width, height], Label::new(format!("{}", sys.gupax_uptime))); ui.add_sized([width, height], Label::new(RichText::new("Gupax CPU").underline().color(BONE))).on_hover_text(STATUS_GUPAX_CPU_USAGE); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().gupax_cpu_usage))); + ui.add_sized([width, height], Label::new(format!("{}", sys.gupax_cpu_usage))); ui.add_sized([width, height], Label::new(RichText::new("Gupax Memory").underline().color(BONE))).on_hover_text(STATUS_GUPAX_MEMORY_USAGE); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().gupax_memory_used_mb))); + ui.add_sized([width, height], Label::new(format!("{}", sys.gupax_memory_used_mb))); ui.add_sized([width, height], Label::new(RichText::new("System CPU").underline().color(BONE))).on_hover_text(STATUS_GUPAX_SYSTEM_CPU_USAGE); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().system_cpu_usage))); + ui.add_sized([width, height], Label::new(format!("{}", sys.system_cpu_usage))); ui.add_sized([width, height], Label::new(RichText::new("System Memory").underline().color(BONE))).on_hover_text(STATUS_GUPAX_SYSTEM_MEMORY); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().system_memory))); + ui.add_sized([width, height], Label::new(format!("{}", sys.system_memory))); ui.add_sized([width, height], Label::new(RichText::new("System CPU Model").underline().color(BONE))).on_hover_text(STATUS_GUPAX_SYSTEM_CPU_MODEL); - ui.add_sized([width, height], Label::new(format!("{}", sys.lock().unwrap().system_cpu_model))); + ui.add_sized([width, height], Label::new(format!("{}", sys.system_cpu_model))); + drop(sys); })}); // [P2Pool] ui.group(|ui| { ui.vertical(|ui| { + ui.set_enabled(p2pool_online); ui.set_min_height(min_height); - ui.add_sized([width, height*2.0], Label::new(RichText::new("[P2Pool]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))); + ui.add_sized([width, height*2.0], Label::new(RichText::new("[P2Pool]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))).on_hover_text("P2Pool is online").on_disabled_hover_text("P2Pool is offline"); // Uptime - ui.add_sized([width, height], Label::new(RichText::new("Uptime").underline())); - ui.add_sized([width, height], Label::new(format!("{}", p2pool_api.lock().unwrap().uptime))); + let api = p2pool_api.lock().unwrap(); + ui.add_sized([width, height], Label::new(RichText::new("Uptime").underline().color(BONE))).on_hover_text(STATUS_P2POOL_UPTIME); + ui.add_sized([width, height], Label::new(format!("{}", api.uptime))); + ui.add_sized([width, height], Label::new(RichText::new("Shares Found").underline().color(BONE))).on_hover_text(STATUS_P2POOL_SHARES); + ui.add_sized([width, height], Label::new(format!("{}", api.shares_found))); + ui.add_sized([width, height], Label::new(RichText::new("Payouts").underline().color(BONE))).on_hover_text(STATUS_P2POOL_PAYOUTS); + ui.add_sized([width, height], Label::new(format!("Total: {}", api.payouts))); + ui.add_sized([width, height], Label::new(format!("[{}/hour] [{}/day] [{}/month]", api.payouts_hour, api.payouts_day, api.payouts_month))); + ui.add_sized([width, height], Label::new(RichText::new("XMR Mined").underline().color(BONE))).on_hover_text(STATUS_P2POOL_XMR); + ui.add_sized([width, height], Label::new(format!("Total: {} XMR", api.xmr))); + ui.add_sized([width, height], Label::new(format!("[{}/hour] [{}/day] [{}/month]", api.xmr_hour, api.xmr_day, api.xmr_month))); + ui.add_sized([width, height], Label::new(RichText::new("P2Pool Hashrate [15m/1h/24h]").underline().color(BONE))).on_hover_text(STATUS_P2POOL_HASHRATE); + ui.add_sized([width, height], Label::new(format!("[{} H/s] [{} H/s] [{} H/s]", api.hashrate_15m, api.hashrate_1h, api.hashrate_24h))); + ui.add_sized([width, height], Label::new(RichText::new("Miners Connected").underline().color(BONE))).on_hover_text(STATUS_P2POOL_CONNECTIONS); + ui.add_sized([width, height], Label::new(format!("{}", api.connections))); + ui.add_sized([width, height], Label::new(RichText::new("Effort").underline().color(BONE))).on_hover_text(STATUS_P2POOL_EFFORT); + ui.add_sized([width, height], Label::new(format!("[Average: {}] [Current: {}]", api.average_effort, api.current_effort))); })}); // [XMRig] ui.group(|ui| { ui.vertical(|ui| { + ui.set_enabled(xmrig_online); ui.set_min_height(min_height); - ui.add_sized([width, height*2.0], Label::new(RichText::new("[XMRig]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))); + ui.add_sized([width, height*2.0], Label::new(RichText::new("[XMRig]").color(LIGHT_GRAY).text_style(TextStyle::Name("MonospaceLarge".into())))).on_hover_text("XMRig is online").on_disabled_hover_text("XMRig is offline"); // Uptime ui.add_sized([width, height], Label::new(RichText::new("Uptime").underline())); ui.add_sized([width, height], Label::new(format!("{}", xmrig_api.lock().unwrap().uptime)));