mirror of
https://github.com/hinto-janai/gupax.git
synced 2024-12-23 03:19:21 +00:00
litter codebase with [debug!()]
The entire codebase is now littered with [debug!()] messages. Thankfully [log] has 0 cost if you aren't using them, so regular users won't have a runtime penalty unless they specify RUST_LOG=debug.
This commit is contained in:
parent
bf4e39c3a5
commit
798966d447
8 changed files with 203 additions and 62 deletions
|
@ -1,6 +1,6 @@
|
||||||
# WORK IN PROGRESS - ETA: December 25th, 2022
|
# WORK IN PROGRESS - ETA: December 25th, 2022
|
||||||
![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/banner.png)
|
![banner.png](https://github.com/hinto-janaiyo/gupax/blob/main/images/banner.png)
|
||||||
Gupax (*guh-picks*) is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig).
|
Gupax is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/monero-project/monero) on [**P2Pool**](https://github.com/SChernykh/p2pool), using [**XMRig**](https://github.com/xmrig/xmrig).
|
||||||
|
|
||||||
**If you just want to see a short 1-minute video on how to download and run Gupax: [click here.](#Video)**
|
**If you just want to see a short 1-minute video on how to download and run Gupax: [click here.](#Video)**
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ pub enum Ratio {
|
||||||
impl Gupax {
|
impl Gupax {
|
||||||
pub fn show(&mut self, og: &Arc<Mutex<State>>, state_path: &Path, update: &Arc<Mutex<Update>>, file_window: &Arc<Mutex<FileWindow>>, error_state: &mut ErrorState, restart: &Arc<Mutex<Restart>>, width: f32, height: f32, frame: &mut eframe::Frame, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, og: &Arc<Mutex<State>>, state_path: &Path, update: &Arc<Mutex<Update>>, file_window: &Arc<Mutex<FileWindow>>, error_state: &mut ErrorState, restart: &Arc<Mutex<Restart>>, width: f32, height: f32, frame: &mut eframe::Frame, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
// Update button + Progress bar
|
// Update button + Progress bar
|
||||||
|
debug!("Gupax Tab | Rendering [Update] button + progress bar");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
// These are in unnecessary [ui.vertical()]'s
|
// These are in unnecessary [ui.vertical()]'s
|
||||||
// because I need to use [ui.set_enabled]s, but I can't
|
// because I need to use [ui.set_enabled]s, but I can't
|
||||||
|
@ -112,6 +113,7 @@ impl Gupax {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
debug!("Gupax Tab | Rendering bool buttons");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = (width - SPACE*12.0)/6.0;
|
let width = (width - SPACE*12.0)/6.0;
|
||||||
|
@ -133,6 +135,7 @@ impl Gupax {
|
||||||
|
|
||||||
if self.simple { return }
|
if self.simple { return }
|
||||||
|
|
||||||
|
debug!("Gupax Tab | Rendering P2Pool/XMRig path selection");
|
||||||
// P2Pool/XMRig binary path selection
|
// P2Pool/XMRig binary path selection
|
||||||
ui.add_space(SPACE);
|
ui.add_space(SPACE);
|
||||||
ui.style_mut().override_text_style = Some(Monospace);
|
ui.style_mut().override_text_style = Some(Monospace);
|
||||||
|
@ -182,6 +185,7 @@ impl Gupax {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
// Gupax App resolution sliders
|
// Gupax App resolution sliders
|
||||||
|
debug!("Gupax Tab | Rendering resolution sliders");
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
let width = width/10.0;
|
let width = width/10.0;
|
||||||
ui.spacing_mut().icon_width = width / 25.0;
|
ui.spacing_mut().icon_width = width / 25.0;
|
||||||
|
@ -229,6 +233,7 @@ impl Gupax {
|
||||||
}
|
}
|
||||||
})});
|
})});
|
||||||
// Saved [Tab]
|
// Saved [Tab]
|
||||||
|
debug!("Gupax Tab | Rendering [Tab] selector");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let height = ui.available_height()/1.85;
|
let height = ui.available_height()/1.85;
|
||||||
let width = (width/5.0)-(SPACE*1.93);
|
let width = (width/5.0)-(SPACE*1.93);
|
||||||
|
|
160
src/helper.rs
160
src/helper.rs
|
@ -251,6 +251,7 @@ impl Helper {
|
||||||
// The actual [String] holds 56_000_000, but this allows for some leeway so it doesn't allocate more memory.
|
// The actual [String] holds 56_000_000, but this allows for some leeway so it doesn't allocate more memory.
|
||||||
// This will also append a message showing it was reset.
|
// This will also append a message showing it was reset.
|
||||||
fn check_reset_output_full(output_full: &Arc<Mutex<String>>, name: ProcessName) {
|
fn check_reset_output_full(output_full: &Arc<Mutex<String>>, name: ProcessName) {
|
||||||
|
debug!("{} Watchdog | Resetting [output_full]...", name);
|
||||||
let mut output_full = output_full.lock().unwrap();
|
let mut output_full = output_full.lock().unwrap();
|
||||||
if output_full.len() > PROCESS_OUTPUT_LEEWAY {
|
if output_full.len() > PROCESS_OUTPUT_LEEWAY {
|
||||||
info!("{} | Output is nearing {} bytes, resetting!", MAX_PROCESS_OUTPUT_BYTES, name);
|
info!("{} | Output is nearing {} bytes, resetting!", MAX_PROCESS_OUTPUT_BYTES, name);
|
||||||
|
@ -258,10 +259,12 @@ impl Helper {
|
||||||
output_full.clear();
|
output_full.clear();
|
||||||
output_full.push_str(&text);
|
output_full.push_str(&text);
|
||||||
}
|
}
|
||||||
|
debug!("{} Watchdog | Resetting [output_full] ... OK", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the GUI thread
|
// For the GUI thread
|
||||||
fn check_reset_gui_p2pool_output(gui_api: &Arc<Mutex<PubP2poolApi>>) {
|
fn check_reset_gui_p2pool_output(gui_api: &Arc<Mutex<PubP2poolApi>>) {
|
||||||
|
debug!("P2Pool Watchdog | Resetting GUI output...");
|
||||||
let mut gui_api = gui_api.lock().unwrap();
|
let mut gui_api = gui_api.lock().unwrap();
|
||||||
if gui_api.output.len() > GUI_OUTPUT_LEEWAY {
|
if gui_api.output.len() > GUI_OUTPUT_LEEWAY {
|
||||||
info!("P2Pool | Output is nearing {} bytes, resetting!", MAX_GUI_OUTPUT_BYTES);
|
info!("P2Pool | Output is nearing {} bytes, resetting!", MAX_GUI_OUTPUT_BYTES);
|
||||||
|
@ -269,9 +272,11 @@ impl Helper {
|
||||||
gui_api.output.clear();
|
gui_api.output.clear();
|
||||||
gui_api.output.push_str(&text);
|
gui_api.output.push_str(&text);
|
||||||
}
|
}
|
||||||
|
debug!("P2Pool Watchdog | Resetting GUI output ... OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_reset_gui_xmrig_output(gui_api: &Arc<Mutex<PubXmrigApi>>) {
|
fn check_reset_gui_xmrig_output(gui_api: &Arc<Mutex<PubXmrigApi>>) {
|
||||||
|
debug!("XMRig Watchdog | Resetting GUI output...");
|
||||||
let mut gui_api = gui_api.lock().unwrap();
|
let mut gui_api = gui_api.lock().unwrap();
|
||||||
if gui_api.output.len() > GUI_OUTPUT_LEEWAY {
|
if gui_api.output.len() > GUI_OUTPUT_LEEWAY {
|
||||||
info!("XMRig | Output is nearing {} bytes, resetting!", MAX_GUI_OUTPUT_BYTES);
|
info!("XMRig | Output is nearing {} bytes, resetting!", MAX_GUI_OUTPUT_BYTES);
|
||||||
|
@ -279,6 +284,7 @@ impl Helper {
|
||||||
gui_api.output.clear();
|
gui_api.output.clear();
|
||||||
gui_api.output.push_str(&text);
|
gui_api.output.push_str(&text);
|
||||||
}
|
}
|
||||||
|
debug!("XMRig Watchdog | Resetting GUI output ... OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- P2Pool specific
|
//---------------------------------------------------------------------------------------------------- P2Pool specific
|
||||||
|
@ -306,6 +312,7 @@ impl Helper {
|
||||||
thread::sleep(SECOND);
|
thread::sleep(SECOND);
|
||||||
}
|
}
|
||||||
// Ok, process is not alive, start the new one!
|
// Ok, process is not alive, start the new one!
|
||||||
|
info!("P2Pool | Old process seems dead, starting new one!");
|
||||||
Self::start_p2pool(&helper, &state, &path);
|
Self::start_p2pool(&helper, &state, &path);
|
||||||
});
|
});
|
||||||
info!("P2Pool | Restart ... OK");
|
info!("P2Pool | Restart ... OK");
|
||||||
|
@ -418,6 +425,7 @@ impl Helper {
|
||||||
// The P2Pool watchdog. Spawns 1 OS thread for reading a PTY (STDOUT+STDERR), and combines the [Child] with a PTY so STDIN actually works.
|
// The P2Pool watchdog. Spawns 1 OS thread for reading a PTY (STDOUT+STDERR), and combines the [Child] with a PTY so STDIN actually works.
|
||||||
fn spawn_p2pool_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubP2poolApi>>, pub_api: Arc<Mutex<PubP2poolApi>>, priv_api: Arc<Mutex<PrivP2poolApi>>, args: Vec<String>, mut path: std::path::PathBuf) {
|
fn spawn_p2pool_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubP2poolApi>>, pub_api: Arc<Mutex<PubP2poolApi>>, priv_api: Arc<Mutex<PrivP2poolApi>>, args: Vec<String>, mut path: std::path::PathBuf) {
|
||||||
// 1a. Create PTY
|
// 1a. Create PTY
|
||||||
|
debug!("P2Pool | Creating PTY...");
|
||||||
let pty = portable_pty::native_pty_system();
|
let pty = portable_pty::native_pty_system();
|
||||||
let pair = pty.openpty(portable_pty::PtySize {
|
let pair = pty.openpty(portable_pty::PtySize {
|
||||||
rows: 100,
|
rows: 100,
|
||||||
|
@ -426,13 +434,16 @@ impl Helper {
|
||||||
pixel_height: 0,
|
pixel_height: 0,
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
// 1b. Create command
|
// 1b. Create command
|
||||||
|
debug!("P2Pool | Creating command...");
|
||||||
let mut cmd = portable_pty::CommandBuilder::new(path.as_path());
|
let mut cmd = portable_pty::CommandBuilder::new(path.as_path());
|
||||||
cmd.args(args);
|
cmd.args(args);
|
||||||
cmd.cwd(path.as_path().parent().unwrap());
|
cmd.cwd(path.as_path().parent().unwrap());
|
||||||
// 1c. Create child
|
// 1c. Create child
|
||||||
|
debug!("P2Pool | Creating child...");
|
||||||
let child_pty = Arc::new(Mutex::new(pair.slave.spawn_command(cmd).unwrap()));
|
let child_pty = Arc::new(Mutex::new(pair.slave.spawn_command(cmd).unwrap()));
|
||||||
|
|
||||||
// 2. Set process state
|
// 2. Set process state
|
||||||
|
debug!("P2Pool | Setting process state...");
|
||||||
let mut lock = process.lock().unwrap();
|
let mut lock = process.lock().unwrap();
|
||||||
lock.state = ProcessState::Alive;
|
lock.state = ProcessState::Alive;
|
||||||
lock.signal = ProcessSignal::None;
|
lock.signal = ProcessSignal::None;
|
||||||
|
@ -443,6 +454,7 @@ impl Helper {
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
||||||
// 3. Spawn PTY read thread
|
// 3. Spawn PTY read thread
|
||||||
|
debug!("P2Pool | Spawning PTY read thread...");
|
||||||
let output_full = Arc::clone(&process.lock().unwrap().output_full);
|
let output_full = Arc::clone(&process.lock().unwrap().output_full);
|
||||||
let output_buf = Arc::clone(&process.lock().unwrap().output_buf);
|
let output_buf = Arc::clone(&process.lock().unwrap().output_buf);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
@ -453,6 +465,8 @@ impl Helper {
|
||||||
|
|
||||||
path.pop();
|
path.pop();
|
||||||
path.push(P2POOL_API_PATH);
|
path.push(P2POOL_API_PATH);
|
||||||
|
|
||||||
|
debug!("P2Pool | Cleaning old API files...");
|
||||||
// Attempt to remove stale API file
|
// Attempt to remove stale API file
|
||||||
match std::fs::remove_file(&path) {
|
match std::fs::remove_file(&path) {
|
||||||
Ok(_) => info!("P2Pool | Attempting to remove stale API file ... OK"),
|
Ok(_) => info!("P2Pool | Attempting to remove stale API file ... OK"),
|
||||||
|
@ -475,9 +489,27 @@ impl Helper {
|
||||||
loop {
|
loop {
|
||||||
// Set timer
|
// Set timer
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
debug!("P2Pool Watchdog | ----------- Start of loop -----------");
|
||||||
|
|
||||||
|
// Check if the process is secretly died without us knowing :)
|
||||||
|
if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
|
||||||
|
debug!("P2Pool Watchdog | Process secretly died! Getting exit status");
|
||||||
|
let exit_status = match code.success() {
|
||||||
|
true => { process.lock().unwrap().state = ProcessState::Dead; "Successful" },
|
||||||
|
false => { process.lock().unwrap().state = ProcessState::Failed; "Failed" },
|
||||||
|
};
|
||||||
|
let uptime = HumanTime::into_human(start.elapsed());
|
||||||
|
info!("P2Pool Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
||||||
|
// This is written directly into the GUI, because sometimes the 900ms event loop can't catch it.
|
||||||
|
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
||||||
|
process.lock().unwrap().signal = ProcessSignal::None;
|
||||||
|
debug!("P2Pool Watchdog | Secret dead process reap OK, breaking");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Check SIGNAL
|
// Check SIGNAL
|
||||||
if process.lock().unwrap().signal == ProcessSignal::Stop {
|
if process.lock().unwrap().signal == ProcessSignal::Stop {
|
||||||
|
debug!("P2Pool Watchdog | Stop SIGNAL caught");
|
||||||
child_pty.lock().unwrap().kill(); // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
|
child_pty.lock().unwrap().kill(); // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
|
||||||
// Wait to get the exit status
|
// Wait to get the exit status
|
||||||
let exit_status = match child_pty.lock().unwrap().wait() {
|
let exit_status = match child_pty.lock().unwrap().wait() {
|
||||||
|
@ -491,13 +523,15 @@ impl Helper {
|
||||||
_ => { process.lock().unwrap().state = ProcessState::Failed; "Unknown Error" },
|
_ => { process.lock().unwrap().state = ProcessState::Failed; "Unknown Error" },
|
||||||
};
|
};
|
||||||
let uptime = HumanTime::into_human(start.elapsed());
|
let uptime = HumanTime::into_human(start.elapsed());
|
||||||
info!("P2Pool | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
info!("P2Pool Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
||||||
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
||||||
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
||||||
process.lock().unwrap().signal = ProcessSignal::None;
|
process.lock().unwrap().signal = ProcessSignal::None;
|
||||||
|
debug!("P2Pool Watchdog | Stop SIGNAL done, breaking");
|
||||||
break
|
break
|
||||||
// Check RESTART
|
// Check RESTART
|
||||||
} else if process.lock().unwrap().signal == ProcessSignal::Restart {
|
} else if process.lock().unwrap().signal == ProcessSignal::Restart {
|
||||||
|
debug!("P2Pool Watchdog | Restart SIGNAL caught");
|
||||||
child_pty.lock().unwrap().kill(); // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
|
child_pty.lock().unwrap().kill(); // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
|
||||||
// Wait to get the exit status
|
// Wait to get the exit status
|
||||||
let exit_status = match child_pty.lock().unwrap().wait() {
|
let exit_status = match child_pty.lock().unwrap().wait() {
|
||||||
|
@ -505,22 +539,11 @@ impl Helper {
|
||||||
_ => "Unknown Error",
|
_ => "Unknown Error",
|
||||||
};
|
};
|
||||||
let uptime = HumanTime::into_human(start.elapsed());
|
let uptime = HumanTime::into_human(start.elapsed());
|
||||||
info!("P2Pool | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
info!("P2Pool Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
||||||
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
||||||
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
||||||
process.lock().unwrap().state = ProcessState::Waiting;
|
process.lock().unwrap().state = ProcessState::Waiting;
|
||||||
break
|
debug!("P2Pool Watchdog | Restart SIGNAL done, breaking");
|
||||||
// Check if the process is secretly died without us knowing :)
|
|
||||||
} else if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
|
|
||||||
let exit_status = match code.success() {
|
|
||||||
true => { process.lock().unwrap().state = ProcessState::Dead; "Successful" },
|
|
||||||
false => { process.lock().unwrap().state = ProcessState::Failed; "Failed" },
|
|
||||||
};
|
|
||||||
let uptime = HumanTime::into_human(start.elapsed());
|
|
||||||
info!("P2Pool | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
|
||||||
// This is written directly into the GUI, because sometimes the 900ms event loop can't catch it.
|
|
||||||
writeln!(gui_api.lock().unwrap().output, "{}\nP2Pool stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
|
||||||
process.lock().unwrap().signal = ProcessSignal::None;
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,15 +552,18 @@ impl Helper {
|
||||||
if !lock.input.is_empty() {
|
if !lock.input.is_empty() {
|
||||||
let input = std::mem::take(&mut lock.input);
|
let input = std::mem::take(&mut lock.input);
|
||||||
for line in input {
|
for line in input {
|
||||||
|
debug!("P2Pool Watchdog | User input not empty, writing to STDIN: [{}]", line);
|
||||||
writeln!(lock.stdin.as_mut().unwrap(), "{}", line);
|
writeln!(lock.stdin.as_mut().unwrap(), "{}", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
||||||
// Always update from output
|
// Always update from output
|
||||||
|
debug!("P2Pool Watchdog | Starting [update_from_output()]");
|
||||||
PubP2poolApi::update_from_output(&pub_api, &output_full, &output_buf, start.elapsed(), ®ex);
|
PubP2poolApi::update_from_output(&pub_api, &output_full, &output_buf, start.elapsed(), ®ex);
|
||||||
|
|
||||||
// Read API file into string
|
// Read API file into string
|
||||||
|
debug!("P2Pool Watchdog | Attempting API file read");
|
||||||
if let Ok(string) = PrivP2poolApi::read_p2pool_api(&path) {
|
if let Ok(string) = PrivP2poolApi::read_p2pool_api(&path) {
|
||||||
// Deserialize
|
// Deserialize
|
||||||
if let Ok(s) = PrivP2poolApi::str_to_priv_p2pool_api(&string) {
|
if let Ok(s) = PrivP2poolApi::str_to_priv_p2pool_api(&string) {
|
||||||
|
@ -547,17 +573,24 @@ impl Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if logs need resetting
|
// Check if logs need resetting
|
||||||
|
debug!("P2Pool Watchdog | Attempting log reset check");
|
||||||
Self::check_reset_output_full(&output_full, ProcessName::P2pool);
|
Self::check_reset_output_full(&output_full, ProcessName::P2pool);
|
||||||
Self::check_reset_gui_p2pool_output(&gui_api);
|
Self::check_reset_gui_p2pool_output(&gui_api);
|
||||||
|
|
||||||
// Sleep (only if 900ms hasn't passed)
|
// Sleep (only if 900ms hasn't passed)
|
||||||
let elapsed = now.elapsed().as_millis();
|
let elapsed = now.elapsed().as_millis();
|
||||||
// Since logic goes off if less than 1000, casting should be safe
|
// Since logic goes off if less than 1000, casting should be safe
|
||||||
if elapsed < 900 { std::thread::sleep(std::time::Duration::from_millis((900-elapsed) as u64)); }
|
if elapsed < 900 {
|
||||||
|
let sleep = (900-elapsed) as u64;
|
||||||
|
debug!("P2Pool Watchdog | END OF LOOP - Sleeping for [{}]ms...", sleep);
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(sleep));
|
||||||
|
} else {
|
||||||
|
debug!("P2Pool Watchdog | END OF LOOP - Not sleeping!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If loop broke, we must be done here.
|
// 5. If loop broke, we must be done here.
|
||||||
info!("P2Pool | Watchdog thread exiting... Goodbye!");
|
info!("P2Pool Watchdog | Watchdog thread exiting... Goodbye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- XMRig specific, most functions are very similar to P2Pool's
|
//---------------------------------------------------------------------------------------------------- XMRig specific, most functions are very similar to P2Pool's
|
||||||
|
@ -620,6 +653,7 @@ impl Helper {
|
||||||
thread::sleep(SECOND);
|
thread::sleep(SECOND);
|
||||||
}
|
}
|
||||||
// Ok, process is not alive, start the new one!
|
// Ok, process is not alive, start the new one!
|
||||||
|
info!("XMRig | Old process seems dead, starting new one!");
|
||||||
Self::start_xmrig(&helper, &state, &path, sudo);
|
Self::start_xmrig(&helper, &state, &path, sudo);
|
||||||
});
|
});
|
||||||
info!("XMRig | Restart ... OK");
|
info!("XMRig | Restart ... OK");
|
||||||
|
@ -745,6 +779,7 @@ impl Helper {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn spawn_xmrig_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubXmrigApi>>, pub_api: Arc<Mutex<PubXmrigApi>>, priv_api: Arc<Mutex<PrivXmrigApi>>, args: Vec<String>, mut path: std::path::PathBuf, sudo: Arc<Mutex<SudoState>>, api_ip_port: String) {
|
async fn spawn_xmrig_watchdog(process: Arc<Mutex<Process>>, gui_api: Arc<Mutex<PubXmrigApi>>, pub_api: Arc<Mutex<PubXmrigApi>>, priv_api: Arc<Mutex<PrivXmrigApi>>, args: Vec<String>, mut path: std::path::PathBuf, sudo: Arc<Mutex<SudoState>>, api_ip_port: String) {
|
||||||
// 1a. Create PTY
|
// 1a. Create PTY
|
||||||
|
debug!("XMRig | Creating PTY...");
|
||||||
let pty = portable_pty::native_pty_system();
|
let pty = portable_pty::native_pty_system();
|
||||||
let mut pair = pty.openpty(portable_pty::PtySize {
|
let mut pair = pty.openpty(portable_pty::PtySize {
|
||||||
rows: 100,
|
rows: 100,
|
||||||
|
@ -753,15 +788,18 @@ impl Helper {
|
||||||
pixel_height: 0,
|
pixel_height: 0,
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
// 1b. Create command
|
// 1b. Create command
|
||||||
|
debug!("XMRig | Creating command...");
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let cmd = Self::create_xmrig_cmd_windows(args, path);
|
let cmd = Self::create_xmrig_cmd_windows(args, path);
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
let cmd = Self::create_xmrig_cmd_unix(args, path);
|
let cmd = Self::create_xmrig_cmd_unix(args, path);
|
||||||
// 1c. Create child
|
// 1c. Create child
|
||||||
|
debug!("XMRig | Creating child...");
|
||||||
let child_pty = Arc::new(Mutex::new(pair.slave.spawn_command(cmd).unwrap()));
|
let child_pty = Arc::new(Mutex::new(pair.slave.spawn_command(cmd).unwrap()));
|
||||||
|
|
||||||
// 2. Input [sudo] pass, wipe, then drop.
|
// 2. Input [sudo] pass, wipe, then drop.
|
||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
|
debug!("XMRig | Inputting [sudo] and wiping...");
|
||||||
// 1d. Sleep to wait for [sudo]'s non-echo prompt (on Unix).
|
// 1d. Sleep to wait for [sudo]'s non-echo prompt (on Unix).
|
||||||
// this prevents users pass from showing up in the STDOUT.
|
// this prevents users pass from showing up in the STDOUT.
|
||||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||||
|
@ -770,6 +808,7 @@ impl Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Set process state
|
// 3. Set process state
|
||||||
|
debug!("XMRig | Setting process state...");
|
||||||
let mut lock = process.lock().unwrap();
|
let mut lock = process.lock().unwrap();
|
||||||
lock.state = ProcessState::Alive;
|
lock.state = ProcessState::Alive;
|
||||||
lock.signal = ProcessSignal::None;
|
lock.signal = ProcessSignal::None;
|
||||||
|
@ -780,6 +819,7 @@ impl Helper {
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
||||||
// 4. Spawn PTY read thread
|
// 4. Spawn PTY read thread
|
||||||
|
debug!("XMRig | Spawning PTY read thread...");
|
||||||
let output_full = Arc::clone(&process.lock().unwrap().output_full);
|
let output_full = Arc::clone(&process.lock().unwrap().output_full);
|
||||||
let output_buf = Arc::clone(&process.lock().unwrap().output_buf);
|
let output_buf = Arc::clone(&process.lock().unwrap().output_buf);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
@ -796,9 +836,11 @@ impl Helper {
|
||||||
loop {
|
loop {
|
||||||
// Set timer
|
// Set timer
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
debug!("XMRig Watchdog | ----------- Start of loop -----------");
|
||||||
|
|
||||||
// Check if the process secretly died without us knowing :)
|
// Check if the process secretly died without us knowing :)
|
||||||
if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
|
if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
|
||||||
|
debug!("XMRig Watchdog | Process secretly died on us! Getting exit status...");
|
||||||
let exit_status = match code.success() {
|
let exit_status = match code.success() {
|
||||||
true => { process.lock().unwrap().state = ProcessState::Dead; "Successful" },
|
true => { process.lock().unwrap().state = ProcessState::Dead; "Successful" },
|
||||||
false => { process.lock().unwrap().state = ProcessState::Failed; "Failed" },
|
false => { process.lock().unwrap().state = ProcessState::Failed; "Failed" },
|
||||||
|
@ -807,12 +849,14 @@ impl Helper {
|
||||||
info!("XMRig | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
info!("XMRig | Stopped ... Uptime was: [{}], Exit status: [{}]", uptime, exit_status);
|
||||||
writeln!(gui_api.lock().unwrap().output, "{}\nXMRig stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
writeln!(gui_api.lock().unwrap().output, "{}\nXMRig stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE);
|
||||||
process.lock().unwrap().signal = ProcessSignal::None;
|
process.lock().unwrap().signal = ProcessSignal::None;
|
||||||
|
debug!("XMRig Watchdog | Secret dead process reap OK, breaking");
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop on [Stop/Restart] SIGNAL
|
// Stop on [Stop/Restart] SIGNAL
|
||||||
let signal = process.lock().unwrap().signal;
|
let signal = process.lock().unwrap().signal;
|
||||||
if signal == ProcessSignal::Stop || signal == ProcessSignal::Restart {
|
if signal == ProcessSignal::Stop || signal == ProcessSignal::Restart {
|
||||||
|
debug!("XMRig Watchdog | Stop/Restart SIGNAL caught");
|
||||||
// macOS requires [sudo] again to kill [XMRig]
|
// macOS requires [sudo] again to kill [XMRig]
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
// If we're at this point, that means the user has
|
// If we're at this point, that means the user has
|
||||||
|
@ -851,6 +895,7 @@ impl Helper {
|
||||||
ProcessSignal::Restart => process.state = ProcessState::Waiting,
|
ProcessSignal::Restart => process.state = ProcessState::Waiting,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
debug!("XMRig Watchdog | Stop/Restart SIGNAL done, breaking");
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,33 +904,44 @@ impl Helper {
|
||||||
if !lock.input.is_empty() {
|
if !lock.input.is_empty() {
|
||||||
let input = std::mem::take(&mut lock.input);
|
let input = std::mem::take(&mut lock.input);
|
||||||
for line in input {
|
for line in input {
|
||||||
|
debug!("XMRig Watchdog | User input not empty, writing to STDIN: [{}]", line);
|
||||||
writeln!(lock.stdin.as_mut().unwrap(), "{}", line);
|
writeln!(lock.stdin.as_mut().unwrap(), "{}", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
||||||
// Always update from output
|
// Always update from output
|
||||||
|
debug!("XMRig Watchdog | Starting [update_from_output()]");
|
||||||
PubXmrigApi::update_from_output(&pub_api, &output_buf, start.elapsed());
|
PubXmrigApi::update_from_output(&pub_api, &output_buf, start.elapsed());
|
||||||
|
|
||||||
// Send an HTTP API request
|
// Send an HTTP API request
|
||||||
|
debug!("XMRig Watchdog | Attempting HTTP API request...");
|
||||||
if let Ok(priv_api) = PrivXmrigApi::request_xmrig_api(client.clone(), &api_ip_port).await {
|
if let Ok(priv_api) = PrivXmrigApi::request_xmrig_api(client.clone(), &api_ip_port).await {
|
||||||
|
debug!("XMRig Watchdog | HTTP API request OK, attempting [update_from_priv()]");
|
||||||
PubXmrigApi::update_from_priv(&pub_api, priv_api);
|
PubXmrigApi::update_from_priv(&pub_api, priv_api);
|
||||||
} else {
|
} else {
|
||||||
warn!("XMRig | Could not send HTTP API request to: {}", api_ip_port);
|
warn!("XMRig Watchdog | Could not send HTTP API request to: {}", api_ip_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if logs need resetting
|
// Check if logs need resetting
|
||||||
|
debug!("XMRig Watchdog | Attempting log reset check");
|
||||||
Self::check_reset_output_full(&output_full, ProcessName::Xmrig);
|
Self::check_reset_output_full(&output_full, ProcessName::Xmrig);
|
||||||
Self::check_reset_gui_xmrig_output(&gui_api);
|
Self::check_reset_gui_xmrig_output(&gui_api);
|
||||||
|
|
||||||
// Sleep (only if 900ms hasn't passed)
|
// Sleep (only if 900ms hasn't passed)
|
||||||
let elapsed = now.elapsed().as_millis();
|
let elapsed = now.elapsed().as_millis();
|
||||||
// Since logic goes off if less than 1000, casting should be safe
|
// Since logic goes off if less than 1000, casting should be safe
|
||||||
if elapsed < 900 { std::thread::sleep(std::time::Duration::from_millis((900-elapsed) as u64)); }
|
if elapsed < 900 {
|
||||||
|
let sleep = (900-elapsed) as u64;
|
||||||
|
debug!("XMRig Watchdog | END OF LOOP - Sleeping for [{}]ms...", sleep);
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(sleep));
|
||||||
|
} else {
|
||||||
|
debug!("XMRig Watchdog | END OF LOOP - Not sleeping!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If loop broke, we must be done here.
|
// 5. If loop broke, we must be done here.
|
||||||
info!("XMRig | Watchdog thread exiting... Goodbye!");
|
info!("XMRig Watchdog | Watchdog thread exiting... Goodbye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- The "helper"
|
//---------------------------------------------------------------------------------------------------- The "helper"
|
||||||
|
@ -933,38 +989,56 @@ impl Helper {
|
||||||
loop {
|
loop {
|
||||||
// 1. Loop init timestamp
|
// 1. Loop init timestamp
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
debug!("Helper | ----------- Start of loop -----------");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ignore the invasive [debug!()] messages on the right side of the code.
|
||||||
|
// The reason why they are there are so that it's extremely easy to track
|
||||||
|
// down the culprit of an [Arc<Mutex>] deadlock. I know, they're ugly.
|
||||||
|
//
|
||||||
|
|
||||||
// 2. Lock... EVERYTHING!
|
// 2. Lock... EVERYTHING!
|
||||||
let mut lock = helper.lock().unwrap();
|
let mut lock = helper.lock().unwrap(); debug!("Helper | Locking (1/8) ... [helper]");
|
||||||
// Calculate Gupax's uptime always.
|
// Calculate Gupax's uptime always.
|
||||||
lock.uptime = HumanTime::into_human(lock.instant.elapsed());
|
lock.uptime = HumanTime::into_human(lock.instant.elapsed());
|
||||||
let mut gui_api_p2pool = lock.gui_api_p2pool.lock().unwrap();
|
let mut gui_api_p2pool = lock.gui_api_p2pool.lock().unwrap(); debug!("Helper | Locking (2/8) ... [gui_api_p2pool]");
|
||||||
let mut gui_api_xmrig = lock.gui_api_xmrig.lock().unwrap();
|
let mut gui_api_xmrig = lock.gui_api_xmrig.lock().unwrap(); debug!("Helper | Locking (3/8) ... [gui_api_xmrig]");
|
||||||
let mut pub_api_p2pool = lock.pub_api_p2pool.lock().unwrap();
|
let mut pub_api_p2pool = lock.pub_api_p2pool.lock().unwrap(); debug!("Helper | Locking (4/8) ... [pub_api_p2pool]");
|
||||||
let mut pub_api_xmrig = lock.pub_api_xmrig.lock().unwrap();
|
let mut pub_api_xmrig = lock.pub_api_xmrig.lock().unwrap(); debug!("Helper | Locking (5/8) ... [pub_api_xmrig]");
|
||||||
let p2pool = lock.p2pool.lock().unwrap();
|
let p2pool = lock.p2pool.lock().unwrap(); debug!("Helper | Locking (6/8) ... [p2pool]");
|
||||||
let xmrig = lock.xmrig.lock().unwrap();
|
let xmrig = lock.xmrig.lock().unwrap(); debug!("Helper | Locking (7/8) ... [xmrig]");
|
||||||
let mut lock_pub_sys = pub_sys.lock().unwrap();
|
let mut lock_pub_sys = pub_sys.lock().unwrap(); debug!("Helper | Locking (8/8) ... [pub_sys]");
|
||||||
// If [P2Pool] is alive...
|
// If [P2Pool] is alive...
|
||||||
if p2pool.is_alive() { PubP2poolApi::combine_gui_pub_api(&mut gui_api_p2pool, &mut pub_api_p2pool); }
|
if p2pool.is_alive() {
|
||||||
|
debug!("Helper | P2Pool is alive! Running [combine_gui_pub_api()]");
|
||||||
|
PubP2poolApi::combine_gui_pub_api(&mut gui_api_p2pool, &mut pub_api_p2pool);
|
||||||
|
} else {
|
||||||
|
debug!("Helper | P2Pool is dead! Skipping...");
|
||||||
|
}
|
||||||
// If [XMRig] is alive...
|
// If [XMRig] is alive...
|
||||||
if xmrig.is_alive() { PubXmrigApi::combine_gui_pub_api(&mut gui_api_xmrig, &mut pub_api_xmrig); }
|
if xmrig.is_alive() {
|
||||||
|
debug!("Helper | XMRig is alive! Running [combine_gui_pub_api()]");
|
||||||
|
PubXmrigApi::combine_gui_pub_api(&mut gui_api_xmrig, &mut pub_api_xmrig);
|
||||||
|
} else {
|
||||||
|
debug!("Helper | XMRig is dead! Skipping...");
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Selectively refresh [sysinfo] for only what we need (better performance).
|
// 2. Selectively refresh [sysinfo] for only what we need (better performance).
|
||||||
sysinfo.refresh_cpu_specifics(sysinfo_cpu);
|
sysinfo.refresh_cpu_specifics(sysinfo_cpu); debug!("Helper | Sysinfo refresh (1/3) ... [cpu]");
|
||||||
sysinfo.refresh_processes_specifics(sysinfo_processes);
|
sysinfo.refresh_processes_specifics(sysinfo_processes); debug!("Helper | Sysinfo refresh (2/3) ... [processes]");
|
||||||
sysinfo.refresh_memory();
|
sysinfo.refresh_memory(); debug!("Helper | Sysinfo refresh (3/3) ... [memory]");
|
||||||
|
debug!("Helper | Sysinfo OK, running [update_pub_sys_from_sysinfo()]");
|
||||||
Self::update_pub_sys_from_sysinfo(&sysinfo, &mut lock_pub_sys, &pid, &lock, max_threads);
|
Self::update_pub_sys_from_sysinfo(&sysinfo, &mut lock_pub_sys, &pid, &lock, max_threads);
|
||||||
|
|
||||||
// 3. Drop... (almost) EVERYTHING... IN REVERSE!
|
// 3. Drop... (almost) EVERYTHING... IN REVERSE!
|
||||||
drop(lock_pub_sys);
|
drop(lock_pub_sys); debug!("Helper | Unlocking (1/8) ... [pub_sys]");
|
||||||
drop(xmrig);
|
drop(xmrig); debug!("Helper | Unlocking (2/8) ... [xmrig]");
|
||||||
drop(p2pool);
|
drop(p2pool); debug!("Helper | Unlocking (3/8) ... [p2pool]");
|
||||||
drop(pub_api_xmrig);
|
drop(pub_api_xmrig); debug!("Helper | Unlocking (4/8) ... [pub_api_xmrig]");
|
||||||
drop(pub_api_p2pool);
|
drop(pub_api_p2pool); debug!("Helper | Unlocking (5/8) ... [pub_api_p2pool]");
|
||||||
drop(gui_api_xmrig);
|
drop(gui_api_xmrig); debug!("Helper | Unlocking (6/8) ... [gui_api_xmrig]");
|
||||||
drop(gui_api_p2pool);
|
drop(gui_api_p2pool); debug!("Helper | Unlocking (7/8) ... [gui_api_p2pool]");
|
||||||
drop(lock);
|
drop(lock); debug!("Helper | Unlocking (8/8) ... [helper]");
|
||||||
|
|
||||||
// 4. Calculate if we should sleep or not.
|
// 4. Calculate if we should sleep or not.
|
||||||
// If we should sleep, how long?
|
// If we should sleep, how long?
|
||||||
|
@ -972,7 +1046,11 @@ impl Helper {
|
||||||
if elapsed < 1000 {
|
if elapsed < 1000 {
|
||||||
// Casting from u128 to u64 should be safe here, because [elapsed]
|
// Casting from u128 to u64 should be safe here, because [elapsed]
|
||||||
// is less than 1000, meaning it can fit into a u64 easy.
|
// is less than 1000, meaning it can fit into a u64 easy.
|
||||||
std::thread::sleep(std::time::Duration::from_millis((1000-elapsed) as u64));
|
let sleep = (1000-elapsed) as u64;
|
||||||
|
debug!("Helper | END OF LOOP - Sleeping for [{}]ms...", sleep);
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(sleep));
|
||||||
|
} else {
|
||||||
|
debug!("Helper | END OF LOOP - Not sleeping!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. End loop
|
// 5. End loop
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -166,6 +166,7 @@ impl App {
|
||||||
|
|
||||||
fn new(now: Instant) -> Self {
|
fn new(now: Instant) -> Self {
|
||||||
info!("Initializing App Struct...");
|
info!("Initializing App Struct...");
|
||||||
|
debug!("App Init | P2Pool & XMRig processes...");
|
||||||
let p2pool = Arc::new(Mutex::new(Process::new(ProcessName::P2pool, String::new(), PathBuf::new())));
|
let p2pool = Arc::new(Mutex::new(Process::new(ProcessName::P2pool, String::new(), PathBuf::new())));
|
||||||
let xmrig = Arc::new(Mutex::new(Process::new(ProcessName::Xmrig, String::new(), PathBuf::new())));
|
let xmrig = Arc::new(Mutex::new(Process::new(ProcessName::Xmrig, String::new(), PathBuf::new())));
|
||||||
let p2pool_api = Arc::new(Mutex::new(PubP2poolApi::new()));
|
let p2pool_api = Arc::new(Mutex::new(PubP2poolApi::new()));
|
||||||
|
@ -173,6 +174,7 @@ impl App {
|
||||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||||
|
|
||||||
|
debug!("App Init | Sysinfo...");
|
||||||
// We give this to the [Helper] thread.
|
// We give this to the [Helper] thread.
|
||||||
let mut sysinfo = sysinfo::System::new_with_specifics(
|
let mut sysinfo = sysinfo::System::new_with_specifics(
|
||||||
sysinfo::RefreshKind::new()
|
sysinfo::RefreshKind::new()
|
||||||
|
@ -183,6 +185,7 @@ impl App {
|
||||||
let pid = sysinfo::get_current_pid().unwrap();
|
let pid = sysinfo::get_current_pid().unwrap();
|
||||||
let pub_sys = Arc::new(Mutex::new(Sys::new()));
|
let pub_sys = Arc::new(Mutex::new(Sys::new()));
|
||||||
|
|
||||||
|
debug!("App Init | The rest of the [App]...");
|
||||||
let mut app = Self {
|
let mut app = Self {
|
||||||
tab: Tab::default(),
|
tab: Tab::default(),
|
||||||
ping: Arc::new(Mutex::new(Ping::new())),
|
ping: Arc::new(Mutex::new(Ping::new())),
|
||||||
|
@ -232,6 +235,7 @@ impl App {
|
||||||
regex: Regexes::new(),
|
regex: Regexes::new(),
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------------------------------- App init data that *could* panic
|
//---------------------------------------------------------------------------------------------------- App init data that *could* panic
|
||||||
|
debug!("App Init | Getting EXE path...");
|
||||||
let mut panic = String::new();
|
let mut panic = String::new();
|
||||||
// Get exe path
|
// Get exe path
|
||||||
app.exe = match get_exe() {
|
app.exe = match get_exe() {
|
||||||
|
@ -249,6 +253,7 @@ impl App {
|
||||||
Err(e) => { panic = format!("get_os_data_path(): {}", e); app.error_state.set(panic.clone(), ErrorFerris::Panic, ErrorButtons::Quit); PathBuf::new() },
|
Err(e) => { panic = format!("get_os_data_path(): {}", e); app.error_state.set(panic.clone(), ErrorFerris::Panic, ErrorButtons::Quit); PathBuf::new() },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
debug!("App Init | Setting TOML path...");
|
||||||
// Set [*.toml] path
|
// Set [*.toml] path
|
||||||
app.state_path = app.os_data_path.clone();
|
app.state_path = app.os_data_path.clone();
|
||||||
app.state_path.push("state.toml");
|
app.state_path.push("state.toml");
|
||||||
|
@ -260,9 +265,11 @@ impl App {
|
||||||
// Apply arg state
|
// Apply arg state
|
||||||
// It's not safe to [--reset] if any of the previous variables
|
// It's not safe to [--reset] if any of the previous variables
|
||||||
// are unset (null path), so make sure we just abort if the [panic] String contains something.
|
// are unset (null path), so make sure we just abort if the [panic] String contains something.
|
||||||
|
debug!("App Init | Applying argument state...");
|
||||||
let mut app = parse_args(app, panic);
|
let mut app = parse_args(app, panic);
|
||||||
|
|
||||||
// Read disk state
|
// Read disk state
|
||||||
|
debug!("App Init | Reading disk state...");
|
||||||
use TomlError::*;
|
use TomlError::*;
|
||||||
app.state = match State::get(&app.state_path) {
|
app.state = match State::get(&app.state_path) {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
|
@ -281,6 +288,7 @@ impl App {
|
||||||
};
|
};
|
||||||
app.og = Arc::new(Mutex::new(app.state.clone()));
|
app.og = Arc::new(Mutex::new(app.state.clone()));
|
||||||
// Read node list
|
// Read node list
|
||||||
|
debug!("App Init | Reading node list...");
|
||||||
app.og_node_vec = match Node::get(&app.node_path) {
|
app.og_node_vec = match Node::get(&app.node_path) {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -297,6 +305,7 @@ impl App {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// Read pool list
|
// Read pool list
|
||||||
|
debug!("App Init | Reading pool list...");
|
||||||
app.og_pool_vec = match Pool::get(&app.pool_path) {
|
app.og_pool_vec = match Pool::get(&app.pool_path) {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -317,6 +326,7 @@ impl App {
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
let mut og = app.og.lock().unwrap(); // Lock [og]
|
let mut og = app.og.lock().unwrap(); // Lock [og]
|
||||||
// Handle max threads
|
// Handle max threads
|
||||||
|
debug!("App Init | Handling max thread overflow...");
|
||||||
og.xmrig.max_threads = app.max_threads;
|
og.xmrig.max_threads = app.max_threads;
|
||||||
let current = og.xmrig.current_threads;
|
let current = og.xmrig.current_threads;
|
||||||
let max = og.xmrig.max_threads;
|
let max = og.xmrig.max_threads;
|
||||||
|
@ -324,6 +334,7 @@ impl App {
|
||||||
og.xmrig.current_threads = max;
|
og.xmrig.current_threads = max;
|
||||||
}
|
}
|
||||||
// Handle [node_vec] overflow
|
// Handle [node_vec] overflow
|
||||||
|
debug!("App Init | Handling [node_vec] overflow");
|
||||||
if og.p2pool.selected_index > app.og_node_vec.len() {
|
if og.p2pool.selected_index > app.og_node_vec.len() {
|
||||||
warn!("App | Overflowing manual node index [{} > {}], resetting to 1", og.p2pool.selected_index, app.og_node_vec.len());
|
warn!("App | Overflowing manual node index [{} > {}], resetting to 1", og.p2pool.selected_index, app.og_node_vec.len());
|
||||||
let (name, node) = app.og_node_vec[0].clone();
|
let (name, node) = app.og_node_vec[0].clone();
|
||||||
|
@ -339,6 +350,7 @@ impl App {
|
||||||
app.state.p2pool.selected_zmq = node.zmq;
|
app.state.p2pool.selected_zmq = node.zmq;
|
||||||
}
|
}
|
||||||
// Handle [pool_vec] overflow
|
// Handle [pool_vec] overflow
|
||||||
|
debug!("App Init | Handling [pool_vec] overflow...");
|
||||||
if og.xmrig.selected_index > app.og_pool_vec.len() {
|
if og.xmrig.selected_index > app.og_pool_vec.len() {
|
||||||
warn!("App | Overflowing manual pool index [{} > {}], resetting to 1", og.xmrig.selected_index, app.og_pool_vec.len());
|
warn!("App | Overflowing manual pool index [{} > {}], resetting to 1", og.xmrig.selected_index, app.og_pool_vec.len());
|
||||||
let (name, pool) = app.og_pool_vec[0].clone();
|
let (name, pool) = app.og_pool_vec[0].clone();
|
||||||
|
@ -351,16 +363,24 @@ impl App {
|
||||||
app.state.xmrig.selected_ip = pool.ip;
|
app.state.xmrig.selected_ip = pool.ip;
|
||||||
app.state.xmrig.selected_port = pool.port;
|
app.state.xmrig.selected_port = pool.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply TOML values to [Update]
|
// Apply TOML values to [Update]
|
||||||
|
debug!("App Init | Applying TOML values to [Update]...");
|
||||||
let p2pool_path = og.gupax.absolute_p2pool_path.clone();
|
let p2pool_path = og.gupax.absolute_p2pool_path.clone();
|
||||||
let xmrig_path = og.gupax.absolute_xmrig_path.clone();
|
let xmrig_path = og.gupax.absolute_xmrig_path.clone();
|
||||||
let tor = og.gupax.update_via_tor;
|
let tor = og.gupax.update_via_tor;
|
||||||
app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor)));
|
app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor)));
|
||||||
|
|
||||||
|
|
||||||
|
debug!("App Init | Setting state Gupax version...");
|
||||||
// Set state version as compiled in version
|
// Set state version as compiled in version
|
||||||
og.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
|
og.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
|
||||||
app.state.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
|
app.state.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
|
||||||
|
|
||||||
|
debug!("App Init | Setting saved [Tab]...");
|
||||||
// Set saved [Tab]
|
// Set saved [Tab]
|
||||||
app.tab = app.state.gupax.tab;
|
app.tab = app.state.gupax.tab;
|
||||||
|
|
||||||
drop(og); // Unlock [og]
|
drop(og); // Unlock [og]
|
||||||
info!("App ... OK");
|
info!("App ... OK");
|
||||||
|
|
||||||
|
@ -370,6 +390,7 @@ impl App {
|
||||||
info!("Helper ... OK");
|
info!("Helper ... OK");
|
||||||
|
|
||||||
// Check for privilege. Should be Admin on [Windows] and NOT root on Unix.
|
// Check for privilege. Should be Admin on [Windows] and NOT root on Unix.
|
||||||
|
debug!("App Init | Checking for privilege level...");
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
if is_elevated::is_elevated() {
|
if is_elevated::is_elevated() {
|
||||||
app.admin = true;
|
app.admin = true;
|
||||||
|
@ -835,6 +856,7 @@ impl eframe::App for App {
|
||||||
// *-------*
|
// *-------*
|
||||||
// | DEBUG |
|
// | DEBUG |
|
||||||
// *-------*
|
// *-------*
|
||||||
|
debug!("App | ----------- Start of [update()] -----------");
|
||||||
|
|
||||||
// If [F11] was pressed, reverse [fullscreen] bool
|
// If [F11] was pressed, reverse [fullscreen] bool
|
||||||
if ctx.input_mut().consume_key(Modifiers::NONE, Key::F11) {
|
if ctx.input_mut().consume_key(Modifiers::NONE, Key::F11) {
|
||||||
|
@ -843,10 +865,12 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh AT LEAST once a second
|
// Refresh AT LEAST once a second
|
||||||
|
debug!("App | Refreshing frame once per second");
|
||||||
ctx.request_repaint_after(SECOND);
|
ctx.request_repaint_after(SECOND);
|
||||||
|
|
||||||
// This sets the top level Ui dimensions.
|
// This sets the top level Ui dimensions.
|
||||||
// Used as a reference for other uis.
|
// Used as a reference for other uis.
|
||||||
|
debug!("App | Setting width/height");
|
||||||
CentralPanel::default().show(ctx, |ui| {
|
CentralPanel::default().show(ctx, |ui| {
|
||||||
let available_width = ui.available_width();
|
let available_width = ui.available_width();
|
||||||
if self.width != available_width {
|
if self.width != available_width {
|
||||||
|
@ -863,6 +887,7 @@ impl eframe::App for App {
|
||||||
// while the user was readjusting the frame. It's a pretty heavy operation and looks
|
// while the user was readjusting the frame. It's a pretty heavy operation and looks
|
||||||
// buggy when calling it that many times. Looking for a [must_resize] in addtion to
|
// buggy when calling it that many times. Looking for a [must_resize] in addtion to
|
||||||
// checking if the user is hovering over the app means that we only have call it once.
|
// checking if the user is hovering over the app means that we only have call it once.
|
||||||
|
debug!("App | Checking if we need to resize");
|
||||||
if self.must_resize && ctx.is_pointer_over_area() {
|
if self.must_resize && ctx.is_pointer_over_area() {
|
||||||
self.resizing = true;
|
self.resizing = true;
|
||||||
self.must_resize = false;
|
self.must_resize = false;
|
||||||
|
@ -899,6 +924,7 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's an error, display [ErrorState] on the whole screen until user responds
|
// If there's an error, display [ErrorState] on the whole screen until user responds
|
||||||
|
debug!("App | Checking if there is an error in [ErrorState]");
|
||||||
if self.error_state.error {
|
if self.error_state.error {
|
||||||
CentralPanel::default().show(ctx, |ui| {
|
CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
|
@ -1058,6 +1084,7 @@ impl eframe::App for App {
|
||||||
// The struct fields are compared directly because [Version]
|
// The struct fields are compared directly because [Version]
|
||||||
// contains Arc<Mutex>'s that cannot be compared easily.
|
// contains Arc<Mutex>'s that cannot be compared easily.
|
||||||
// They don't need to be compared anyway.
|
// They don't need to be compared anyway.
|
||||||
|
debug!("App | Checking diff between [og] & [state]");
|
||||||
let og = self.og.lock().unwrap();
|
let og = self.og.lock().unwrap();
|
||||||
if og.gupax != self.state.gupax || og.p2pool != self.state.p2pool || og.xmrig != self.state.xmrig || self.og_node_vec != self.node_vec {
|
if og.gupax != self.state.gupax || og.p2pool != self.state.p2pool || og.xmrig != self.state.xmrig || self.og_node_vec != self.node_vec {
|
||||||
self.diff = true;
|
self.diff = true;
|
||||||
|
@ -1067,6 +1094,7 @@ impl eframe::App for App {
|
||||||
drop(og);
|
drop(og);
|
||||||
|
|
||||||
// Top: Tabs
|
// Top: Tabs
|
||||||
|
debug!("App | Rendering TOP tabs");
|
||||||
TopBottomPanel::top("top").show(ctx, |ui| {
|
TopBottomPanel::top("top").show(ctx, |ui| {
|
||||||
let width = (self.width - (SPACE*10.0))/5.0;
|
let width = (self.width - (SPACE*10.0))/5.0;
|
||||||
let height = self.height/12.0;
|
let height = self.height/12.0;
|
||||||
|
@ -1091,6 +1119,7 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bottom: app info + state/process buttons
|
// Bottom: app info + state/process buttons
|
||||||
|
debug!("App | Rendering BOTTOM bar");
|
||||||
TopBottomPanel::bottom("bottom").show(ctx, |ui| {
|
TopBottomPanel::bottom("bottom").show(ctx, |ui| {
|
||||||
let height = self.height/20.0;
|
let height = self.height/20.0;
|
||||||
ui.style_mut().override_text_style = Some(Name("Bottom".into()));
|
ui.style_mut().override_text_style = Some(Name("Bottom".into()));
|
||||||
|
@ -1308,6 +1337,7 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Middle panel, contents of the [Tab]
|
// Middle panel, contents of the [Tab]
|
||||||
|
debug!("App | Rendering CENTRAL_PANEL (tab contents)");
|
||||||
CentralPanel::default().show(ctx, |ui| {
|
CentralPanel::default().show(ctx, |ui| {
|
||||||
// This sets the Ui dimensions after Top/Bottom are filled
|
// This sets the Ui dimensions after Top/Bottom are filled
|
||||||
self.width = ui.available_width();
|
self.width = ui.available_width();
|
||||||
|
@ -1315,6 +1345,7 @@ impl eframe::App for App {
|
||||||
ui.style_mut().override_text_style = Some(TextStyle::Body);
|
ui.style_mut().override_text_style = Some(TextStyle::Body);
|
||||||
match self.tab {
|
match self.tab {
|
||||||
Tab::About => {
|
Tab::About => {
|
||||||
|
debug!("App | Entering [About] Tab");
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
// Display [Gupax] banner at max, 1/4 the available length
|
// Display [Gupax] banner at max, 1/4 the available length
|
||||||
|
@ -1336,15 +1367,19 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Tab::Status => {
|
Tab::Status => {
|
||||||
|
debug!("App | Entering [Status] Tab");
|
||||||
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);
|
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 => {
|
Tab::Gupax => {
|
||||||
|
debug!("App | Entering [Gupax] Tab");
|
||||||
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);
|
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);
|
||||||
}
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
|
debug!("App | Entering [P2Pool] Tab");
|
||||||
P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, &self.ping, &self.regex, &self.p2pool, &self.p2pool_api, &mut self.p2pool_console, self.width, self.height, ctx, ui);
|
P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, &self.ping, &self.regex, &self.p2pool, &self.p2pool_api, &mut self.p2pool_console, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Xmrig => {
|
Tab::Xmrig => {
|
||||||
|
debug!("App | Entering [XMRig] Tab");
|
||||||
Xmrig::show(&mut self.state.xmrig, &mut self.pool_vec, &self.regex, &self.xmrig, &self.xmrig_api, &mut self.xmrig_console, self.width, self.height, ctx, ui);
|
Xmrig::show(&mut self.state.xmrig, &mut self.pool_vec, &self.regex, &self.xmrig, &self.xmrig_api, &mut self.xmrig_console, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
src/node.rs
27
src/node.rs
|
@ -213,12 +213,14 @@ impl Ping {
|
||||||
//---------------------------------------------------------------------------------------------------- Main Ping function
|
//---------------------------------------------------------------------------------------------------- Main Ping function
|
||||||
// Intermediate function for spawning thread
|
// Intermediate function for spawning thread
|
||||||
pub fn spawn_thread(ping: &Arc<Mutex<Self>>) {
|
pub fn spawn_thread(ping: &Arc<Mutex<Self>>) {
|
||||||
|
info!("Spawning ping thread...");
|
||||||
let ping = Arc::clone(ping);
|
let ping = Arc::clone(ping);
|
||||||
std::thread::spawn(move|| {
|
std::thread::spawn(move|| {
|
||||||
info!("Spawning ping thread...");
|
let now = Instant::now();
|
||||||
match Self::ping(ping.clone()) {
|
match Self::ping(&ping) {
|
||||||
Ok(_) => {
|
Ok(msg) => {
|
||||||
info!("Ping ... OK");
|
info!("Ping ... OK");
|
||||||
|
ping.lock().unwrap().msg = msg;
|
||||||
ping.lock().unwrap().pinged = true;
|
ping.lock().unwrap().pinged = true;
|
||||||
ping.lock().unwrap().auto_selected = false;
|
ping.lock().unwrap().auto_selected = false;
|
||||||
},
|
},
|
||||||
|
@ -228,6 +230,7 @@ impl Ping {
|
||||||
ping.lock().unwrap().msg = err.to_string();
|
ping.lock().unwrap().msg = err.to_string();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
info!("Ping ... Took [{}] seconds...", now.elapsed().as_secs_f32());
|
||||||
ping.lock().unwrap().pinging = false;
|
ping.lock().unwrap().pinging = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -250,9 +253,10 @@ impl Ping {
|
||||||
// timeout = BLACK
|
// timeout = BLACK
|
||||||
// default = GRAY
|
// default = GRAY
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn ping(ping: Arc<Mutex<Self>>) -> Result<(), anyhow::Error> {
|
pub async fn ping(ping: &Arc<Mutex<Self>>) -> Result<String, anyhow::Error> {
|
||||||
// Timer
|
// Timer
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
let ping = Arc::clone(ping);
|
||||||
|
|
||||||
// Start ping
|
// Start ping
|
||||||
ping.lock().unwrap().pinging = true;
|
ping.lock().unwrap().pinging = true;
|
||||||
|
@ -268,8 +272,8 @@ impl Ping {
|
||||||
// Random User Agent
|
// Random User Agent
|
||||||
let rand_user_agent = crate::Pkg::get_user_agent();
|
let rand_user_agent = crate::Pkg::get_user_agent();
|
||||||
// Handle vector
|
// Handle vector
|
||||||
let mut handles = vec![];
|
let mut handles = Vec::with_capacity(NODE_IPS.len());
|
||||||
let node_vec = Arc::new(Mutex::new(Vec::new()));
|
let node_vec = Arc::new(Mutex::new(Vec::with_capacity(NODE_IPS.len())));
|
||||||
|
|
||||||
for ip in NODE_IPS {
|
for ip in NODE_IPS {
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
|
@ -288,18 +292,19 @@ impl Ping {
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
handle.await?;
|
handle.await?;
|
||||||
}
|
}
|
||||||
let node_vec = node_vec.lock().unwrap().clone();
|
|
||||||
|
|
||||||
let info = format!("Fastest node: {}ms ... {} @ {}", node_vec[0].ms, node_vec[0].id, node_vec[0].ip);
|
let node_vec = std::mem::take(&mut *node_vec.lock().unwrap());
|
||||||
info!("Ping | {}", info);
|
let fastest_info = format!("Fastest node: {}ms ... {} @ {}", node_vec[0].ms, node_vec[0].id, node_vec[0].ip);
|
||||||
info!("Ping | Took [{}] seconds...", now.elapsed().as_secs_f32());
|
|
||||||
|
let info = format!("Cleaning up connections");
|
||||||
|
info!("Ping | {}...", info);
|
||||||
let mut ping = ping.lock().unwrap();
|
let mut ping = ping.lock().unwrap();
|
||||||
ping.fastest = node_vec[0].id;
|
ping.fastest = node_vec[0].id;
|
||||||
ping.nodes = node_vec;
|
ping.nodes = node_vec;
|
||||||
ping.prog = 100.0;
|
ping.prog = 100.0;
|
||||||
ping.msg = info;
|
ping.msg = info;
|
||||||
drop(ping);
|
drop(ping);
|
||||||
Ok(())
|
Ok(fastest_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn response(client: Client<HttpConnector>, request: Request<Body>, ip: &'static str, ping: Arc<Mutex<Self>>, percent: f32, node_vec: Arc<Mutex<Vec<NodeData>>>) {
|
async fn response(client: Client<HttpConnector>, request: Request<Body>, ip: &'static str, ping: Arc<Mutex<Self>>, percent: f32, node_vec: Arc<Mutex<Vec<NodeData>>>) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ impl P2pool {
|
||||||
pub fn show(&mut self, node_vec: &mut Vec<(String, Node)>, og: &Arc<Mutex<State>>, ping: &Arc<Mutex<Ping>>, regex: &Regexes, process: &Arc<Mutex<Process>>, api: &Arc<Mutex<PubP2poolApi>>, buffer: &mut String, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, node_vec: &mut Vec<(String, Node)>, og: &Arc<Mutex<State>>, ping: &Arc<Mutex<Ping>>, regex: &Regexes, process: &Arc<Mutex<Process>>, api: &Arc<Mutex<PubP2poolApi>>, buffer: &mut String, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let text_edit = height / 25.0;
|
let text_edit = height / 25.0;
|
||||||
//---------------------------------------------------------------------------------------------------- [Simple] Console
|
//---------------------------------------------------------------------------------------------------- [Simple] Console
|
||||||
|
debug!("P2Pool Tab | Rendering [Console]");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
if self.simple {
|
if self.simple {
|
||||||
let height = height / 2.4;
|
let height = height / 2.4;
|
||||||
|
@ -71,6 +72,7 @@ impl P2pool {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Args
|
//---------------------------------------------------------------------------------------------------- Args
|
||||||
if !self.simple {
|
if !self.simple {
|
||||||
|
debug!("P2Pool Tab | Rendering [Arguments]");
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
let width = (width/10.0) - SPACE;
|
let width = (width/10.0) - SPACE;
|
||||||
ui.style_mut().override_text_style = Some(Monospace);
|
ui.style_mut().override_text_style = Some(Monospace);
|
||||||
|
@ -82,6 +84,7 @@ impl P2pool {
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Address
|
//---------------------------------------------------------------------------------------------------- Address
|
||||||
|
debug!("P2Pool Tab | Rendering [Address]");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = width - SPACE;
|
let width = width - SPACE;
|
||||||
ui.spacing_mut().text_edit_width = (width)-(SPACE*3.0);
|
ui.spacing_mut().text_edit_width = (width)-(SPACE*3.0);
|
||||||
|
@ -117,6 +120,7 @@ impl P2pool {
|
||||||
// saves me the hassle of wrapping [state: State] completely
|
// saves me the hassle of wrapping [state: State] completely
|
||||||
// and [.lock().unwrap()]ing it everywhere.
|
// and [.lock().unwrap()]ing it everywhere.
|
||||||
// Two atomic bools = enough to represent this data
|
// Two atomic bools = enough to represent this data
|
||||||
|
debug!("P2Pool Tab | Running [auto-select] check");
|
||||||
if self.auto_select {
|
if self.auto_select {
|
||||||
let mut ping = ping.lock().unwrap();
|
let mut ping = ping.lock().unwrap();
|
||||||
// If we haven't auto_selected yet, auto-select and turn it off
|
// If we haven't auto_selected yet, auto-select and turn it off
|
||||||
|
@ -129,6 +133,7 @@ impl P2pool {
|
||||||
|
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
debug!("P2Pool Tab | Rendering [Ping List]");
|
||||||
// [Ping List]
|
// [Ping List]
|
||||||
let id = self.node;
|
let id = self.node;
|
||||||
let ip = enum_to_ip(id);
|
let ip = enum_to_ip(id);
|
||||||
|
@ -143,6 +148,7 @@ impl P2pool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug!("P2Pool Tab | Rendering [ComboBox] of Community Nodes");
|
||||||
let text = RichText::new(format!(" ⏺ {}ms | {} | {}", ms, id, ip)).color(color);
|
let text = RichText::new(format!(" ⏺ {}ms | {} | {}", ms, id, ip)).color(color);
|
||||||
ComboBox::from_id_source("community_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
ComboBox::from_id_source("community_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
||||||
for data in ping.lock().unwrap().nodes.iter() {
|
for data in ping.lock().unwrap().nodes.iter() {
|
||||||
|
@ -156,6 +162,7 @@ impl P2pool {
|
||||||
|
|
||||||
ui.add_space(5.0);
|
ui.add_space(5.0);
|
||||||
|
|
||||||
|
debug!("P2Pool Tab | Rendering [Select fastest ... Ping] buttons");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let width = (width/2.0)-4.0;
|
let width = (width/2.0)-4.0;
|
||||||
// [Select fastest node]
|
// [Select fastest node]
|
||||||
|
@ -189,15 +196,11 @@ impl P2pool {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
debug!("P2Pool Tab | Rendering [Auto-*] buttons");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let width = (width/2.0)-(SPACE*1.75);
|
let width = (width/2.0)-(SPACE*1.75);
|
||||||
// [Auto-node] + [Auto-select]
|
// [Auto-node] + [Auto-select]
|
||||||
// let mut style = (*ctx.style()).clone();
|
|
||||||
// style.spacing.icon_width_inner = width / 16.0;
|
|
||||||
// style.spacing.icon_width = width / 6.0;
|
|
||||||
// style.spacing.icon_spacing = 20.0;
|
|
||||||
// ctx.set_style(style);
|
|
||||||
ui.add_sized([width, height], Checkbox::new(&mut self.auto_select, "Auto-select")).on_hover_text(P2POOL_AUTO_SELECT);
|
ui.add_sized([width, height], Checkbox::new(&mut self.auto_select, "Auto-select")).on_hover_text(P2POOL_AUTO_SELECT);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add_sized([width, height], Checkbox::new(&mut self.auto_node, "Auto-node")).on_hover_text(P2POOL_AUTO_NODE);
|
ui.add_sized([width, height], Checkbox::new(&mut self.auto_node, "Auto-node")).on_hover_text(P2POOL_AUTO_NODE);
|
||||||
|
@ -205,6 +208,7 @@ impl P2pool {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Advanced
|
//---------------------------------------------------------------------------------------------------- Advanced
|
||||||
} else {
|
} else {
|
||||||
|
debug!("P2Pool Tab | Rendering [Node List] elements");
|
||||||
let mut incorrect_input = false; // This will disable [Add/Delete] on bad input
|
let mut incorrect_input = false; // This will disable [Add/Delete] on bad input
|
||||||
// [Monero node IP/RPC/ZMQ]
|
// [Monero node IP/RPC/ZMQ]
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
@ -302,6 +306,7 @@ impl P2pool {
|
||||||
ui.spacing_mut().slider_width = width - 8.0;
|
ui.spacing_mut().slider_width = width - 8.0;
|
||||||
ui.spacing_mut().icon_width = width / 25.0;
|
ui.spacing_mut().icon_width = width / 25.0;
|
||||||
// [Ping List]
|
// [Ping List]
|
||||||
|
debug!("P2Pool Tab | Rendering [Node List]");
|
||||||
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
|
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
|
||||||
ComboBox::from_id_source("manual_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
ComboBox::from_id_source("manual_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
|
@ -416,6 +421,7 @@ impl P2pool {
|
||||||
});
|
});
|
||||||
ui.add_space(5.0);
|
ui.add_space(5.0);
|
||||||
|
|
||||||
|
debug!("P2Pool Tab | Rendering [Main/Mini/Peers/Log] elements");
|
||||||
// [Main/Mini]
|
// [Main/Mini]
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let height = height/4.0;
|
let height = height/4.0;
|
||||||
|
|
|
@ -25,6 +25,7 @@ use crate::{
|
||||||
Sys,
|
Sys,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc,Mutex};
|
use std::sync::{Arc,Mutex};
|
||||||
|
use log::*;
|
||||||
use egui::{
|
use egui::{
|
||||||
containers::*,
|
containers::*,
|
||||||
Label,RichText,TextStyle
|
Label,RichText,TextStyle
|
||||||
|
@ -42,6 +43,7 @@ pub fn show(sys: &Arc<Mutex<Sys>>, p2pool_api: &Arc<Mutex<PubP2poolApi>>, xmrig_
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
// [Gupax]
|
// [Gupax]
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
|
debug!("Status | Rendering [Gupax]");
|
||||||
ui.set_min_height(min_height);
|
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())))).on_hover_text("Gupax is online");
|
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");
|
||||||
let sys = sys.lock().unwrap();
|
let sys = sys.lock().unwrap();
|
||||||
|
@ -61,6 +63,7 @@ pub fn show(sys: &Arc<Mutex<Sys>>, p2pool_api: &Arc<Mutex<PubP2poolApi>>, xmrig_
|
||||||
})});
|
})});
|
||||||
// [P2Pool]
|
// [P2Pool]
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
|
debug!("Status Tab | Rendering [P2Pool]");
|
||||||
ui.set_enabled(p2pool_online);
|
ui.set_enabled(p2pool_online);
|
||||||
ui.set_min_height(min_height);
|
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())))).on_hover_text("P2Pool is online").on_disabled_hover_text("P2Pool is offline");
|
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");
|
||||||
|
@ -85,6 +88,7 @@ pub fn show(sys: &Arc<Mutex<Sys>>, p2pool_api: &Arc<Mutex<PubP2poolApi>>, xmrig_
|
||||||
})});
|
})});
|
||||||
// [XMRig]
|
// [XMRig]
|
||||||
ui.group(|ui| { ui.vertical(|ui| {
|
ui.group(|ui| { ui.vertical(|ui| {
|
||||||
|
debug!("Status Tab | Rendering [XMRig]");
|
||||||
ui.set_enabled(xmrig_online);
|
ui.set_enabled(xmrig_online);
|
||||||
ui.set_min_height(min_height);
|
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())))).on_hover_text("XMRig is online").on_disabled_hover_text("XMRig is offline");
|
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");
|
||||||
|
|
16
src/xmrig.rs
16
src/xmrig.rs
|
@ -36,6 +36,7 @@ impl Xmrig {
|
||||||
pub fn show(&mut self, pool_vec: &mut Vec<(String, Pool)>, regex: &Regexes, process: &Arc<Mutex<Process>>, api: &Arc<Mutex<PubXmrigApi>>, buffer: &mut String, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, pool_vec: &mut Vec<(String, Pool)>, regex: &Regexes, process: &Arc<Mutex<Process>>, api: &Arc<Mutex<PubXmrigApi>>, buffer: &mut String, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let text_edit = height / 25.0;
|
let text_edit = height / 25.0;
|
||||||
//---------------------------------------------------------------------------------------------------- [Simple] Console
|
//---------------------------------------------------------------------------------------------------- [Simple] Console
|
||||||
|
debug!("XMRig Tab | Rendering [Console]");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
if self.simple {
|
if self.simple {
|
||||||
let height = height / 1.5;
|
let height = height / 1.5;
|
||||||
|
@ -70,8 +71,9 @@ impl Xmrig {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Config
|
//---------------------------------------------------------------------------------------------------- Arguments
|
||||||
if !self.simple {
|
if !self.simple {
|
||||||
|
debug!("XMRig Tab | Rendering [Arguments]");
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
let width = (width/10.0) - SPACE;
|
let width = (width/10.0) - SPACE;
|
||||||
ui.style_mut().override_text_style = Some(Monospace);
|
ui.style_mut().override_text_style = Some(Monospace);
|
||||||
|
@ -81,6 +83,7 @@ impl Xmrig {
|
||||||
})});
|
})});
|
||||||
ui.set_enabled(self.arguments.is_empty());
|
ui.set_enabled(self.arguments.is_empty());
|
||||||
//---------------------------------------------------------------------------------------------------- Address
|
//---------------------------------------------------------------------------------------------------- Address
|
||||||
|
debug!("XMRig Tab | Rendering [Address]");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = width - SPACE;
|
let width = width - SPACE;
|
||||||
ui.spacing_mut().text_edit_width = (width)-(SPACE*3.0);
|
ui.spacing_mut().text_edit_width = (width)-(SPACE*3.0);
|
||||||
|
@ -106,6 +109,7 @@ impl Xmrig {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Threads
|
//---------------------------------------------------------------------------------------------------- Threads
|
||||||
if self.simple { ui.add_space(SPACE); }
|
if self.simple { ui.add_space(SPACE); }
|
||||||
|
debug!("XMRig Tab | Rendering [Threads]");
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
let width = width/10.0;
|
let width = width/10.0;
|
||||||
ui.spacing_mut().icon_width = width / 25.0;
|
ui.spacing_mut().icon_width = width / 25.0;
|
||||||
|
@ -129,7 +133,8 @@ impl Xmrig {
|
||||||
|
|
||||||
// });
|
// });
|
||||||
} else {
|
} else {
|
||||||
let _height = height / 10.0;
|
debug!("XMRig Tab | Rendering [Pool List] elements");
|
||||||
|
// let _height = height / 10.0;
|
||||||
let width = ui.available_width() - 10.0;
|
let width = ui.available_width() - 10.0;
|
||||||
let mut incorrect_input = false; // This will disable [Add/Delete] on bad input
|
let mut incorrect_input = false; // This will disable [Add/Delete] on bad input
|
||||||
// [Pool IP/Port]
|
// [Pool IP/Port]
|
||||||
|
@ -226,7 +231,8 @@ impl Xmrig {
|
||||||
// [Manual node selection]
|
// [Manual node selection]
|
||||||
ui.spacing_mut().slider_width = width - 8.0;
|
ui.spacing_mut().slider_width = width - 8.0;
|
||||||
ui.spacing_mut().icon_width = width / 25.0;
|
ui.spacing_mut().icon_width = width / 25.0;
|
||||||
// [Ping List]
|
// [Node List]
|
||||||
|
debug!("XMRig Tab | Rendering [Node List] ComboBox");
|
||||||
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
|
let text = RichText::new(format!("{}. {}", self.selected_index+1, self.selected_name));
|
||||||
ComboBox::from_id_source("manual_pool").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
ComboBox::from_id_source("manual_pool").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
|
@ -345,7 +351,8 @@ impl Xmrig {
|
||||||
});
|
});
|
||||||
ui.add_space(5.0);
|
ui.add_space(5.0);
|
||||||
|
|
||||||
// [HTTP API IP/Port] + [TLS + Keepalive]
|
debug!("XMRig Tab | Rendering [API] TextEdits");
|
||||||
|
// [HTTP API IP/Port]
|
||||||
ui.group(|ui| { ui.horizontal(|ui| {
|
ui.group(|ui| { ui.horizontal(|ui| {
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
let width = width/10.0;
|
let width = width/10.0;
|
||||||
|
@ -396,6 +403,7 @@ impl Xmrig {
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
|
debug!("XMRig Tab | Rendering [TLS/Keepalive] buttons");
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
// TLS/Keepalive
|
// TLS/Keepalive
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
|
Loading…
Reference in a new issue