feat: add deadlock detection at CI
Some checks are pending
CI / ci (macos-12) (push) Waiting to run
CI / ci (ubuntu-latest) (push) Waiting to run
Lockbud / lockbud (push) Waiting to run
Rust / fmt (push) Waiting to run
Rust / test (macos-latest) (push) Waiting to run
Rust / test (ubuntu-latest) (push) Waiting to run
Rust / typo (push) Waiting to run
Rust / clippy (macos-latest) (push) Waiting to run
Rust / clippy (ubuntu-latest) (push) Waiting to run
Rust / check (macos-latest) (push) Waiting to run
Rust / check (ubuntu-latest) (push) Waiting to run
Rust / doc (macos-latest) (push) Waiting to run
Rust / doc (ubuntu-latest) (push) Waiting to run
Typo / typo (push) Waiting to run

add [lockbud](https://github.com/BurtonQin/lockbud.git) for detection
**somes** deadlocks.

Need to remove the macros lock since lockbud would not be able to give
the right location with it.

The following command was used on the source code to reduce manual
modifications.
`
fd "*.rs" src/| xargs -I {} sd 'lock!\(([^\)]*)\)'
'$1.lock().unwrap()'{}
`
This commit is contained in:
Cyrix126 2024-10-10 16:42:27 +02:00
parent ee3fcce0d8
commit 5230d46d93
36 changed files with 756 additions and 710 deletions

25
.github/workflows/lockbud.yml vendored Normal file
View file

@ -0,0 +1,25 @@
name: Lockbud
on: push
jobs:
test:
name: lockbud
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Generate code coverage
run: |
git clone https://github.com/BurtonQin/lockbud.git
cd lockbud
cargo install --path .
cd ..
cargo clean
cargo lockbud -k deadlock -l gupaxx &> >(tee log.out)
if grep -q "WARN" log.out; then
echo "Lockbud warnings found:"
echo "$output"
exit 1
fi

View file

@ -1,4 +1,4 @@
[toolchain] [toolchain]
channel = "nightly-2024-07-24" channel = "nightly-2024-10-05"
components = [ "rustfmt", "rustc-dev", "cargo", "clippy", "rust-analyzer"] components = [ "rustfmt", "rustc-dev", "cargo", "clippy", "rust-analyzer", "rust-src", "llvm-tools-preview"]
target = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-apple-darwin","x86_64-pc-windows-gnu"] target = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-apple-darwin","x86_64-pc-windows-gnu"]

View file

@ -4,7 +4,6 @@ use crate::errors::{process_running, ErrorButtons, ErrorFerris};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use crate::helper::ProcessName; use crate::helper::ProcessName;
use crate::helper::ProcessState; use crate::helper::ProcessState;
use crate::macros::lock;
use crate::SECOND; use crate::SECOND;
use egui::CentralPanel; use egui::CentralPanel;
use log::debug; use log::debug;
@ -29,31 +28,31 @@ impl eframe::App for App {
// might as well check only once here to save // might as well check only once here to save
// on a bunch of [.lock().unwrap()]s. // on a bunch of [.lock().unwrap()]s.
debug!("App | Locking and collecting P2Pool state..."); debug!("App | Locking and collecting P2Pool state...");
let p2pool = lock!(self.p2pool); let p2pool = self.p2pool.lock().unwrap();
let p2pool_is_alive = p2pool.is_alive(); let p2pool_is_alive = p2pool.is_alive();
let p2pool_is_waiting = p2pool.is_waiting(); let p2pool_is_waiting = p2pool.is_waiting();
let p2pool_state = p2pool.state; let p2pool_state = p2pool.state;
drop(p2pool); drop(p2pool);
debug!("App | Locking and collecting XMRig state..."); debug!("App | Locking and collecting XMRig state...");
let xmrig = lock!(self.xmrig); let xmrig = self.xmrig.lock().unwrap();
let xmrig_is_alive = xmrig.is_alive(); let xmrig_is_alive = xmrig.is_alive();
let xmrig_is_waiting = xmrig.is_waiting(); let xmrig_is_waiting = xmrig.is_waiting();
let xmrig_state = xmrig.state; let xmrig_state = xmrig.state;
drop(xmrig); drop(xmrig);
debug!("App | Locking and collecting XMRig-Proxy state..."); debug!("App | Locking and collecting XMRig-Proxy state...");
let xmrig_proxy = lock!(self.xmrig_proxy); let xmrig_proxy = self.xmrig_proxy.lock().unwrap();
let xmrig_proxy_is_alive = xmrig_proxy.is_alive(); let xmrig_proxy_is_alive = xmrig_proxy.is_alive();
let xmrig_proxy_is_waiting = xmrig_proxy.is_waiting(); let xmrig_proxy_is_waiting = xmrig_proxy.is_waiting();
let xmrig_proxy_state = xmrig_proxy.state; let xmrig_proxy_state = xmrig_proxy.state;
drop(xmrig_proxy); drop(xmrig_proxy);
debug!("App | Locking and collecting XvB state..."); debug!("App | Locking and collecting XvB state...");
let xvb = lock!(self.xvb); let xvb = self.xvb.lock().unwrap();
let xvb_is_alive = xvb.is_alive(); let xvb_is_alive = xvb.is_alive();
let xvb_is_waiting = xvb.is_waiting(); let xvb_is_waiting = xvb.is_waiting();
let xvb_state = xvb.state; let xvb_state = xvb.state;
drop(xvb); drop(xvb);
debug!("App | Locking and collecting Node state..."); debug!("App | Locking and collecting Node state...");
let node = lock!(self.node); let node = self.node.lock().unwrap();
let node_is_alive = node.is_alive(); let node_is_alive = node.is_alive();
let node_is_waiting = node.is_waiting(); let node_is_waiting = node.is_waiting();
let node_state = node.state; let node_state = node.state;
@ -94,7 +93,7 @@ impl eframe::App for App {
// 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]"); debug!("App | Checking diff between [og] & [state]");
let og = lock!(self.og); let og = self.og.lock().unwrap();
self.diff = og.status != self.state.status self.diff = og.status != self.state.status
|| og.gupax != self.state.gupax || og.gupax != self.state.gupax
|| og.node != self.state.node || og.node != self.state.node

View file

@ -33,7 +33,6 @@ use crate::miscs::get_exe;
use crate::miscs::get_exe_dir; use crate::miscs::get_exe_dir;
use crate::utils::constants::VISUALS; use crate::utils::constants::VISUALS;
use crate::utils::macros::arc_mut; use crate::utils::macros::arc_mut;
use crate::utils::macros::lock;
use crate::utils::sudo::SudoState; use crate::utils::sudo::SudoState;
use crate::APP_DEFAULT_HEIGHT; use crate::APP_DEFAULT_HEIGHT;
use crate::APP_DEFAULT_WIDTH; use crate::APP_DEFAULT_WIDTH;
@ -371,7 +370,10 @@ impl App {
app.pool_path.push(POOL_TOML); app.pool_path.push(POOL_TOML);
// Set GupaxP2poolApi path // Set GupaxP2poolApi path
app.gupax_p2pool_api_path = crate::disk::get_gupax_p2pool_path(&app.os_data_path); app.gupax_p2pool_api_path = crate::disk::get_gupax_p2pool_path(&app.os_data_path);
lock!(app.gupax_p2pool_api).fill_paths(&app.gupax_p2pool_api_path); app.gupax_p2pool_api
.lock()
.unwrap()
.fill_paths(&app.gupax_p2pool_api_path);
// 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
@ -453,7 +455,7 @@ impl App {
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Read [GupaxP2poolApi] disk files // Read [GupaxP2poolApi] disk files
let mut gupax_p2pool_api = lock!(app.gupax_p2pool_api); let mut gupax_p2pool_api = app.gupax_p2pool_api.lock().unwrap();
match GupaxP2poolApi::create_all_files(&app.gupax_p2pool_api_path) { match GupaxP2poolApi::create_all_files(&app.gupax_p2pool_api_path) {
Ok(_) => info!("App Init | Creating Gupax-P2Pool API files ... OK"), Ok(_) => info!("App Init | Creating Gupax-P2Pool API files ... OK"),
Err(err) => { Err(err) => {
@ -493,10 +495,10 @@ impl App {
} }
}; };
drop(gupax_p2pool_api); drop(gupax_p2pool_api);
lock!(app.helper).gupax_p2pool_api = Arc::clone(&app.gupax_p2pool_api); app.helper.lock().unwrap().gupax_p2pool_api = Arc::clone(&app.gupax_p2pool_api);
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
let mut og = lock!(app.og); // Lock [og] let mut og = app.og.lock().unwrap(); // Lock [og]
// Handle max threads // Handle max threads
info!("App Init | Handling max thread overflow..."); info!("App Init | Handling max thread overflow...");
og.xmrig.max_threads = app.max_threads; og.xmrig.max_threads = app.max_threads;
@ -585,8 +587,8 @@ impl App {
// Set state version as compiled in version // Set state version as compiled in version
info!("App Init | Setting state Gupax version..."); info!("App Init | Setting state Gupax version...");
lock!(og.version).gupax = GUPAX_VERSION.to_string(); og.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
lock!(app.state.version).gupax = GUPAX_VERSION.to_string(); app.state.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
// Set saved [Tab] // Set saved [Tab]
info!("App Init | Setting saved [Tab]..."); info!("App Init | Setting saved [Tab]...");
@ -660,7 +662,7 @@ impl App {
// Realistically, most of them are, but we can't be sure, // Realistically, most of them are, but we can't be sure,
// and checking here without explicitly asking the user // and checking here without explicitly asking the user
// to connect to nodes is a no-go (also, non-async environment). // to connect to nodes is a no-go (also, non-async environment).
if !lock!(self.ping).pinged { if !self.ping.lock().unwrap().pinged {
warn!("Backup hosts ... simple node backup: no ping data available, returning None"); warn!("Backup hosts ... simple node backup: no ping data available, returning None");
return None; return None;
} }
@ -670,7 +672,7 @@ impl App {
// Locking during this entire loop should be fine, // Locking during this entire loop should be fine,
// only a few nodes to iter through. // only a few nodes to iter through.
for pinged_node in lock!(self.ping).nodes.iter() { for pinged_node in self.ping.lock().unwrap().nodes.iter() {
// Continue if this node is not green/yellow. // Continue if this node is not green/yellow.
if pinged_node.ms > crate::components::node::RED_NODE_PING { if pinged_node.ms > crate::components::node::RED_NODE_PING {
continue; continue;

View file

@ -9,7 +9,6 @@ use crate::errors::process_running;
use crate::helper::{Helper, ProcessSignal, ProcessState}; use crate::helper::{Helper, ProcessSignal, ProcessState};
use crate::utils::constants::*; use crate::utils::constants::*;
use crate::utils::errors::{ErrorButtons, ErrorFerris}; use crate::utils::errors::{ErrorButtons, ErrorFerris};
use crate::utils::macros::lock;
use crate::utils::regex::Regexes; use crate::utils::regex::Regexes;
use egui::TextStyle::Name; use egui::TextStyle::Name;
use egui::*; use egui::*;
@ -52,7 +51,7 @@ impl crate::app::App {
let size = vec2(0.0, height); let size = vec2(0.0, height);
// [Gupax Version] // [Gupax Version]
// Is yellow if the user updated and should (but isn't required to) restart. // Is yellow if the user updated and should (but isn't required to) restart.
match *lock!(self.restart) { match *self.restart.lock().unwrap() {
Restart::Yes => ui Restart::Yes => ui
.add_sized( .add_sized(
size, size,
@ -174,7 +173,7 @@ impl crate::app::App {
.on_hover_text("Reset changes") .on_hover_text("Reset changes")
.clicked() .clicked()
{ {
let og = lock!(self.og).clone(); let og = self.og.lock().unwrap().clone();
self.state.status = og.status; self.state.status = og.status;
self.state.gupax = og.gupax; self.state.gupax = og.gupax;
self.state.node = og.node; self.state.node = og.node;
@ -193,7 +192,7 @@ impl crate::app::App {
{ {
match State::save(&mut self.state, &self.state_path) { match State::save(&mut self.state, &self.state_path) {
Ok(_) => { Ok(_) => {
let mut og = lock!(self.og); let mut og = self.og.lock().unwrap();
og.status = self.state.status.clone(); og.status = self.state.status.clone();
og.gupax = self.state.gupax.clone(); og.gupax = self.state.gupax.clone();
og.node = self.state.node.clone(); og.node = self.state.node.clone();
@ -380,7 +379,7 @@ impl crate::app::App {
.on_hover_text("Restart P2Pool") .on_hover_text("Restart P2Pool")
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::restart_p2pool( Helper::restart_p2pool(
&self.helper, &self.helper,
@ -435,7 +434,7 @@ impl crate::app::App {
.on_disabled_hover_text(text) .on_disabled_hover_text(text)
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::start_p2pool( Helper::start_p2pool(
&self.helper, &self.helper,
@ -476,7 +475,7 @@ impl crate::app::App {
.on_hover_text("Restart node") .on_hover_text("Restart node")
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::restart_node( Helper::restart_node(
&self.helper, &self.helper,
@ -525,7 +524,7 @@ impl crate::app::App {
.on_disabled_hover_text(text) .on_disabled_hover_text(text)
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::start_node( Helper::start_node(
&self.helper, &self.helper,
@ -619,7 +618,7 @@ impl crate::app::App {
.on_hover_text("Restart XMRig") .on_hover_text("Restart XMRig")
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
if cfg!(windows) { if cfg!(windows) {
Helper::restart_xmrig( Helper::restart_xmrig(
@ -629,7 +628,7 @@ impl crate::app::App {
Arc::clone(&self.sudo), Arc::clone(&self.sudo),
); );
} else { } else {
lock!(self.sudo).signal = ProcessSignal::Restart; self.sudo.lock().unwrap().signal = ProcessSignal::Restart;
self.error_state.ask_sudo(&self.sudo); self.error_state.ask_sudo(&self.sudo);
} }
} }
@ -640,7 +639,7 @@ impl crate::app::App {
.clicked() .clicked()
{ {
if cfg!(target_os = "macos") { if cfg!(target_os = "macos") {
lock!(self.sudo).signal = ProcessSignal::Stop; self.sudo.lock().unwrap().signal = ProcessSignal::Stop;
self.error_state.ask_sudo(&self.sudo); self.error_state.ask_sudo(&self.sudo);
} else { } else {
Helper::stop_xmrig(&self.helper); Helper::stop_xmrig(&self.helper);
@ -679,7 +678,7 @@ impl crate::app::App {
.on_disabled_hover_text(text) .on_disabled_hover_text(text)
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
if cfg!(windows) { if cfg!(windows) {
Helper::start_xmrig( Helper::start_xmrig(
@ -689,7 +688,7 @@ impl crate::app::App {
Arc::clone(&self.sudo), Arc::clone(&self.sudo),
); );
} else if cfg!(unix) { } else if cfg!(unix) {
lock!(self.sudo).signal = ProcessSignal::Start; self.sudo.lock().unwrap().signal = ProcessSignal::Start;
self.error_state.ask_sudo(&self.sudo); self.error_state.ask_sudo(&self.sudo);
} }
} }
@ -829,7 +828,7 @@ impl crate::app::App {
.on_hover_text("Restart XMRig-Proxy") .on_hover_text("Restart XMRig-Proxy")
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::restart_xp( Helper::restart_xp(
&self.helper, &self.helper,
@ -881,7 +880,7 @@ impl crate::app::App {
.on_disabled_hover_text(text) .on_disabled_hover_text(text)
.clicked() .clicked()
{ {
let _ = lock!(self.og).update_absolute_path(); let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path(); let _ = self.state.update_absolute_path();
Helper::start_xp( Helper::start_xp(
&self.helper, &self.helper,

View file

@ -4,7 +4,6 @@ use crate::app::Restart;
use crate::components::gupax::*; use crate::components::gupax::*;
use crate::components::update::Update; use crate::components::update::Update;
use crate::disk::state::*; use crate::disk::state::*;
use crate::macros::lock2;
use log::debug; use log::debug;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
@ -40,7 +39,7 @@ impl Gupax {
size.y / 10.0 size.y / 10.0
}; };
let width = size.x - SPACE; let width = size.x - SPACE;
let updating = *lock2!(update, updating); let updating = *update.lock().unwrap().updating.lock().unwrap();
ui.vertical(|ui| { ui.vertical(|ui| {
// If [Gupax] is being built for a Linux distro, // If [Gupax] is being built for a Linux distro,
// disable built-in updating completely. // disable built-in updating completely.
@ -50,7 +49,7 @@ impl Gupax {
ui.add_sized([width, button], Button::new("Updates are disabled")) ui.add_sized([width, button], Button::new("Updates are disabled"))
.on_disabled_hover_text(DISTRO_NO_UPDATE); .on_disabled_hover_text(DISTRO_NO_UPDATE);
#[cfg(not(feature = "distro"))] #[cfg(not(feature = "distro"))]
ui.add_enabled_ui(!updating && *lock!(restart) == Restart::No, |ui| { ui.add_enabled_ui(!updating && *restart.lock().unwrap() == Restart::No, |ui| {
#[cfg(not(feature = "distro"))] #[cfg(not(feature = "distro"))]
if ui if ui
.add_sized([width, button], Button::new("Check for updates")) .add_sized([width, button], Button::new("Check for updates"))
@ -70,8 +69,13 @@ impl Gupax {
}); });
ui.vertical(|ui| { ui.vertical(|ui| {
ui.add_enabled_ui(updating, |ui| { ui.add_enabled_ui(updating, |ui| {
let prog = *lock2!(update, prog); let prog = *update.lock().unwrap().prog.lock().unwrap();
let msg = format!("{}\n{}{}", *lock2!(update, msg), prog, "%"); let msg = format!(
"{}\n{}{}",
*update.lock().unwrap().msg.lock().unwrap(),
prog,
"%"
);
ui.add_sized([width, height * 1.4], Label::new(RichText::new(msg))); ui.add_sized([width, height * 1.4], Label::new(RichText::new(msg)));
let height = height / 2.0; let height = height / 2.0;
let size = vec2(width, height); let size = vec2(width, height);
@ -80,7 +84,12 @@ impl Gupax {
} else { } else {
ui.add_sized(size, Label::new("...")); ui.add_sized(size, Label::new("..."));
} }
ui.add_sized(size, ProgressBar::new(lock2!(update, prog).round() / 100.0)); ui.add_sized(
size,
ProgressBar::new(
update.lock().unwrap().prog.lock().unwrap().round() / 100.0,
),
);
}); });
}); });
}); });
@ -140,7 +149,7 @@ impl Gupax {
debug!("Gupaxx Tab | Rendering P2Pool/XMRig path selection"); debug!("Gupaxx Tab | Rendering P2Pool/XMRig path selection");
// P2Pool/XMRig binary path selection // P2Pool/XMRig binary path selection
// need to clone bool so file_window is not locked across a thread // need to clone bool so file_window is not locked across a thread
let window_busy = lock!(file_window).thread.to_owned(); let window_busy = file_window.lock().unwrap().thread.to_owned();
let height = size.y / 28.0; let height = size.y / 28.0;
let text_edit = (ui.available_width() / 10.0) - SPACE; let text_edit = (ui.available_width() / 10.0) - SPACE;
ui.group(|ui| { ui.group(|ui| {
@ -309,7 +318,7 @@ impl Gupax {
}); });
}); });
}); });
let mut guard = lock!(file_window); let mut guard = file_window.lock().unwrap();
if guard.picked_p2pool { if guard.picked_p2pool {
self.p2pool_path.clone_from(&guard.p2pool_path); self.p2pool_path.clone_from(&guard.p2pool_path);
guard.picked_p2pool = false; guard.picked_p2pool = false;

View file

@ -3,7 +3,6 @@ use crate::app::Tab;
use crate::helper::ProcessState; use crate::helper::ProcessState;
use crate::utils::constants::*; use crate::utils::constants::*;
use crate::utils::errors::{ErrorButtons, ErrorFerris}; use crate::utils::errors::{ErrorButtons, ErrorFerris};
use crate::utils::macros::lock;
use egui::*; use egui::*;
use log::debug; use log::debug;
@ -44,10 +43,10 @@ impl crate::app::App {
let distro = true; let distro = true;
#[cfg(not(feature = "distro"))] #[cfg(not(feature = "distro"))]
let distro = false; let distro = false;
let p2pool_gui_len = lock!(self.p2pool_api).output.len(); let p2pool_gui_len = self.p2pool_api.lock().unwrap().output.len();
let xmrig_gui_len = lock!(self.xmrig_api).output.len(); let xmrig_gui_len = self.xmrig_api.lock().unwrap().output.len();
let xmrig_proxy_gui_len = lock!(self.xmrig_proxy_api).output.len(); let xmrig_proxy_gui_len = self.xmrig_proxy_api.lock().unwrap().output.len();
let gupax_p2pool_api = lock!(self.gupax_p2pool_api); let gupax_p2pool_api = self.gupax_p2pool_api.lock().unwrap();
let debug_info = format!( let debug_info = format!(
"Gupax version: {}\n "Gupax version: {}\n
Bundled P2Pool version: {}\n Bundled P2Pool version: {}\n
@ -118,8 +117,8 @@ path_xmr: {:#?}\n
p2pool_gui_len, p2pool_gui_len,
xmrig_gui_len, xmrig_gui_len,
xmrig_proxy_gui_len, xmrig_proxy_gui_len,
lock!(self.p2pool_img), self.p2pool_img.lock().unwrap(),
lock!(self.xmrig_img), self.xmrig_img.lock().unwrap(),
gupax_p2pool_api.payout, gupax_p2pool_api.payout,
gupax_p2pool_api.payout_u64, gupax_p2pool_api.payout_u64,
gupax_p2pool_api.xmr, gupax_p2pool_api.xmr,
@ -127,7 +126,7 @@ path_xmr: {:#?}\n
gupax_p2pool_api.path_payout, gupax_p2pool_api.path_payout,
gupax_p2pool_api.path_xmr, gupax_p2pool_api.path_xmr,
self.state, self.state,
lock!(self.og), self.og.lock().unwrap(),
); );
self.error_state.set(debug_info, ErrorFerris::Cute, ErrorButtons::Debug); self.error_state.set(debug_info, ErrorFerris::Cute, ErrorButtons::Debug);
} }
@ -153,7 +152,7 @@ path_xmr: {:#?}\n
ui.add_space(SPACE*2.0); ui.add_space(SPACE*2.0);
if cfg!(debug_assertions) { ui.label(format!("Gupax is running in debug mode - {}", self.now.elapsed().as_secs_f64())); } if cfg!(debug_assertions) { ui.label(format!("Gupax is running in debug mode - {}", self.now.elapsed().as_secs_f64())); }
ui.label(format!("Gupax has been running for {}", lock!(self.pub_sys).gupax_uptime)); ui.label(format!("Gupax has been running for {}", self.pub_sys.lock().unwrap().gupax_uptime));
}); });
} }
Tab::Status => { Tab::Status => {
@ -182,7 +181,7 @@ path_xmr: {:#?}\n
} }
Tab::Xvb => { Tab::Xvb => {
debug!("App | Entering [XvB] Tab"); debug!("App | Entering [XvB] Tab");
crate::disk::state::Xvb::show(&mut self.state.xvb, self.size, &self.state.p2pool.address, ctx, ui, &self.xvb_api, &self.xmrig_api, lock!(self.xvb).state == ProcessState::Alive); crate::disk::state::Xvb::show(&mut self.state.xvb, self.size, &self.state.p2pool.address, ctx, ui, &self.xvb_api, &self.xmrig_api, self.xvb.lock().unwrap().state == ProcessState::Alive);
} }
} }
}); });

View file

@ -16,7 +16,6 @@ use crate::helper::node::PubNodeApi;
use crate::helper::Process; use crate::helper::Process;
use crate::regex::{num_lines, REGEXES}; use crate::regex::{num_lines, REGEXES};
use crate::utils::constants::DARK_GRAY; use crate::utils::constants::DARK_GRAY;
use crate::utils::macros::lock;
use crate::{GREEN, LIGHT_GRAY, P2POOL_IN, P2POOL_LOG, P2POOL_OUT, RED, SPACE}; use crate::{GREEN, LIGHT_GRAY, P2POOL_IN, P2POOL_LOG, P2POOL_OUT, RED, SPACE};
impl Node { impl Node {
@ -47,7 +46,7 @@ impl Node {
// console output for log // console output for log
debug!("Node Tab | Rendering [Console]"); debug!("Node Tab | Rendering [Console]");
ui.group(|ui| { ui.group(|ui| {
let text = &lock!(api).output; let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text); let nb_lines = num_lines(text);
let height = size.y / 2.8; let height = size.y / 2.8;
let width = size.x - (space_h / 2.0); let width = size.x - (space_h / 2.0);
@ -89,7 +88,7 @@ impl Node {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) { if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock let mut process = process.lock().unwrap(); // Lock
if process.is_alive() { if process.is_alive() {
process.input.push(buffer); process.input.push(buffer);
} // Push only if alive } // Push only if alive
@ -326,7 +325,7 @@ fn path_db_field(
); );
ui.spacing_mut().text_edit_width = ui.spacing_mut().text_edit_width =
ui.available_width() - (ui.spacing().item_spacing.x * 8.0) - SPACE * 2.0; ui.available_width() - (ui.spacing().item_spacing.x * 8.0) - SPACE * 2.0;
let window_busy = lock!(file_window).thread; let window_busy = file_window.lock().unwrap().thread;
ui.add_enabled_ui(!window_busy, |ui| { ui.add_enabled_ui(!window_busy, |ui| {
if ui.button("Open").on_hover_text(GUPAX_SELECT).clicked() { if ui.button("Open").on_hover_text(GUPAX_SELECT).clicked() {
Gupax::spawn_file_window_thread(file_window, FileType::NodeDB); Gupax::spawn_file_window_thread(file_window, FileType::NodeDB);
@ -336,7 +335,7 @@ fn path_db_field(
}); });
}); });
let mut guard = lock!(file_window); let mut guard = file_window.lock().unwrap();
if guard.picked_nodedb { if guard.picked_nodedb {
state.path_db.clone_from(&guard.nodedb_path); state.path_db.clone_from(&guard.nodedb_path);
guard.picked_nodedb = false; guard.picked_nodedb = false;

View file

@ -18,7 +18,7 @@ use crate::regex::num_lines;
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{components::node::*, constants::*, helper::*, macros::*, utils::regex::Regexes}; use crate::{components::node::*, constants::*, helper::*, utils::regex::Regexes};
use egui::{ use egui::{
vec2, Color32, Label, RichText, TextEdit, vec2, Color32, Label, RichText, TextEdit,
TextStyle::{self, *}, TextStyle::{self, *},
@ -53,7 +53,7 @@ impl P2pool {
// debug!("P2Pool Tab | Rendering [Console]"); // debug!("P2Pool Tab | Rendering [Console]");
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
ui.group(|ui| { ui.group(|ui| {
let text = &lock!(api).output; let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text); let nb_lines = num_lines(text);
let (height, width) = if self.simple { let (height, width) = if self.simple {
((size.y * 0.38) - SPACE, size.x - SPACE) ((size.y * 0.38) - SPACE, size.x - SPACE)
@ -104,7 +104,7 @@ impl P2pool {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) { if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock let mut process = process.lock().unwrap(); // Lock
if process.is_alive() { if process.is_alive() {
process.input.push(buffer); process.input.push(buffer);
} // Push only if alive } // Push only if alive

View file

@ -9,7 +9,6 @@ use crate::components::node::format_ms;
use crate::components::node::Ping; use crate::components::node::Ping;
use crate::components::node::RemoteNode; use crate::components::node::RemoteNode;
use crate::disk::state::P2pool; use crate::disk::state::P2pool;
use crate::utils::macros::lock;
use egui::vec2; use egui::vec2;
use egui::Button; use egui::Button;
use egui::Checkbox; use egui::Checkbox;
@ -47,7 +46,7 @@ impl P2pool {
let visible = !self.local_node; let visible = !self.local_node;
debug!("P2Pool Tab | Running [auto-select] check"); debug!("P2Pool Tab | Running [auto-select] check");
if self.auto_select && visible { if self.auto_select && visible {
let mut ping = lock!(ping); 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
if ping.pinged && !ping.auto_selected { if ping.pinged && !ping.auto_selected {
self.node = ping.fastest.to_string(); self.node = ping.fastest.to_string();
@ -63,8 +62,8 @@ impl P2pool {
// [Ping List] // [Ping List]
let mut ms = 0; let mut ms = 0;
let mut color = Color32::LIGHT_GRAY; let mut color = Color32::LIGHT_GRAY;
if lock!(ping).pinged { if ping.lock().unwrap().pinged {
for data in lock!(ping).nodes.iter() { for data in ping.lock().unwrap().nodes.iter() {
if data.ip == self.node { if data.ip == self.node {
ms = data.ms; ms = data.ms;
color = data.color; color = data.color;
@ -79,7 +78,7 @@ impl P2pool {
.selected_text(text) .selected_text(text)
.width(size.x) .width(size.x)
.show_ui(ui, |ui| { .show_ui(ui, |ui| {
for data in lock!(ping).nodes.iter() { for data in ping.lock().unwrap().nodes.iter() {
let ms = format_ms(data.ms); let ms = format_ms(data.ms);
let ip_location = format_ip_location(data.ip, true); let ip_location = format_ip_location(data.ip, true);
let text = RichText::new(format!("{} | {}", ms, ip_location)) let text = RichText::new(format!("{} | {}", ms, ip_location))
@ -108,12 +107,12 @@ impl P2pool {
.add_sized(size, Button::new("Select fastest node")) .add_sized(size, Button::new("Select fastest node"))
.on_hover_text(P2POOL_SELECT_FASTEST) .on_hover_text(P2POOL_SELECT_FASTEST)
.clicked() .clicked()
&& lock!(ping).pinged && ping.lock().unwrap().pinged
{ {
self.node = lock!(ping).fastest.to_string(); self.node = ping.lock().unwrap().fastest.to_string();
} }
// [Ping Button] // [Ping Button]
ui.add_enabled_ui(!lock!(ping).pinging, |ui| { ui.add_enabled_ui(!ping.lock().unwrap().pinging, |ui| {
if ui if ui
.add_sized(size, Button::new("Ping remote nodes")) .add_sized(size, Button::new("Ping remote nodes"))
.on_hover_text(P2POOL_PING) .on_hover_text(P2POOL_PING)
@ -128,7 +127,7 @@ impl P2pool {
.on_hover_text(P2POOL_SELECT_LAST) .on_hover_text(P2POOL_SELECT_LAST)
.clicked() .clicked()
{ {
let ping = lock!(ping); let ping = ping.lock().unwrap();
match ping.pinged { match ping.pinged {
true => { true => {
self.node = RemoteNode::get_last_from_ping(&self.node, &ping.nodes) self.node = RemoteNode::get_last_from_ping(&self.node, &ping.nodes)
@ -143,7 +142,7 @@ impl P2pool {
.on_hover_text(P2POOL_SELECT_NEXT) .on_hover_text(P2POOL_SELECT_NEXT)
.clicked() .clicked()
{ {
let ping = lock!(ping); let ping = ping.lock().unwrap();
match ping.pinged { match ping.pinged {
true => { true => {
self.node = RemoteNode::get_next_from_ping(&self.node, &ping.nodes) self.node = RemoteNode::get_next_from_ping(&self.node, &ping.nodes)
@ -156,10 +155,11 @@ impl P2pool {
ui.vertical(|ui| { ui.vertical(|ui| {
let height = height / 2.0; let height = height / 2.0;
let pinging = lock!(ping).pinging; let pinging = ping.lock().unwrap().pinging;
ui.add_enabled_ui(pinging, |ui| { ui.add_enabled_ui(pinging, |ui| {
let prog = lock!(ping).prog.round(); let prog = ping.lock().unwrap().prog.round();
let msg = RichText::new(format!("{} ... {}%", lock!(ping).msg, prog)); let msg =
RichText::new(format!("{} ... {}%", ping.lock().unwrap().msg, prog));
let height = height / 1.25; let height = height / 1.25;
let size = vec2(size.x, height); let size = vec2(size.x, height);
ui.add_space(space_h); ui.add_space(space_h);

View file

@ -5,8 +5,6 @@ use egui::{Hyperlink, ProgressBar, ScrollArea, Spinner, Vec2};
use egui_extras::{Column, TableBuilder}; use egui_extras::{Column, TableBuilder};
use readable::num::{Float, Percent, Unsigned}; use readable::num::{Float, Percent, Unsigned};
use crate::utils::macros::lock;
use crate::constants::*; use crate::constants::*;
use egui::{Label, RichText}; use egui::{Label, RichText};
use log::*; use log::*;
@ -93,7 +91,7 @@ impl Status {
// User's CPU hashrate comparison (if XMRig is alive). // User's CPU hashrate comparison (if XMRig is alive).
ui.scope(|ui| { ui.scope(|ui| {
if xmrig_alive { if xmrig_alive {
let api = lock!(xmrig_api); let api = xmrig_api.lock().unwrap();
let percent = (api.hashrate_raw / cpu.high) * 100.0; let percent = (api.hashrate_raw / cpu.high) * 100.0;
let human = Percent::from(percent); let human = Percent::from(percent);
if percent > 100.0 { if percent > 100.0 {

View file

@ -10,7 +10,7 @@ use crate::{
status::{Hash, PayoutView}, status::{Hash, PayoutView},
}, },
helper::p2pool::PubP2poolApi, helper::p2pool::PubP2poolApi,
utils::{constants::*, macros::lock}, utils::constants::*,
}; };
impl Status { impl Status {
@ -22,7 +22,7 @@ impl Status {
p2pool_alive: bool, p2pool_alive: bool,
p2pool_api: &Arc<Mutex<PubP2poolApi>>, p2pool_api: &Arc<Mutex<PubP2poolApi>>,
) { ) {
let api = lock!(gupax_p2pool_api); let api = gupax_p2pool_api.lock().unwrap();
let height = size.y; let height = size.y;
let width = size.x; let width = size.x;
let text = height / 25.0; let text = height / 25.0;
@ -214,7 +214,7 @@ impl Status {
let text = height / 25.0; let text = height / 25.0;
let width = (width / 3.0) - (SPACE * 1.666); let width = (width / 3.0) - (SPACE * 1.666);
let min_height = ui.available_height() / 1.3; let min_height = ui.available_height() / 1.3;
let api = lock!(p2pool_api); let api = p2pool_api.lock().unwrap();
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.group(|ui| { ui.group(|ui| {
ui.vertical(|ui| { ui.vertical(|ui| {

View file

@ -9,7 +9,6 @@ use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi; use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::xvb::{rounds::XvbRound, PubXvbApi}; use crate::helper::xvb::{rounds::XvbRound, PubXvbApi};
use crate::helper::Sys; use crate::helper::Sys;
use crate::utils::macros::lock;
use egui::TextStyle; use egui::TextStyle;
use crate::constants::*; use crate::constants::*;
@ -91,7 +90,7 @@ fn gupax(ui: &mut Ui, min_size: Vec2, size: Vec2, sys: &Arc<Mutex<Sys>>) {
), ),
) )
.on_hover_text("Gupaxx is online"); .on_hover_text("Gupaxx is online");
let sys = lock!(sys); let sys = sys.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Uptime").underline().color(BONE)), Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -160,7 +159,7 @@ fn p2pool(
.on_disabled_hover_text("P2Pool is offline"); .on_disabled_hover_text("P2Pool is offline");
ui.style_mut().override_text_style = Some(Name("MonospaceSmall".into())); ui.style_mut().override_text_style = Some(Name("MonospaceSmall".into()));
let size = [size.x, size.y / 1.4]; let size = [size.x, size.y / 1.4];
let api = lock!(p2pool_api); let api = p2pool_api.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Uptime").underline().color(BONE)), Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -249,7 +248,7 @@ fn p2pool(
api.average_effort, api.current_effort api.average_effort, api.current_effort
)), )),
); );
let img = lock!(p2pool_img); let img = p2pool_img.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Monero Node").underline().color(BONE)), Label::new(RichText::new("Monero Node").underline().color(BONE)),
@ -305,7 +304,7 @@ fn xmrig_proxy(
) )
.on_hover_text("XMRig-Proxy is online") .on_hover_text("XMRig-Proxy is online")
.on_disabled_hover_text("XMRig-Proxy is offline"); .on_disabled_hover_text("XMRig-Proxy is offline");
let api = lock!(xmrig_proxy_api); let api = xmrig_proxy_api.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Uptime").underline().color(BONE)), Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -378,7 +377,7 @@ fn xmrig(
) )
.on_hover_text("XMRig is online") .on_hover_text("XMRig is online")
.on_disabled_hover_text("XMRig is offline"); .on_disabled_hover_text("XMRig is offline");
let api = lock!(xmrig_api); let api = xmrig_api.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Uptime").underline().color(BONE)), Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -427,7 +426,11 @@ fn xmrig(
.on_hover_text(STATUS_XMRIG_THREADS); .on_hover_text(STATUS_XMRIG_THREADS);
ui.add_sized( ui.add_sized(
size, size,
Label::new(format!("{}/{}", &lock!(xmrig_img).threads, max_threads)), Label::new(format!(
"{}/{}",
&xmrig_img.lock().unwrap().threads,
max_threads
)),
); );
drop(api); drop(api);
}); });
@ -438,7 +441,7 @@ fn xmrig(
fn xvb(ui: &mut Ui, min_size: Vec2, size: Vec2, xvb_alive: bool, xvb_api: &Arc<Mutex<PubXvbApi>>) { fn xvb(ui: &mut Ui, min_size: Vec2, size: Vec2, xvb_alive: bool, xvb_api: &Arc<Mutex<PubXvbApi>>) {
// //
let api = &lock!(xvb_api).stats_pub; let api = &xvb_api.lock().unwrap().stats_pub;
let enabled = xvb_alive; let enabled = xvb_alive;
ui.group(|ui| { ui.group(|ui| {
ScrollArea::vertical().show(ui, |ui| { ScrollArea::vertical().show(ui, |ui| {
@ -583,7 +586,7 @@ fn node(
) )
.on_hover_text("Node is online") .on_hover_text("Node is online")
.on_disabled_hover_text("Node is offline"); .on_disabled_hover_text("Node is offline");
let api = lock!(node_api); let api = node_api.lock().unwrap();
ui.add_sized( ui.add_sized(
size, size,
Label::new(RichText::new("Uptime").underline().color(BONE)), Label::new(RichText::new("Uptime").underline().color(BONE)),

View file

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::constants::*;
use crate::disk::pool::Pool; use crate::disk::pool::Pool;
use crate::disk::state::Xmrig; use crate::disk::state::Xmrig;
use crate::helper::xrig::xmrig::PubXmrigApi; use crate::helper::xrig::xmrig::PubXmrigApi;
use crate::helper::Process; use crate::helper::Process;
use crate::regex::{num_lines, REGEXES}; use crate::regex::{num_lines, REGEXES};
use crate::utils::regex::Regexes; use crate::utils::regex::Regexes;
use crate::{constants::*, macros::*};
use egui::{ use egui::{
vec2, Button, Checkbox, ComboBox, Label, RichText, SelectableLabel, Slider, TextEdit, vec2, Button, Checkbox, ComboBox, Label, RichText, SelectableLabel, Slider, TextEdit,
TextStyle::{self, *}, TextStyle::{self, *},
@ -49,7 +49,7 @@ impl Xmrig {
debug!("XMRig Tab | Rendering [Console]"); debug!("XMRig Tab | Rendering [Console]");
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
ui.group(|ui| { ui.group(|ui| {
let text = &lock!(api).output; let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text); let nb_lines = num_lines(text);
let (height, width) = if self.simple { let (height, width) = if self.simple {
(size.y / 1.5, size.x - SPACE) (size.y / 1.5, size.x - SPACE)
@ -93,7 +93,7 @@ impl Xmrig {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) { if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock let mut process = process.lock().unwrap(); // Lock
if process.is_alive() { if process.is_alive() {
process.input.push(buffer); process.input.push(buffer);
} // Push only if alive } // Push only if alive

View file

@ -10,7 +10,6 @@ use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::Process; use crate::helper::Process;
use crate::regex::{num_lines, REGEXES}; use crate::regex::{num_lines, REGEXES};
use crate::utils::constants::DARK_GRAY; use crate::utils::constants::DARK_GRAY;
use crate::utils::macros::lock;
use crate::{ use crate::{
GREEN, LIGHT_GRAY, LIST_ADD, LIST_CLEAR, LIST_DELETE, LIST_SAVE, RED, SPACE, XMRIG_API_IP, GREEN, LIGHT_GRAY, LIST_ADD, LIST_CLEAR, LIST_DELETE, LIST_SAVE, RED, SPACE, XMRIG_API_IP,
XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE, XMRIG_NAME, XMRIG_PORT, XMRIG_PROXY_ARGUMENTS, XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE, XMRIG_NAME, XMRIG_PORT, XMRIG_PROXY_ARGUMENTS,
@ -44,7 +43,7 @@ impl XmrigProxy {
// console output for log // console output for log
debug!("Xmrig-Proxy Tab | Rendering [Console]"); debug!("Xmrig-Proxy Tab | Rendering [Console]");
ui.group(|ui| { ui.group(|ui| {
let text = &lock!(api).output; let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text); let nb_lines = num_lines(text);
let height = size.y / 2.8; let height = size.y / 2.8;
let width = size.x - (space_h / 2.0); let width = size.x - (space_h / 2.0);
@ -86,7 +85,7 @@ impl XmrigProxy {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) { if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock let mut process = process.lock().unwrap(); // Lock
if process.is_alive() { if process.is_alive() {
process.input.push(buffer); process.input.push(buffer);
} // Push only if alive } // Push only if alive

View file

@ -20,7 +20,6 @@ use crate::utils::constants::{
XVB_MODE_MANUAL_P2POOL_HELP, XVB_MODE_MANUAL_XVB_HELP, XVB_ROUND_TYPE_FIELD, XVB_TOKEN_FIELD, XVB_MODE_MANUAL_P2POOL_HELP, XVB_MODE_MANUAL_XVB_HELP, XVB_ROUND_TYPE_FIELD, XVB_TOKEN_FIELD,
XVB_TOKEN_LEN, XVB_URL_RULES, XVB_WINNER_FIELD, XVB_TOKEN_LEN, XVB_URL_RULES, XVB_WINNER_FIELD,
}; };
use crate::utils::macros::lock;
use crate::utils::regex::Regexes; use crate::utils::regex::Regexes;
use crate::XVB_MINING_ON_FIELD; use crate::XVB_MINING_ON_FIELD;
use crate::{ use crate::{
@ -64,7 +63,7 @@ impl crate::disk::state::Xvb {
// console output for log // console output for log
debug!("XvB Tab | Rendering [Console]"); debug!("XvB Tab | Rendering [Console]");
ui.group(|ui| { ui.group(|ui| {
let text = &lock!(api).output; let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text); let nb_lines = num_lines(text);
let height = size.y / 2.8; let height = size.y / 2.8;
let width = size.x - (space_h / 2.0); let width = size.x - (space_h / 2.0);
@ -134,9 +133,9 @@ impl crate::disk::state::Xvb {
if ui.checkbox(&mut self.simple_hero_mode, "Hero Mode").on_hover_text(XVB_HERO_SELECT).clicked() { if ui.checkbox(&mut self.simple_hero_mode, "Hero Mode").on_hover_text(XVB_HERO_SELECT).clicked() {
// also change hero mode of runtime. // also change hero mode of runtime.
lock!(api).stats_priv.runtime_mode = RuntimeMode::Hero; api.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Hero;
} else { } else {
lock!(api).stats_priv.runtime_mode = RuntimeMode::Auto; api.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
} }
} }
@ -179,12 +178,12 @@ impl crate::disk::state::Xvb {
}; };
let mut hashrate_xmrig = { let mut hashrate_xmrig = {
if lock!(gui_api_xmrig).hashrate_raw_15m > 0.0 { if gui_api_xmrig.lock().unwrap().hashrate_raw_15m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_15m gui_api_xmrig.lock().unwrap().hashrate_raw_15m
} else if lock!(gui_api_xmrig).hashrate_raw_1m > 0.0 { } else if gui_api_xmrig.lock().unwrap().hashrate_raw_1m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_1m gui_api_xmrig.lock().unwrap().hashrate_raw_1m
} else if lock!(gui_api_xmrig).hashrate_raw > 0.0 { } else if gui_api_xmrig.lock().unwrap().hashrate_raw > 0.0 {
lock!(gui_api_xmrig).hashrate_raw gui_api_xmrig.lock().unwrap().hashrate_raw
} else { } else {
default_xmrig_hashrate default_xmrig_hashrate
} }
@ -243,7 +242,7 @@ impl crate::disk::state::Xvb {
ManualDonationLevel::DonorMega.to_string()) ManualDonationLevel::DonorMega.to_string())
.on_hover_text(XVB_DONATION_LEVEL_MEGA_DONOR_HELP); .on_hover_text(XVB_DONATION_LEVEL_MEGA_DONOR_HELP);
lock!(api).stats_priv.runtime_manual_donation_level = self.manual_donation_level.clone().into(); api.lock().unwrap().stats_priv.runtime_manual_donation_level = self.manual_donation_level.clone().into();
} }
}); });
}); });
@ -263,8 +262,8 @@ impl crate::disk::state::Xvb {
} }
// Set runtime_mode & runtime_manual_amount // Set runtime_mode & runtime_manual_amount
lock!(api).stats_priv.runtime_mode = self.mode.clone().into(); api.lock().unwrap().stats_priv.runtime_mode = self.mode.clone().into();
lock!(api).stats_priv.runtime_manual_amount = self.manual_amount_raw; api.lock().unwrap().stats_priv.runtime_manual_amount = self.manual_amount_raw;
ui.add_space(space_h); ui.add_space(space_h);
// allow user to modify the buffer for p2pool // allow user to modify the buffer for p2pool
@ -289,7 +288,7 @@ impl crate::disk::state::Xvb {
ui.add_space(space_h); ui.add_space(space_h);
// ui.add_enabled_ui(is_alive, |ui| { // ui.add_enabled_ui(is_alive, |ui| {
ui.add_enabled_ui(is_alive, |ui| { ui.add_enabled_ui(is_alive, |ui| {
let api = &lock!(api); let api = &api.lock().unwrap();
let priv_stats = &api.stats_priv; let priv_stats = &api.stats_priv;
let current_node = &api.current_node; let current_node = &api.current_node;
let width_stat = (ui.available_width() - SPACE * 4.0) / 5.0; let width_stat = (ui.available_width() - SPACE * 4.0) / 5.0;

View file

@ -6,7 +6,7 @@ use crate::disk::state::State;
use crate::utils::constants::*; use crate::utils::constants::*;
use crate::utils::errors::ErrorState; use crate::utils::errors::ErrorState;
use crate::utils::ferris::*; use crate::utils::ferris::*;
use crate::utils::macros::{arc_mut, flip, lock, lock2}; use crate::utils::macros::{arc_mut, flip};
use crate::utils::resets::{reset_nodes, reset_state}; use crate::utils::resets::{reset_nodes, reset_state};
use crate::utils::sudo::SudoState; use crate::utils::sudo::SudoState;
use egui::TextStyle::Name; use egui::TextStyle::Name;
@ -53,7 +53,7 @@ impl crate::app::App {
match self.error_state.buttons { match self.error_state.buttons {
StayQuit => { StayQuit => {
let mut text = "".to_string(); let mut text = "".to_string();
if *lock2!(self.update, updating) { if *self.update.lock().unwrap().updating.lock().unwrap() {
text = format!( text = format!(
"{}\nUpdate is in progress...! Quitting may cause file corruption!", "{}\nUpdate is in progress...! Quitting may cause file corruption!",
text text
@ -277,7 +277,7 @@ impl crate::app::App {
ErrorButtons::Sudo => { ErrorButtons::Sudo => {
let sudo_width = width / 10.0; let sudo_width = width / 10.0;
let height = ui.available_height() / 4.0; let height = ui.available_height() / 4.0;
let mut sudo = lock!(self.sudo); let mut sudo = self.sudo.lock().unwrap();
let hide = sudo.hide; let hide = sudo.hide;
if sudo.testing { if sudo.testing {
ui.add_sized([width, height], Spinner::new().size(height)); ui.add_sized([width, height], Spinner::new().size(height));

View file

@ -15,10 +15,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{ use crate::{disk::state::*, utils::macros::arc_mut};
disk::state::*,
utils::macros::{arc_mut, lock},
};
use log::*; use log::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
@ -111,7 +108,7 @@ impl Gupax {
NodeDB => "Node DB", NodeDB => "Node DB",
}; };
let file_window = file_window.clone(); let file_window = file_window.clone();
lock!(file_window).thread = true; file_window.lock().unwrap().thread = true;
thread::spawn(move || { thread::spawn(move || {
let path = match file_type { let path = match file_type {
NodeDB => rfd::FileDialog::new() NodeDB => rfd::FileDialog::new()
@ -125,31 +122,31 @@ impl Gupax {
info!("Gupaxx | Path selected for {} ... {}", name, path.display()); info!("Gupaxx | Path selected for {} ... {}", name, path.display());
match file_type { match file_type {
P2pool => { P2pool => {
lock!(file_window).p2pool_path = path.display().to_string(); file_window.lock().unwrap().p2pool_path = path.display().to_string();
lock!(file_window).picked_p2pool = true; file_window.lock().unwrap().picked_p2pool = true;
} }
Xmrig => { Xmrig => {
lock!(file_window).xmrig_path = path.display().to_string(); file_window.lock().unwrap().xmrig_path = path.display().to_string();
lock!(file_window).picked_xmrig = true; file_window.lock().unwrap().picked_xmrig = true;
} }
XmrigProxy => { XmrigProxy => {
lock!(file_window).xmrig_proxy_path = path.display().to_string(); file_window.lock().unwrap().xmrig_proxy_path = path.display().to_string();
lock!(file_window).picked_xp = true; file_window.lock().unwrap().picked_xp = true;
} }
Node => { Node => {
lock!(file_window).node_path = path.display().to_string(); file_window.lock().unwrap().node_path = path.display().to_string();
lock!(file_window).picked_node = true; file_window.lock().unwrap().picked_node = true;
} }
NodeDB => { NodeDB => {
lock!(file_window).nodedb_path = path.display().to_string(); file_window.lock().unwrap().nodedb_path = path.display().to_string();
lock!(file_window).picked_nodedb = true; file_window.lock().unwrap().picked_nodedb = true;
} }
}; };
} else { } else {
info!("Gupaxx | No path selected for {}", name); info!("Gupaxx | No path selected for {}", name);
} }
lock!(file_window).thread = false; file_window.lock().unwrap().thread = false;
}); });
} }
} }

View file

@ -331,19 +331,19 @@ impl Ping {
match Self::ping(&ping) { match Self::ping(&ping) {
Ok(msg) => { Ok(msg) => {
info!("Ping ... OK"); info!("Ping ... OK");
lock!(ping).msg = msg; ping.lock().unwrap().msg = msg;
lock!(ping).pinged = true; ping.lock().unwrap().pinged = true;
lock!(ping).auto_selected = false; ping.lock().unwrap().auto_selected = false;
lock!(ping).prog = 100.0; ping.lock().unwrap().prog = 100.0;
} }
Err(err) => { Err(err) => {
error!("Ping ... FAIL ... {}", err); error!("Ping ... FAIL ... {}", err);
lock!(ping).pinged = false; ping.lock().unwrap().pinged = false;
lock!(ping).msg = err.to_string(); ping.lock().unwrap().msg = err.to_string();
} }
} }
info!("Ping ... Took [{}] seconds...", now.elapsed().as_secs_f32()); info!("Ping ... Took [{}] seconds...", now.elapsed().as_secs_f32());
lock!(ping).pinging = false; ping.lock().unwrap().pinging = false;
}); });
} }
@ -370,13 +370,13 @@ impl Ping {
pub async fn ping(ping: &Arc<Mutex<Self>>) -> Result<String, anyhow::Error> { pub async fn ping(ping: &Arc<Mutex<Self>>) -> Result<String, anyhow::Error> {
// Start ping // Start ping
let ping = Arc::clone(ping); let ping = Arc::clone(ping);
lock!(ping).pinging = true; ping.lock().unwrap().pinging = true;
lock!(ping).prog = 0.0; ping.lock().unwrap().prog = 0.0;
let percent = (100.0 / (REMOTE_NODE_LENGTH as f32)).floor(); let percent = (100.0 / (REMOTE_NODE_LENGTH as f32)).floor();
// Create HTTP client // Create HTTP client
let info = "Creating HTTP Client".to_string(); let info = "Creating HTTP Client".to_string();
lock!(ping).msg = info; ping.lock().unwrap().msg = info;
let client = Client::new(); let client = Client::new();
// Random User Agent // Random User Agent
@ -404,13 +404,13 @@ impl Ping {
handle.await?; handle.await?;
} }
let mut node_vec = std::mem::take(&mut *lock!(node_vec)); let mut node_vec = std::mem::take(&mut *node_vec.lock().unwrap());
node_vec.sort_by(|a, b| a.ms.cmp(&b.ms)); node_vec.sort_by(|a, b| a.ms.cmp(&b.ms));
let fastest_info = format!("Fastest node: {}ms ... {}", node_vec[0].ms, node_vec[0].ip); let fastest_info = format!("Fastest node: {}ms ... {}", node_vec[0].ms, node_vec[0].ip);
let info = "Cleaning up connections".to_string(); let info = "Cleaning up connections".to_string();
info!("Ping | {}...", info); info!("Ping | {}...", info);
let mut ping = lock!(ping); let mut ping = ping.lock().unwrap();
ping.fastest = node_vec[0].ip; ping.fastest = node_vec[0].ip;
ping.nodes = node_vec; ping.nodes = node_vec;
ping.msg = info; ping.msg = info;
@ -467,11 +467,11 @@ impl Ping {
BLACK BLACK
}; };
let mut ping = lock!(ping); let mut ping = ping.lock().unwrap();
ping.msg = info; ping.msg = info;
ping.prog += percent; ping.prog += percent;
drop(ping); drop(ping);
lock!(node_vec).push(NodeData { ip, ms, color }); node_vec.lock().unwrap().push(NodeData { ip, ms, color });
} }
} }
//---------------------------------------------------------------------------------------------------- NODE //---------------------------------------------------------------------------------------------------- NODE

View file

@ -287,7 +287,7 @@ impl Update {
#[cfg(feature = "distro")] #[cfg(feature = "distro")]
return; return;
// verify validity of absolute path for p2pool, xmrig and xmrig-proxy only if we want to update them. // verify validity of absolute path for p2pool, xmrig and xmrig-proxy only if we want to update them.
if lock!(og).gupax.bundled { if og.lock().unwrap().gupax.bundled {
// Check P2Pool path for safety // Check P2Pool path for safety
// Attempt relative to absolute path // Attempt relative to absolute path
// it's ok if file doesn't exist. User could enable bundled version for the first time. // it's ok if file doesn't exist. User could enable bundled version for the first time.
@ -350,15 +350,15 @@ impl Update {
return; return;
} }
}; };
lock!(update).path_p2pool = p2pool_path.display().to_string(); update.lock().unwrap().path_p2pool = p2pool_path.display().to_string();
lock!(update).path_xmrig = xmrig_path.display().to_string(); update.lock().unwrap().path_xmrig = xmrig_path.display().to_string();
lock!(update).path_xp = xmrig_proxy_path.display().to_string(); update.lock().unwrap().path_xp = xmrig_proxy_path.display().to_string();
lock!(update).path_node = node_path.display().to_string(); update.lock().unwrap().path_node = node_path.display().to_string();
} }
// Clone before thread spawn // Clone before thread spawn
let og = Arc::clone(og); let og = Arc::clone(og);
let state_ver = Arc::clone(&lock!(og).version); let state_ver = Arc::clone(&og.lock().unwrap().version);
let state_path = state_path.to_path_buf(); let state_path = state_path.to_path_buf();
let update = Arc::clone(update); let update = Arc::clone(update);
let restart = Arc::clone(restart); let restart = Arc::clone(restart);
@ -367,24 +367,25 @@ impl Update {
match Update::start(update.clone(), og.clone(), restart) { match Update::start(update.clone(), og.clone(), restart) {
Ok(_) => { Ok(_) => {
info!("Update | Saving state..."); info!("Update | Saving state...");
let original_version = lock!(og).version.clone(); let original_version = og.lock().unwrap().version.clone();
lock!(og).version = state_ver; og.lock().unwrap().version = state_ver;
match State::save(&mut lock!(og), &state_path) { match State::save(&mut og.lock().unwrap(), &state_path) {
Ok(_) => info!("Update ... OK"), Ok(_) => info!("Update ... OK"),
Err(e) => { Err(e) => {
warn!("Update | Saving state ... FAIL: {}", e); warn!("Update | Saving state ... FAIL: {}", e);
lock!(og).version = original_version; og.lock().unwrap().version = original_version;
*lock2!(update, msg) = *update.lock().unwrap().msg.lock().unwrap() =
"Saving new versions into state failed".to_string(); "Saving new versions into state failed".to_string();
} }
}; };
} }
Err(e) => { Err(e) => {
info!("Update ... FAIL: {}", e); info!("Update ... FAIL: {}", e);
*lock2!(update, msg) = format!("{} | {}\n{}", MSG_FAILED, e, MSG_FAILED_HELP); *update.lock().unwrap().msg.lock().unwrap() =
format!("{} | {}\n{}", MSG_FAILED, e, MSG_FAILED_HELP);
} }
}; };
*lock2!(update, updating) = false; *update.lock().unwrap().updating.lock().unwrap() = false;
}); });
} }
@ -412,38 +413,41 @@ impl Update {
)); ));
//---------------------------------------------------------------------------------------------------- Init //---------------------------------------------------------------------------------------------------- Init
*lock2!(update, updating) = true; *update.lock().unwrap().updating.lock().unwrap() = true;
// Set timer // Set timer
let now = std::time::Instant::now(); let now = std::time::Instant::now();
// Set progress bar // Set progress bar
*lock2!(update, msg) = MSG_START.to_string(); *update.lock().unwrap().msg.lock().unwrap() = MSG_START.to_string();
*lock2!(update, prog) = 0.0; *update.lock().unwrap().prog.lock().unwrap() = 0.0;
info!("Update | {}", INIT); info!("Update | {}", INIT);
// Get temporary directory // Get temporary directory
let msg = MSG_TMP.to_string(); let msg = MSG_TMP.to_string();
info!("Update | {}", msg); info!("Update | {}", msg);
*lock2!(update, msg) = msg; *update.lock().unwrap().msg.lock().unwrap() = msg;
let tmp_dir = Self::get_tmp_dir()?; let tmp_dir = Self::get_tmp_dir()?;
std::fs::create_dir(&tmp_dir)?; std::fs::create_dir(&tmp_dir)?;
// Generate fake user-agent // Generate fake user-agent
let user_agent = get_user_agent(); let user_agent = get_user_agent();
*lock2!(update, prog) = 5.0; *update.lock().unwrap().prog.lock().unwrap() = 5.0;
// Create HTTPS client // Create HTTPS client
let lock = lock!(update); let lock = update.lock().unwrap();
let msg = MSG_HTTPS.to_string(); let msg = MSG_HTTPS.to_string();
info!("Update | {}", msg); info!("Update | {}", msg);
*lock!(lock.msg) = msg; *lock.msg.lock().unwrap() = msg;
drop(lock); drop(lock);
let client = Client::new(); let client = Client::new();
*lock2!(update, prog) += 5.0; *update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!("Update | Init ... OK ... {}%", lock2!(update, prog)); info!(
"Update | Init ... OK ... {}%",
update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Metadata //---------------------------------------------------------------------------------------------------- Metadata
*lock2!(update, msg) = MSG_METADATA.to_string(); *update.lock().unwrap().msg.lock().unwrap() = MSG_METADATA.to_string();
info!("Update | {}", METADATA); info!("Update | {}", METADATA);
// Loop process: // Loop process:
// reqwest will retry himself // reqwest will retry himself
@ -457,11 +461,11 @@ impl Update {
return Err(anyhow!("Metadata fetch failed")); return Err(anyhow!("Metadata fetch failed"));
}; };
*lock2!(update, prog) += 10.0; *update.lock().unwrap().prog.lock().unwrap() += 10.0;
info!("Update | Gupaxx {} ... OK", new_ver); info!("Update | Gupaxx {} ... OK", new_ver);
//---------------------------------------------------------------------------------------------------- Compare //---------------------------------------------------------------------------------------------------- Compare
*lock2!(update, msg) = MSG_COMPARE.to_string(); *update.lock().unwrap().msg.lock().unwrap() = MSG_COMPARE.to_string();
info!("Update | {}", COMPARE); info!("Update | {}", COMPARE);
let diff = GUPAX_VERSION != new_ver; let diff = GUPAX_VERSION != new_ver;
if diff { if diff {
@ -475,18 +479,21 @@ impl Update {
GUPAX_VERSION, new_ver GUPAX_VERSION, new_ver
); );
info!("Update | All packages up-to-date ... RETURNING"); info!("Update | All packages up-to-date ... RETURNING");
*lock2!(update, prog) = 100.0; *update.lock().unwrap().prog.lock().unwrap() = 100.0;
*lock2!(update, msg) = MSG_UP_TO_DATE.to_string(); *update.lock().unwrap().msg.lock().unwrap() = MSG_UP_TO_DATE.to_string();
return Ok(()); return Ok(());
} }
*lock2!(update, prog) += 5.0; *update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!("Update | Compare ... OK ... {}%", lock2!(update, prog)); info!(
"Update | Compare ... OK ... {}%",
update.lock().unwrap().prog.lock().unwrap()
);
// Return if 0 (all packages up-to-date) // Return if 0 (all packages up-to-date)
// Get amount of packages to divide up the percentage increases // Get amount of packages to divide up the percentage increases
//---------------------------------------------------------------------------------------------------- Download //---------------------------------------------------------------------------------------------------- Download
*lock2!(update, msg) = format!("{} Gupaxx", MSG_DOWNLOAD); *update.lock().unwrap().msg.lock().unwrap() = format!("{} Gupaxx", MSG_DOWNLOAD);
info!("Update | {}", DOWNLOAD); info!("Update | {}", DOWNLOAD);
// Clone data before async // Clone data before async
let version = new_ver; let version = new_ver;
@ -500,7 +507,7 @@ impl Update {
// arch // arch
// standalone or bundled // standalone or bundled
// archive extension // archive extension
let bundle = if lock!(og).gupax.bundled { let bundle = if og.lock().unwrap().gupax.bundled {
"bundle" "bundle"
} else { } else {
"standalone" "standalone"
@ -527,12 +534,15 @@ impl Update {
error!("Update | Download ... FAIL"); error!("Update | Download ... FAIL");
return Err(anyhow!("Download failed")); return Err(anyhow!("Download failed"));
}; };
*lock2!(update, prog) += 30.0; *update.lock().unwrap().prog.lock().unwrap() += 30.0;
info!("Update | Gupaxx ... OK"); info!("Update | Gupaxx ... OK");
info!("Update | Download ... OK ... {}%", *lock2!(update, prog)); info!(
"Update | Download ... OK ... {}%",
*update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Extract //---------------------------------------------------------------------------------------------------- Extract
*lock2!(update, msg) = format!("{} Gupaxx", MSG_EXTRACT); *update.lock().unwrap().msg.lock().unwrap() = format!("{} Gupaxx", MSG_EXTRACT);
info!("Update | {}", EXTRACT); info!("Update | {}", EXTRACT);
let tmp = tmp_dir.to_owned(); let tmp = tmp_dir.to_owned();
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -542,9 +552,12 @@ impl Update {
)?; )?;
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
tar::Archive::new(flate2::read::GzDecoder::new(bytes.as_ref())).unpack(tmp)?; tar::Archive::new(flate2::read::GzDecoder::new(bytes.as_ref())).unpack(tmp)?;
*lock2!(update, prog) += 5.0; *update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!("Update | Gupaxx ... OK"); info!("Update | Gupaxx ... OK");
info!("Update | Extract ... OK ... {}%", *lock2!(update, prog)); info!(
"Update | Extract ... OK ... {}%",
*update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Upgrade //---------------------------------------------------------------------------------------------------- Upgrade
// if bundled, directories p2pool, xmrig and xmrig-proxy will exist. // if bundled, directories p2pool, xmrig and xmrig-proxy will exist.
@ -553,7 +566,7 @@ impl Update {
// //
// 3. Rename tmp path into current path // 3. Rename tmp path into current path
// 4. Update [State/Version] // 4. Update [State/Version]
*lock2!(update, msg) = format!("Gupaxx {}", MSG_UPGRADE); *update.lock().unwrap().msg.lock().unwrap() = format!("Gupaxx {}", MSG_UPGRADE);
info!("Update | {}", UPGRADE); info!("Update | {}", UPGRADE);
// If this bool doesn't get set, something has gone wrong because // If this bool doesn't get set, something has gone wrong because
// we _didn't_ find a binary even though we downloaded it. // we _didn't_ find a binary even though we downloaded it.
@ -569,11 +582,11 @@ impl Update {
.to_str() .to_str()
.ok_or_else(|| anyhow!("WalkDir basename failed"))?; .ok_or_else(|| anyhow!("WalkDir basename failed"))?;
let path = match name { let path = match name {
GUPAX_BINARY => lock!(update).path_gupax.clone(), GUPAX_BINARY => update.lock().unwrap().path_gupax.clone(),
P2POOL_BINARY => lock!(update).path_p2pool.clone(), P2POOL_BINARY => update.lock().unwrap().path_p2pool.clone(),
XMRIG_BINARY => lock!(update).path_xmrig.clone(), XMRIG_BINARY => update.lock().unwrap().path_xmrig.clone(),
XMRIG_PROXY_BINARY => lock!(update).path_xp.clone(), XMRIG_PROXY_BINARY => update.lock().unwrap().path_xp.clone(),
NODE_BINARY => lock!(update).path_node.clone(), NODE_BINARY => update.lock().unwrap().path_node.clone(),
_ => continue, _ => continue,
}; };
found = true; found = true;
@ -606,7 +619,7 @@ impl Update {
path.display() path.display()
); );
// if bundled, create directory for p2pool, xmrig and xmrig-proxy if not present // if bundled, create directory for p2pool, xmrig and xmrig-proxy if not present
if lock!(og).gupax.bundled if og.lock().unwrap().gupax.bundled
&& (name == P2POOL_BINARY && (name == P2POOL_BINARY
|| name == XMRIG_BINARY || name == XMRIG_BINARY
|| name == XMRIG_PROXY_BINARY || name == XMRIG_PROXY_BINARY
@ -620,8 +633,8 @@ impl Update {
// Move downloaded path into old path // Move downloaded path into old path
std::fs::rename(entry.path(), path)?; std::fs::rename(entry.path(), path)?;
// If we're updating Gupax, set the [Restart] state so that the user knows to restart // If we're updating Gupax, set the [Restart] state so that the user knows to restart
*lock!(restart) = Restart::Yes; *restart.lock().unwrap() = Restart::Yes;
*lock2!(update, prog) += 5.0; *update.lock().unwrap().prog.lock().unwrap() += 5.0;
} }
if !found { if !found {
return Err(anyhow!("Fatal error: Package binary could not be found")); return Err(anyhow!("Fatal error: Package binary could not be found"));
@ -635,11 +648,11 @@ impl Update {
let seconds = now.elapsed().as_secs(); let seconds = now.elapsed().as_secs();
info!("Update | Seconds elapsed ... [{}s]", seconds); info!("Update | Seconds elapsed ... [{}s]", seconds);
*lock2!(update, msg) = format!( *update.lock().unwrap().msg.lock().unwrap() = format!(
"Updated from {} to {}\nYou need to restart Gupaxx.", "Updated from {} to {}\nYou need to restart Gupaxx.",
GUPAX_VERSION, version GUPAX_VERSION, version
); );
*lock2!(update, prog) = 100.0; *update.lock().unwrap().prog.lock().unwrap() = 100.0;
Ok(()) Ok(())
} }
} }

View file

@ -26,7 +26,7 @@
// found here, e.g: User clicks [Stop P2Pool] -> Arc<Mutex<ProcessSignal> is set // found here, e.g: User clicks [Stop P2Pool] -> Arc<Mutex<ProcessSignal> is set
// indicating to this thread during its loop: "I should stop P2Pool!", e.g: // indicating to this thread during its loop: "I should stop P2Pool!", e.g:
// //
// if lock!(p2pool).signal == ProcessSignal::Stop { // if p2pool.lock().unwrap().signal == ProcessSignal::Stop {
// stop_p2pool(), // stop_p2pool(),
// } // }
// //
@ -430,7 +430,7 @@ impl Helper {
// order as the main GUI thread (top to bottom). // order as the main GUI thread (top to bottom).
let helper = Arc::clone(helper); let helper = Arc::clone(helper);
let lock = lock!(helper); let lock = helper.lock().unwrap();
let node = Arc::clone(&lock.node); let node = Arc::clone(&lock.node);
let p2pool = Arc::clone(&lock.p2pool); let p2pool = Arc::clone(&lock.p2pool);
let xmrig = Arc::clone(&lock.xmrig); let xmrig = Arc::clone(&lock.xmrig);
@ -465,39 +465,39 @@ impl Helper {
// down the culprit of an [Arc<Mutex>] deadlock. I know, they're ugly. // down the culprit of an [Arc<Mutex>] deadlock. I know, they're ugly.
// 2. Lock... EVERYTHING! // 2. Lock... EVERYTHING!
let mut lock = lock!(helper); let mut lock = helper.lock().unwrap();
debug!("Helper | Locking (1/15) ... [helper]"); debug!("Helper | Locking (1/15) ... [helper]");
let node = lock!(node); let node = node.lock().unwrap();
debug!("Helper | Locking (2/15) ... [helper]"); debug!("Helper | Locking (2/15) ... [helper]");
let p2pool = lock!(p2pool); let p2pool = p2pool.lock().unwrap();
debug!("Helper | Locking (3/15) ... [p2pool]"); debug!("Helper | Locking (3/15) ... [p2pool]");
let xmrig = lock!(xmrig); let xmrig = xmrig.lock().unwrap();
debug!("Helper | Locking (4/15) ... [xmrig]"); debug!("Helper | Locking (4/15) ... [xmrig]");
let xmrig_proxy = lock!(xmrig_proxy); let xmrig_proxy = xmrig_proxy.lock().unwrap();
debug!("Helper | Locking (5/15) ... [xmrig_proxy]"); debug!("Helper | Locking (5/15) ... [xmrig_proxy]");
let xvb = lock!(xvb); let xvb = xvb.lock().unwrap();
debug!("Helper | Locking (6/15) ... [xvb]"); debug!("Helper | Locking (6/15) ... [xvb]");
let mut lock_pub_sys = lock!(pub_sys); let mut lock_pub_sys = pub_sys.lock().unwrap();
debug!("Helper | Locking (8/15) ... [gui_api_node]"); debug!("Helper | Locking (8/15) ... [gui_api_node]");
let mut gui_api_node = lock!(gui_api_node); let mut gui_api_node = gui_api_node.lock().unwrap();
debug!("Helper | Locking (7/15) ... [pub_sys]"); debug!("Helper | Locking (7/15) ... [pub_sys]");
let mut gui_api_p2pool = lock!(gui_api_p2pool); let mut gui_api_p2pool = gui_api_p2pool.lock().unwrap();
debug!("Helper | Locking (8/15) ... [gui_api_p2pool]"); debug!("Helper | Locking (8/15) ... [gui_api_p2pool]");
let mut gui_api_xmrig = lock!(gui_api_xmrig); let mut gui_api_xmrig = gui_api_xmrig.lock().unwrap();
debug!("Helper | Locking (9/15) ... [gui_api_xmrig]"); debug!("Helper | Locking (9/15) ... [gui_api_xmrig]");
let mut gui_api_xp = lock!(gui_api_xp); let mut gui_api_xp = gui_api_xp.lock().unwrap();
debug!("Helper | Locking (10/15) ... [gui_api_xp]"); debug!("Helper | Locking (10/15) ... [gui_api_xp]");
let mut gui_api_xvb = lock!(gui_api_xvb); let mut gui_api_xvb = gui_api_xvb.lock().unwrap();
debug!("Helper | Locking (11/15) ... [gui_api_xvb]"); debug!("Helper | Locking (11/15) ... [gui_api_xvb]");
let mut pub_api_node = lock!(pub_api_node); let mut pub_api_node = pub_api_node.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_node]"); debug!("Helper | Locking (14/15) ... [pub_api_node]");
let mut pub_api_p2pool = lock!(pub_api_p2pool); let mut pub_api_p2pool = pub_api_p2pool.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_p2pool]"); debug!("Helper | Locking (14/15) ... [pub_api_p2pool]");
let mut pub_api_xmrig = lock!(pub_api_xmrig); let mut pub_api_xmrig = pub_api_xmrig.lock().unwrap();
debug!("Helper | Locking (13/15) ... [pub_api_xmrig]"); debug!("Helper | Locking (13/15) ... [pub_api_xmrig]");
let mut pub_api_xp = lock!(pub_api_xp); let mut pub_api_xp = pub_api_xp.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_xp]"); debug!("Helper | Locking (14/15) ... [pub_api_xp]");
let mut pub_api_xvb = lock!(pub_api_xvb); let mut pub_api_xvb = pub_api_xvb.lock().unwrap();
debug!("Helper | Locking (15/15) ... [pub_api_xvb]"); debug!("Helper | Locking (15/15) ... [pub_api_xvb]");
// 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());
@ -619,7 +619,7 @@ fn check_died(
gui_api_output_raw: &mut String, gui_api_output_raw: &mut String,
) -> bool { ) -> bool {
// Check if the process secretly died without us knowing :) // Check if the process secretly died without us knowing :)
if let Ok(Some(code)) = lock!(child_pty).try_wait() { if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
debug!( debug!(
"{} Watchdog | Process secretly died on us! Getting exit status...", "{} Watchdog | Process secretly died on us! Getting exit status...",
process.name process.name
@ -659,7 +659,7 @@ fn check_died(
false false
} }
fn check_user_input(process: &Arc<Mutex<Process>>, stdin: &mut Box<dyn std::io::Write + Send>) { fn check_user_input(process: &Arc<Mutex<Process>>, stdin: &mut Box<dyn std::io::Write + Send>) {
let mut lock = lock!(process); let mut lock = process.lock().unwrap();
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 {
@ -691,32 +691,32 @@ fn signal_end(
start: &Instant, start: &Instant,
gui_api_output_raw: &mut String, gui_api_output_raw: &mut String,
) -> bool { ) -> bool {
if lock!(process).signal == ProcessSignal::Stop { if process.lock().unwrap().signal == ProcessSignal::Stop {
debug!("{} Watchdog | Stop SIGNAL caught", lock!(process).name); debug!("{} Watchdog | Stop SIGNAL caught", process.lock().unwrap().name);
// This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool) // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
if let Err(e) = lock!(child_pty).kill() { if let Err(e) = child_pty.lock().unwrap().kill() {
error!("{} Watchdog | Kill error: {}", lock!(process).name, e); error!("{} Watchdog | Kill error: {}", process.lock().unwrap().name, e);
} }
// Wait to get the exit status // Wait to get the exit status
let exit_status = match lock!(child_pty).wait() { let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => { Ok(e) => {
if e.success() { if e.success() {
lock!(process).state = ProcessState::Dead; process.lock().unwrap().state = ProcessState::Dead;
"Successful" "Successful"
} else { } else {
lock!(process).state = ProcessState::Failed; process.lock().unwrap().state = ProcessState::Failed;
"Failed" "Failed"
} }
} }
_ => { _ => {
lock!(process).state = ProcessState::Failed; process.lock().unwrap().state = ProcessState::Failed;
"Unknown Error" "Unknown Error"
} }
}; };
let uptime = HumanTime::into_human(start.elapsed()); let uptime = HumanTime::into_human(start.elapsed());
info!( info!(
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]", "{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
lock!(process).name, process.lock().unwrap().name,
uptime, uptime,
exit_status exit_status
); );
@ -724,7 +724,7 @@ fn signal_end(
if let Err(e) = writeln!( if let Err(e) = writeln!(
gui_api_output_raw, gui_api_output_raw,
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", "{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
lock!(process).name, process.lock().unwrap().name,
HORI_CONSOLE, HORI_CONSOLE,
uptime, uptime,
exit_status, exit_status,
@ -732,25 +732,25 @@ fn signal_end(
) { ) {
error!( error!(
"{} Watchdog | GUI Uptime/Exit status write failed: {}", "{} Watchdog | GUI Uptime/Exit status write failed: {}",
lock!(process).name, process.lock().unwrap().name,
e e
); );
} }
lock!(process).signal = ProcessSignal::None; process.lock().unwrap().signal = ProcessSignal::None;
debug!( debug!(
"{} Watchdog | Stop SIGNAL done, breaking", "{} Watchdog | Stop SIGNAL done, breaking",
lock!(process).name, process.lock().unwrap().name,
); );
return true; return true;
// Check RESTART // Check RESTART
} else if lock!(process).signal == ProcessSignal::Restart { } else if process.lock().unwrap().signal == ProcessSignal::Restart {
debug!("{} Watchdog | Restart SIGNAL caught", lock!(process).name,); debug!("{} Watchdog | Restart SIGNAL caught", process.lock().unwrap().name,);
// This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool) // This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
if let Err(e) = lock!(child_pty).kill() { if let Err(e) = child_pty.lock().unwrap().kill() {
error!("{} Watchdog | Kill error: {}", lock!(process).name, e); error!("{} Watchdog | Kill error: {}", process.lock().unwrap().name, e);
} }
// Wait to get the exit status // Wait to get the exit status
let exit_status = match lock!(child_pty).wait() { let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => { Ok(e) => {
if e.success() { if e.success() {
"Successful" "Successful"
@ -763,7 +763,7 @@ fn signal_end(
let uptime = HumanTime::into_human(start.elapsed()); let uptime = HumanTime::into_human(start.elapsed());
info!( info!(
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]", "{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
lock!(process).name, process.lock().unwrap().name,
uptime, uptime,
exit_status exit_status
); );
@ -771,7 +771,7 @@ fn signal_end(
if let Err(e) = writeln!( if let Err(e) = writeln!(
gui_api_output_raw, gui_api_output_raw,
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n", "{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
lock!(process).name, process.lock().unwrap().name,
HORI_CONSOLE, HORI_CONSOLE,
uptime, uptime,
exit_status, exit_status,
@ -779,14 +779,14 @@ fn signal_end(
) { ) {
error!( error!(
"{} Watchdog | GUI Uptime/Exit status write failed: {}", "{} Watchdog | GUI Uptime/Exit status write failed: {}",
lock!(process).name, process.lock().unwrap().name,
e e
); );
} }
lock!(process).state = ProcessState::Waiting; process.lock().unwrap().state = ProcessState::Waiting;
debug!( debug!(
"{} Watchdog | Restart SIGNAL done, breaking", "{} Watchdog | Restart SIGNAL done, breaking",
lock!(process).name, process.lock().unwrap().name,
); );
return true; return true;
} }

View file

@ -18,11 +18,11 @@ use crate::{
check_died, check_user_input, signal_end, sleep_end_loop, ProcessName, ProcessSignal, check_died, check_user_input, signal_end, sleep_end_loop, ProcessName, ProcessSignal,
ProcessState, ProcessState,
}, },
macros::{arc_mut, lock2, sleep}, macros::{arc_mut, sleep},
}; };
use std::fmt::Write; use std::fmt::Write;
use super::{lock, Helper, HumanNumber, HumanTime, Process}; use super::{Helper, HumanNumber, HumanTime, Process};
impl Helper { impl Helper {
#[cold] #[cold]
@ -38,18 +38,18 @@ impl Helper {
// Run a ANSI escape sequence filter. // Run a ANSI escape sequence filter.
while let Some(Ok(line)) = stdout.next() { while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line); let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("Node PTY Parse | Output error: {}", e); error!("Node PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("Node PTY Pub | Output error: {}", e); error!("Node PTY Pub | Output error: {}", e);
} }
} }
while let Some(Ok(line)) = stdout.next() { while let Some(Ok(line)) = stdout.next() {
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e); error!("P2Pool PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e); error!("P2Pool PTY Pub | Output error: {}", e);
} }
} }
@ -121,12 +121,12 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on. // Just sets some signals for the watchdog thread to pick up on.
pub fn stop_node(helper: &Arc<Mutex<Self>>) { pub fn stop_node(helper: &Arc<Mutex<Self>>) {
info!("Node | Attempting to stop..."); info!("Node | Attempting to stop...");
lock2!(helper, node).signal = ProcessSignal::Stop; helper.lock().unwrap().node.lock().unwrap().signal = ProcessSignal::Stop;
lock2!(helper, node).state = ProcessState::Middle; helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let gui_api = Arc::clone(&lock!(helper).gui_api_node); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_node);
let pub_api = Arc::clone(&lock!(helper).pub_api_node); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_node);
*lock!(pub_api) = PubNodeApi::new(); *pub_api.lock().unwrap() = PubNodeApi::new();
*lock!(gui_api) = PubNodeApi::new(); *gui_api.lock().unwrap() = PubNodeApi::new();
} }
#[cold] #[cold]
#[inline(never)] #[inline(never)]
@ -134,15 +134,15 @@ impl Helper {
// Basically calls to kill the current p2pool, waits a little, then starts the below function in a a new thread, then exit. // Basically calls to kill the current p2pool, waits a little, then starts the below function in a a new thread, then exit.
pub fn restart_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) { pub fn restart_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) {
info!("Node | Attempting to restart..."); info!("Node | Attempting to restart...");
lock2!(helper, node).signal = ProcessSignal::Restart; helper.lock().unwrap().node.lock().unwrap().signal = ProcessSignal::Restart;
lock2!(helper, node).state = ProcessState::Middle; helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper); let helper = Arc::clone(helper);
let state = state.clone(); let state = state.clone();
let path = path.to_path_buf(); let path = path.to_path_buf();
// This thread lives to wait, start p2pool then die. // This thread lives to wait, start p2pool then die.
thread::spawn(move || { thread::spawn(move || {
while lock2!(helper, node).state != ProcessState::Waiting { while helper.lock().unwrap().node.lock().unwrap().state != ProcessState::Waiting {
warn!("Node | Want to restart but process is still alive, waiting..."); warn!("Node | Want to restart but process is still alive, waiting...");
sleep!(1000); sleep!(1000);
} }
@ -156,7 +156,7 @@ impl Helper {
#[inline(never)] #[inline(never)]
// The "frontend" function that parses the arguments, and spawns either the [Simple] or [Advanced] Node watchdog thread. // The "frontend" function that parses the arguments, and spawns either the [Simple] or [Advanced] Node watchdog thread.
pub fn start_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) { pub fn start_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) {
lock2!(helper, node).state = ProcessState::Middle; helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_node_args(state); let args = Self::build_node_args(state);
@ -164,9 +164,9 @@ impl Helper {
crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args)); crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args));
// Spawn watchdog thread // Spawn watchdog thread
let process = Arc::clone(&lock!(helper).node); let process = Arc::clone(&helper.lock().unwrap().node);
let gui_api = Arc::clone(&lock!(helper).gui_api_node); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_node);
let pub_api = Arc::clone(&lock!(helper).pub_api_node); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_node);
let path = path.to_path_buf(); let path = path.to_path_buf();
let state = state.clone(); let state = state.clone();
thread::spawn(move || { thread::spawn(move || {
@ -184,7 +184,7 @@ impl Helper {
path: std::path::PathBuf, path: std::path::PathBuf,
state: Node, state: Node,
) { ) {
lock!(process).start = Instant::now(); process.lock().unwrap().start = Instant::now();
// spawn pty // spawn pty
debug!("Node | Creating PTY..."); debug!("Node | Creating PTY...");
let pty = portable_pty::native_pty_system(); let pty = portable_pty::native_pty_system();
@ -199,8 +199,8 @@ impl Helper {
// 4. Spawn PTY read thread // 4. Spawn PTY read thread
debug!("Node | Spawning PTY read thread..."); debug!("Node | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enc!((output_parse, output_pub) async move { spawn(enc!((output_parse, output_pub) async move {
Self::read_pty_node(output_parse, output_pub, reader); Self::read_pty_node(output_parse, output_pub, reader);
})); }));
@ -216,13 +216,13 @@ impl Helper {
let mut stdin = pair.master.take_writer().unwrap(); let mut stdin = pair.master.take_writer().unwrap();
// set state // set state
let client = Client::new(); let client = Client::new();
lock!(process).state = ProcessState::Syncing; process.lock().unwrap().state = ProcessState::Syncing;
lock!(process).signal = ProcessSignal::None; process.lock().unwrap().signal = ProcessSignal::None;
// reset stats // reset stats
*lock!(pub_api) = PubNodeApi::new(); *pub_api.lock().unwrap() = PubNodeApi::new();
*lock!(gui_api) = PubNodeApi::new(); *gui_api.lock().unwrap() = PubNodeApi::new();
// loop // loop
let start = lock!(process).start; let start = process.lock().unwrap().start;
info!("Node | Entering watchdog mode... woof!"); info!("Node | Entering watchdog mode... woof!");
loop { loop {
let now = Instant::now(); let now = Instant::now();
@ -231,14 +231,19 @@ impl Helper {
// check state // check state
if check_died( if check_died(
&child_pty, &child_pty,
&mut lock!(process), &mut process.lock().unwrap(),
&start, &start,
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
) { ) {
break; break;
} }
// check signal // check signal
if signal_end(process, &child_pty, &start, &mut lock!(gui_api).output) { if signal_end(
process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break; break;
} }
// check user input // check user input
@ -248,7 +253,7 @@ impl Helper {
// Check if logs need resetting // Check if logs need resetting
debug!("Node Watchdog | Attempting GUI log reset check"); debug!("Node Watchdog | Attempting GUI log reset check");
{ {
let mut lock = lock!(gui_api); let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::Node); Self::check_reset_gui_output(&mut lock.output, ProcessName::Node);
} }
// No need to check output since monerod has a sufficient API // No need to check output since monerod has a sufficient API
@ -261,7 +266,7 @@ impl Helper {
Ok(priv_api) => { Ok(priv_api) => {
debug!("Node Watchdog | HTTP API request OK, attempting [update_from_priv()]"); debug!("Node Watchdog | HTTP API request OK, attempting [update_from_priv()]");
if priv_api.result.synchronized && priv_api.result.status == "OK" { if priv_api.result.synchronized && priv_api.result.status == "OK" {
lock!(process).state = ProcessState::Alive process.lock().unwrap().state = ProcessState::Alive
} }
PubNodeApi::update_from_priv(pub_api, priv_api); PubNodeApi::update_from_priv(pub_api, priv_api);
} }
@ -332,7 +337,7 @@ impl PubNodeApi {
} }
} }
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivNodeApi) { fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivNodeApi) {
let mut public = lock!(public); let mut public = public.lock().unwrap();
*public = Self { *public = Self {
blockheight: HumanNumber::from_u64(private.result.height), blockheight: HumanNumber::from_u64(private.result.height),
difficulty: HumanNumber::from_u64(private.result.difficulty), difficulty: HumanNumber::from_u64(private.result.difficulty),
@ -352,10 +357,10 @@ impl PubNodeApi {
elapsed: std::time::Duration, elapsed: std::time::Duration,
) { ) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty) // 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub); let mut output_pub = output_pub.lock().unwrap();
{ {
let mut public = lock!(public); let mut public = public.lock().unwrap();
if !output_pub.is_empty() { if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub)); public.output.push_str(&std::mem::take(&mut *output_pub));
} }

View file

@ -53,10 +53,10 @@ impl Helper {
while let Some(Ok(line)) = stdout.next() { while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line); let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e); error!("P2Pool PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e); error!("P2Pool PTY Pub | Output error: {}", e);
} }
if i > 20 { if i > 20 {
@ -81,10 +81,10 @@ impl Helper {
ehr ehr
); );
// multiply by a thousand because value is given as kH/s instead H/s // multiply by a thousand because value is given as kH/s instead H/s
lock!(gui_api).sidechain_ehr = ehr; gui_api.lock().unwrap().sidechain_ehr = ehr;
debug!( debug!(
"P2pool | PTY getting current estimated HR data from status: {} H/s", "P2pool | PTY getting current estimated HR data from status: {} H/s",
lock!(gui_api).sidechain_ehr gui_api.lock().unwrap().sidechain_ehr
); );
} else { } else {
error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line); error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line);
@ -97,7 +97,7 @@ impl Helper {
"P2pool | PTY getting current shares data from status: {} share", "P2pool | PTY getting current shares data from status: {} share",
shares shares
); );
lock!(gui_api).sidechain_shares = shares; gui_api.lock().unwrap().sidechain_shares = shares;
} else { } else {
error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line); error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line);
} }
@ -114,23 +114,23 @@ impl Helper {
let (date, atomic_unit, block) = PayoutOrd::parse_raw_payout_line(&line); let (date, atomic_unit, block) = PayoutOrd::parse_raw_payout_line(&line);
let formatted_log_line = GupaxP2poolApi::format_payout(&date, &atomic_unit, &block); let formatted_log_line = GupaxP2poolApi::format_payout(&date, &atomic_unit, &block);
GupaxP2poolApi::add_payout( GupaxP2poolApi::add_payout(
&mut lock!(gupax_p2pool_api), &mut gupax_p2pool_api.lock().unwrap(),
&formatted_log_line, &formatted_log_line,
date, date,
atomic_unit, atomic_unit,
block, block,
); );
if let Err(e) = GupaxP2poolApi::write_to_all_files( if let Err(e) = GupaxP2poolApi::write_to_all_files(
&lock!(gupax_p2pool_api), &gupax_p2pool_api.lock().unwrap(),
&formatted_log_line, &formatted_log_line,
) { ) {
error!("P2Pool PTY GupaxP2poolApi | Write error: {}", e); error!("P2Pool PTY GupaxP2poolApi | Write error: {}", e);
} }
} }
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e); error!("P2Pool PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e); error!("P2Pool PTY Pub | Output error: {}", e);
} }
} }
@ -141,8 +141,8 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on. // Just sets some signals for the watchdog thread to pick up on.
pub fn stop_p2pool(helper: &Arc<Mutex<Self>>) { pub fn stop_p2pool(helper: &Arc<Mutex<Self>>) {
info!("P2Pool | Attempting to stop..."); info!("P2Pool | Attempting to stop...");
lock2!(helper, p2pool).signal = ProcessSignal::Stop; helper.lock().unwrap().p2pool.lock().unwrap().signal = ProcessSignal::Stop;
lock2!(helper, p2pool).state = ProcessState::Middle; helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
} }
#[cold] #[cold]
@ -156,15 +156,15 @@ impl Helper {
backup_hosts: Option<Vec<Node>>, backup_hosts: Option<Vec<Node>>,
) { ) {
info!("P2Pool | Attempting to restart..."); info!("P2Pool | Attempting to restart...");
lock2!(helper, p2pool).signal = ProcessSignal::Restart; helper.lock().unwrap().p2pool.lock().unwrap().signal = ProcessSignal::Restart;
lock2!(helper, p2pool).state = ProcessState::Middle; helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper); let helper = Arc::clone(helper);
let state = state.clone(); let state = state.clone();
let path = path.to_path_buf(); let path = path.to_path_buf();
// This thread lives to wait, start p2pool then die. // This thread lives to wait, start p2pool then die.
thread::spawn(move || { thread::spawn(move || {
while lock2!(helper, p2pool).state != ProcessState::Waiting { while helper.lock().unwrap().p2pool.lock().unwrap().state != ProcessState::Waiting {
warn!("P2Pool | Want to restart but process is still alive, waiting..."); warn!("P2Pool | Want to restart but process is still alive, waiting...");
sleep!(1000); sleep!(1000);
} }
@ -184,7 +184,7 @@ impl Helper {
path: &Path, path: &Path,
backup_hosts: Option<Vec<Node>>, backup_hosts: Option<Vec<Node>>,
) { ) {
lock2!(helper, p2pool).state = ProcessState::Middle; helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let (args, api_path_local, api_path_network, api_path_pool) = let (args, api_path_local, api_path_network, api_path_pool) =
Self::build_p2pool_args_and_mutate_img(helper, state, path, backup_hosts); Self::build_p2pool_args_and_mutate_img(helper, state, path, backup_hosts);
@ -199,10 +199,10 @@ impl Helper {
)); ));
// Spawn watchdog thread // Spawn watchdog thread
let process = Arc::clone(&lock!(helper).p2pool); let process = Arc::clone(&helper.lock().unwrap().p2pool);
let gui_api = Arc::clone(&lock!(helper).gui_api_p2pool); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_p2pool);
let pub_api = Arc::clone(&lock!(helper).pub_api_p2pool); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_p2pool);
let gupax_p2pool_api = Arc::clone(&lock!(helper).gupax_p2pool_api); let gupax_p2pool_api = Arc::clone(&helper.lock().unwrap().gupax_p2pool_api);
let path = path.to_path_buf(); let path = path.to_path_buf();
thread::spawn(move || { thread::spawn(move || {
Self::spawn_p2pool_watchdog( Self::spawn_p2pool_watchdog(
@ -278,7 +278,7 @@ impl Helper {
} }
} }
*lock2!(helper, img_p2pool) = ImgP2pool { *helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(), mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address), address: Self::head_tail_of_monero_address(&state.address),
host: ip.to_string(), host: ip.to_string(),
@ -305,7 +305,7 @@ impl Helper {
args.push("--mini".to_string()); // P2Pool Mini args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine. args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
*lock2!(helper, img_p2pool) = ImgP2pool { *helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(), mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address), address: Self::head_tail_of_monero_address(&state.address),
host: "Local node".to_string(), host: "Local node".to_string(),
@ -322,8 +322,8 @@ impl Helper {
// This parses the input and attempts to fill out // This parses the input and attempts to fill out
// the [ImgP2pool]... This is pretty bad code... // the [ImgP2pool]... This is pretty bad code...
let mut last = ""; let mut last = "";
let lock = lock!(helper); let lock = helper.lock().unwrap();
let mut p2pool_image = lock!(lock.img_p2pool); let mut p2pool_image = lock.img_p2pool.lock().unwrap();
let mut mini = false; let mut mini = false;
for arg in state.arguments.split_whitespace() { for arg in state.arguments.split_whitespace() {
match last { match last {
@ -398,7 +398,7 @@ impl Helper {
} }
} }
*lock2!(helper, img_p2pool) = ImgP2pool { *helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: if state.mini { mini: if state.mini {
"P2Pool Mini".to_string() "P2Pool Mini".to_string()
} else { } else {
@ -464,7 +464,7 @@ impl Helper {
// 2. Set process state // 2. Set process state
debug!("P2Pool | Setting process state..."); debug!("P2Pool | Setting process state...");
let mut lock = lock!(process); let mut lock = process.lock().unwrap();
lock.state = ProcessState::Syncing; lock.state = ProcessState::Syncing;
lock.signal = ProcessSignal::None; lock.signal = ProcessSignal::None;
lock.start = Instant::now(); lock.start = Instant::now();
@ -474,8 +474,8 @@ impl Helper {
// 3. Spawn PTY read thread // 3. Spawn PTY read thread
debug!("P2Pool | Spawning PTY read thread..."); debug!("P2Pool | Spawning PTY read thread...");
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
let gupax_p2pool_api = Arc::clone(&gupax_p2pool_api); let gupax_p2pool_api = Arc::clone(&gupax_p2pool_api);
let p2pool_api_c = Arc::clone(&gui_api); let p2pool_api_c = Arc::clone(&gui_api);
tokio::spawn(async move { tokio::spawn(async move {
@ -487,8 +487,8 @@ impl Helper {
p2pool_api_c, p2pool_api_c,
); );
}); });
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
debug!("P2Pool | Cleaning old [local] API files..."); debug!("P2Pool | Cleaning old [local] API files...");
// Attempt to remove stale API file // Attempt to remove stale API file
@ -511,11 +511,11 @@ impl Helper {
), ),
} }
} }
let start = lock!(process).start; let start = process.lock().unwrap().start;
// Reset stats before loop // Reset stats before loop
*lock!(pub_api) = PubP2poolApi::new(); *pub_api.lock().unwrap() = PubP2poolApi::new();
*lock!(gui_api) = PubP2poolApi::new(); *gui_api.lock().unwrap() = PubP2poolApi::new();
// 4. Loop as watchdog // 4. Loop as watchdog
let mut first_loop = true; let mut first_loop = true;
@ -527,27 +527,32 @@ impl Helper {
// Set timer // Set timer
let now = Instant::now(); let now = Instant::now();
debug!("P2Pool Watchdog | ----------- Start of loop -----------"); debug!("P2Pool Watchdog | ----------- Start of loop -----------");
lock!(gui_api).tick = (last_p2pool_request.elapsed().as_secs() % 60) as u8; gui_api.lock().unwrap().tick = (last_p2pool_request.elapsed().as_secs() % 60) as u8;
// Check if the process is secretly died without us knowing :) // Check if the process is secretly died without us knowing :)
if check_died( if check_died(
&child_pty, &child_pty,
&mut lock!(process), &mut process.lock().unwrap(),
&start, &start,
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
) { ) {
break; break;
} }
// Check SIGNAL // Check SIGNAL
if signal_end(&process, &child_pty, &start, &mut lock!(gui_api).output) { if signal_end(
&process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break; break;
} }
// Check vector of user input // Check vector of user input
check_user_input(&process, &mut stdin); check_user_input(&process, &mut stdin);
// Check if logs need resetting // Check if logs need resetting
debug!("P2Pool Watchdog | Attempting GUI log reset check"); debug!("P2Pool Watchdog | Attempting GUI log reset check");
let mut lock = lock!(gui_api); let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::P2pool); Self::check_reset_gui_output(&mut lock.output, ProcessName::P2pool);
drop(lock); drop(lock);
@ -575,8 +580,9 @@ impl Helper {
last_p2pool_request.elapsed() >= Duration::from_secs(60); last_p2pool_request.elapsed() >= Duration::from_secs(60);
// need to reload fast to get the first right values after syncing. // need to reload fast to get the first right values after syncing.
// check if value is 100k or under and request immediately if that's the case. fixed in release of p2pool including commit https://github.com/SChernykh/p2pool/commit/64a199be6dec7924b41f857a401086f25e1ec9be // check if value is 100k or under and request immediately if that's the case. fixed in release of p2pool including commit https://github.com/SChernykh/p2pool/commit/64a199be6dec7924b41f857a401086f25e1ec9be
if (last_p2pool_request_expired || lock!(pub_api).p2pool_difficulty_u64 <= 100000) if (last_p2pool_request_expired
&& lock!(process).state == ProcessState::Alive || pub_api.lock().unwrap().p2pool_difficulty_u64 <= 100000)
&& process.lock().unwrap().state == ProcessState::Alive
{ {
debug!("P2Pool Watchdog | Attempting [network] & [pool] API file read"); debug!("P2Pool Watchdog | Attempting [network] & [pool] API file read");
if let (Ok(network_api), Ok(pool_api)) = ( if let (Ok(network_api), Ok(pool_api)) = (
@ -597,7 +603,7 @@ impl Helper {
last_status_request.elapsed() >= Duration::from_secs(60); last_status_request.elapsed() >= Duration::from_secs(60);
if (last_status_request_expired || first_loop) if (last_status_request_expired || first_loop)
&& lock!(process).state == ProcessState::Alive && process.lock().unwrap().state == ProcessState::Alive
{ {
debug!("P2Pool Watchdog | Reading status output of p2pool node"); debug!("P2Pool Watchdog | Reading status output of p2pool node");
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -622,7 +628,7 @@ impl Helper {
sleep_end_loop(now, ProcessName::P2pool).await; sleep_end_loop(now, ProcessName::P2pool).await;
debug!( debug!(
"P2Pool Watchdog | END OF LOOP - Tick: [{}/60]", "P2Pool Watchdog | END OF LOOP - Tick: [{}/60]",
lock!(gui_api).tick, gui_api.lock().unwrap().tick,
); );
} }
@ -827,37 +833,39 @@ impl PubP2poolApi {
process: &Arc<Mutex<Process>>, process: &Arc<Mutex<Process>>,
) { ) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty) // 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub); let mut output_pub = output_pub.lock().unwrap();
if !output_pub.is_empty() { if !output_pub.is_empty() {
lock!(public) public
.lock()
.unwrap()
.output .output
.push_str(&std::mem::take(&mut *output_pub)); .push_str(&std::mem::take(&mut *output_pub));
} }
// 2. Parse the full STDOUT // 2. Parse the full STDOUT
let mut output_parse = lock!(output_parse); let mut output_parse = output_parse.lock().unwrap();
let (payouts_new, xmr_new) = Self::calc_payouts_and_xmr(&output_parse); let (payouts_new, xmr_new) = Self::calc_payouts_and_xmr(&output_parse);
// Check for "SYNCHRONIZED" only if we aren't already. // Check for "SYNCHRONIZED" only if we aren't already.
if lock!(process).state == ProcessState::Syncing { if process.lock().unwrap().state == ProcessState::Syncing {
// look for depth 0 // look for depth 0
if P2POOL_REGEX.depth_0.is_match(&output_parse) { if P2POOL_REGEX.depth_0.is_match(&output_parse) {
lock!(process).state = ProcessState::Alive; process.lock().unwrap().state = ProcessState::Alive;
} }
} }
// check if zmq server still alive // check if zmq server still alive
if lock!(process).state == ProcessState::Alive if process.lock().unwrap().state == ProcessState::Alive
&& contains_zmq_connection_lost(&output_parse) && contains_zmq_connection_lost(&output_parse)
{ {
// node zmq is not responding, p2pool is not ready // node zmq is not responding, p2pool is not ready
lock!(process).state = ProcessState::Syncing; process.lock().unwrap().state = ProcessState::Syncing;
} }
// 3. Throw away [output_parse] // 3. Throw away [output_parse]
output_parse.clear(); output_parse.clear();
drop(output_parse); drop(output_parse);
// 4. Add to current values // 4. Add to current values
let mut public = lock!(public); let mut public = public.lock().unwrap();
let (payouts, xmr) = (public.payouts + payouts_new, public.xmr + xmr_new); let (payouts, xmr) = (public.payouts + payouts_new, public.xmr + xmr_new);
// 5. Calculate hour/day/month given elapsed time // 5. Calculate hour/day/month given elapsed time
@ -910,7 +918,7 @@ impl PubP2poolApi {
// Mutate [PubP2poolApi] with data from a [PrivP2poolLocalApi] and the process output. // Mutate [PubP2poolApi] with data from a [PrivP2poolLocalApi] and the process output.
pub(super) fn update_from_local(public: &Arc<Mutex<Self>>, local: PrivP2poolLocalApi) { pub(super) fn update_from_local(public: &Arc<Mutex<Self>>, local: PrivP2poolLocalApi) {
let mut public = lock!(public); let mut public = public.lock().unwrap();
*public = Self { *public = Self {
hashrate_15m: HumanNumber::from_u64(local.hashrate_15m), hashrate_15m: HumanNumber::from_u64(local.hashrate_15m),
hashrate_1h: HumanNumber::from_u64(local.hashrate_1h), hashrate_1h: HumanNumber::from_u64(local.hashrate_1h),
@ -930,7 +938,7 @@ impl PubP2poolApi {
net: PrivP2poolNetworkApi, net: PrivP2poolNetworkApi,
pool: PrivP2poolPoolApi, pool: PrivP2poolPoolApi,
) { ) {
let user_hashrate = lock!(public).user_p2pool_hashrate_u64; // The user's total P2Pool hashrate let user_hashrate = public.lock().unwrap().user_p2pool_hashrate_u64; // The user's total P2Pool hashrate
let monero_difficulty = net.difficulty; let monero_difficulty = net.difficulty;
let monero_hashrate = monero_difficulty / MONERO_BLOCK_TIME_IN_SECONDS; let monero_hashrate = monero_difficulty / MONERO_BLOCK_TIME_IN_SECONDS;
let p2pool_hashrate = pool.pool_statistics.hashRate; let p2pool_hashrate = pool.pool_statistics.hashRate;
@ -972,7 +980,7 @@ impl PubP2poolApi {
p2pool_difficulty / user_hashrate, p2pool_difficulty / user_hashrate,
)); ));
} }
let mut public = lock!(public); let mut public = public.lock().unwrap();
*public = Self { *public = Self {
p2pool_difficulty_u64: p2pool_difficulty, p2pool_difficulty_u64: p2pool_difficulty,
monero_difficulty_u64: monero_difficulty, monero_difficulty_u64: monero_difficulty,

View file

@ -425,7 +425,6 @@ Uptime = 0h 2m 4s
use crate::{ use crate::{
disk::state::P2pool, disk::state::P2pool,
helper::{p2pool::PubP2poolApi, xrig::xmrig::PubXmrigApi}, helper::{p2pool::PubP2poolApi, xrig::xmrig::PubXmrigApi},
macros::lock,
}; };
use crate::helper::xvb::{public_stats::XvbPubStats, PubXvbApi}; use crate::helper::xvb::{public_stats::XvbPubStats, PubXvbApi};
@ -458,9 +457,9 @@ Uptime = 0h 2m 4s
let share = 1; let share = 1;
let p2pool_buffer = 5; let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualXvb; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualXvb;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0; gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -497,9 +496,9 @@ Uptime = 0h 2m 4s
let share = 1; let share = 1;
let p2pool_buffer = 5; let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualP2pool; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualP2pool;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0; gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -536,10 +535,14 @@ Uptime = 0h 2m 4s
let share = 1; let share = 1;
let p2pool_buffer = 5; let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualDonationLevel; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualDonationLevel;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0; gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
lock!(gui_api_xvb).stats_priv.runtime_manual_donation_level = RuntimeDonationLevel::Donor; gui_api_xvb
.lock()
.unwrap()
.stats_priv
.runtime_manual_donation_level = RuntimeDonationLevel::Donor;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -576,9 +579,9 @@ Uptime = 0h 2m 4s
let share = 1; let share = 1;
let p2pool_buffer = 5; let p2pool_buffer = 5;
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 9_000_000; gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 9_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 20000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Auto; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -598,9 +601,9 @@ Uptime = 0h 2m 4s
assert_eq!(algo.stats.target_donation_hashrate, 10000.0); assert_eq!(algo.stats.target_donation_hashrate, 10000.0);
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 95_000_000; gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 95_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Auto; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -637,9 +640,9 @@ Uptime = 0h 2m 4s
let share = 1; let share = 1;
let p2pool_buffer = 5; let p2pool_buffer = 5;
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 95_000_000; gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 95_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 20000.0; gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Hero; gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Hero;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,
@ -659,7 +662,7 @@ Uptime = 0h 2m 4s
assert_eq!(algo.stats.target_donation_hashrate, 15382.1); assert_eq!(algo.stats.target_donation_hashrate, 15382.1);
lock!(gui_api_p2pool).sidechain_ehr = 25000.0; gui_api_p2pool.lock().unwrap().sidechain_ehr = 25000.0;
let algo = Algorithm::new( let algo = Algorithm::new(
&client, &client,

View file

@ -46,10 +46,10 @@ impl Helper {
let mut i = 0; let mut i = 0;
while let Some(Ok(line)) = stdout.next() { while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line); let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig PTY Parse | Output error: {}", e); error!("XMRig PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig PTY Pub | Output error: {}", e); error!("XMRig PTY Pub | Output error: {}", e);
} }
if i > 13 { if i > 13 {
@ -63,9 +63,9 @@ impl Helper {
// need to verify if node still working // need to verify if node still working
// for that need to catch "connect error" // for that need to catch "connect error"
// only check if xvb process is used and xmrig-proxy is not. // only check if xvb process is used and xmrig-proxy is not.
if lock!(process_xvb).is_alive() && !lock!(process_xp).is_alive() { if process_xvb.lock().unwrap().is_alive() && !process_xp.lock().unwrap().is_alive() {
if contains_error(&line) { if contains_error(&line) {
let current_node = lock!(pub_api_xvb).current_node; let current_node = pub_api_xvb.lock().unwrap().current_node;
if let Some(current_node) = current_node { if let Some(current_node) = current_node {
// updating current node to None, will stop sending signal of FailedNode until new node is set // updating current node to None, will stop sending signal of FailedNode until new node is set
// send signal to update node. // send signal to update node.
@ -73,9 +73,10 @@ impl Helper {
// update nodes only if we were not mining on p2pool. // update nodes only if we were not mining on p2pool.
// if xmrig stop, xvb will react in any case. // if xmrig stop, xvb will react in any case.
if current_node != XvbNode::P2pool { if current_node != XvbNode::P2pool {
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(current_node); process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(current_node);
} }
lock!(pub_api_xvb).current_node = None; pub_api_xvb.lock().unwrap().current_node = None;
} }
} }
if contains_usepool(&line) { if contains_usepool(&line) {
@ -86,16 +87,17 @@ impl Helper {
if node.is_none() { if node.is_none() {
error!("XMRig PTY Parse | node is not understood, switching to backup."); error!("XMRig PTY Parse | node is not understood, switching to backup.");
// update with default will choose which XvB to prefer. Will update XvB to use p2pool. // update with default will choose which XvB to prefer. Will update XvB to use p2pool.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default()); process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(XvbNode::default());
} }
lock!(pub_api_xvb).current_node = node; pub_api_xvb.lock().unwrap().current_node = node;
} }
} }
// println!("{}", line); // For debugging. // println!("{}", line); // For debugging.
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig PTY Parse | Output error: {}", e); error!("XMRig PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig PTY Pub | Output error: {}", e); error!("XMRig PTY Pub | Output error: {}", e);
} }
} }
@ -117,7 +119,7 @@ impl Helper {
// Write the [sudo] password to STDIN. // Write the [sudo] password to STDIN.
let mut stdin = child.stdin.take().unwrap(); let mut stdin = child.stdin.take().unwrap();
use std::io::Write; use std::io::Write;
if let Err(e) = writeln!(stdin, "{}\n", lock!(sudo).pass) { if let Err(e) = writeln!(stdin, "{}\n", sudo.lock().unwrap().pass) {
error!("Sudo Kill | STDIN error: {}", e); error!("Sudo Kill | STDIN error: {}", e);
} }
@ -130,12 +132,12 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on. // Just sets some signals for the watchdog thread to pick up on.
pub fn stop_xmrig(helper: &Arc<Mutex<Self>>) { pub fn stop_xmrig(helper: &Arc<Mutex<Self>>) {
info!("XMRig | Attempting to stop..."); info!("XMRig | Attempting to stop...");
lock2!(helper, xmrig).signal = ProcessSignal::Stop; helper.lock().unwrap().xmrig.lock().unwrap().signal = ProcessSignal::Stop;
lock2!(helper, xmrig).state = ProcessState::Middle; helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let gui_api = Arc::clone(&lock!(helper).gui_api_xmrig); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api = Arc::clone(&lock!(helper).pub_api_xmrig); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
*lock!(pub_api) = PubXmrigApi::new(); *pub_api.lock().unwrap() = PubXmrigApi::new();
*lock!(gui_api) = PubXmrigApi::new(); *gui_api.lock().unwrap() = PubXmrigApi::new();
} }
#[cold] #[cold]
@ -149,15 +151,15 @@ impl Helper {
sudo: Arc<Mutex<SudoState>>, sudo: Arc<Mutex<SudoState>>,
) { ) {
info!("XMRig | Attempting to restart..."); info!("XMRig | Attempting to restart...");
lock2!(helper, xmrig).signal = ProcessSignal::Restart; helper.lock().unwrap().xmrig.lock().unwrap().signal = ProcessSignal::Restart;
lock2!(helper, xmrig).state = ProcessState::Middle; helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper); let helper = Arc::clone(helper);
let state = state.clone(); let state = state.clone();
let path = path.to_path_buf(); let path = path.to_path_buf();
// This thread lives to wait, start xmrig then die. // This thread lives to wait, start xmrig then die.
thread::spawn(move || { thread::spawn(move || {
while lock2!(helper, xmrig).state != ProcessState::Waiting { while helper.lock().unwrap().xmrig.lock().unwrap().state != ProcessState::Waiting {
warn!("XMRig | Want to restart but process is still alive, waiting..."); warn!("XMRig | Want to restart but process is still alive, waiting...");
sleep!(1000); sleep!(1000);
} }
@ -176,7 +178,7 @@ impl Helper {
path: &Path, path: &Path,
sudo: Arc<Mutex<SudoState>>, sudo: Arc<Mutex<SudoState>>,
) { ) {
lock2!(helper, xmrig).state = ProcessState::Middle; helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let (args, api_ip_port) = Self::build_xmrig_args_and_mutate_img(helper, state, path); let (args, api_ip_port) = Self::build_xmrig_args_and_mutate_img(helper, state, path);
// Print arguments & user settings to console // Print arguments & user settings to console
@ -184,15 +186,15 @@ impl Helper {
info!("XMRig | Using path: [{}]", path.display()); info!("XMRig | Using path: [{}]", path.display());
// Spawn watchdog thread // Spawn watchdog thread
let process = Arc::clone(&lock!(helper).xmrig); let process = Arc::clone(&helper.lock().unwrap().xmrig);
let gui_api = Arc::clone(&lock!(helper).gui_api_xmrig); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api = Arc::clone(&lock!(helper).pub_api_xmrig); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
let process_xvb = Arc::clone(&lock!(helper).xvb); let process_xvb = Arc::clone(&helper.lock().unwrap().xvb);
let process_xp = Arc::clone(&lock!(helper).xmrig_proxy); let process_xp = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let path = path.to_path_buf(); let path = path.to_path_buf();
let token = state.token.clone(); let token = state.token.clone();
let img_xmrig = Arc::clone(&lock!(helper).img_xmrig); let img_xmrig = Arc::clone(&helper.lock().unwrap().img_xmrig);
let pub_api_xvb = Arc::clone(&lock!(helper).pub_api_xvb); let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
thread::spawn(move || { thread::spawn(move || {
Self::spawn_xmrig_watchdog( Self::spawn_xmrig_watchdog(
process, process,
@ -258,12 +260,13 @@ impl Helper {
args.push("--pause-on-active".to_string()); args.push("--pause-on-active".to_string());
args.push(state.pause.to_string()); args.push(state.pause.to_string());
} // Pause on active } // Pause on active
*lock2!(helper, img_xmrig) = ImgXmrig { *helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
threads: state.current_threads.to_string(), threads: state.current_threads.to_string(),
url: "127.0.0.1:3333 (Local P2Pool)".to_string(), url: "127.0.0.1:3333 (Local P2Pool)".to_string(),
}; };
lock2!(helper, pub_api_xmrig).node = "127.0.0.1:3333 (Local P2Pool)".to_string(); helper.lock().unwrap().pub_api_xmrig.lock().unwrap().node =
"127.0.0.1:3333 (Local P2Pool)".to_string();
api_ip = "127.0.0.1".to_string(); api_ip = "127.0.0.1".to_string();
api_port = "18088".to_string(); api_port = "18088".to_string();
@ -274,8 +277,8 @@ impl Helper {
// This parses the input and attempts to fill out // This parses the input and attempts to fill out
// the [ImgXmrig]... This is pretty bad code... // the [ImgXmrig]... This is pretty bad code...
let mut last = ""; let mut last = "";
let lock = lock!(helper); let lock = helper.lock().unwrap();
let mut xmrig_image = lock!(lock.img_xmrig); let mut xmrig_image = lock.img_xmrig.lock().unwrap();
for arg in state.arguments.split_whitespace() { for arg in state.arguments.split_whitespace() {
match last { match last {
"--threads" => xmrig_image.threads = arg.to_string(), "--threads" => xmrig_image.threads = arg.to_string(),
@ -339,11 +342,11 @@ impl Helper {
args.push("--pause-on-active".to_string()); args.push("--pause-on-active".to_string());
args.push(state.pause.to_string()); args.push(state.pause.to_string());
} // Pause on active } // Pause on active
*lock2!(helper, img_xmrig) = ImgXmrig { *helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
url: url.clone(), url: url.clone(),
threads: state.current_threads.to_string(), threads: state.current_threads.to_string(),
}; };
lock2!(helper, pub_api_xmrig).node = url; helper.lock().unwrap().pub_api_xmrig.lock().unwrap().node = url;
} }
} }
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
@ -404,8 +407,8 @@ impl Helper {
// 4. Spawn PTY read thread // 4. Spawn PTY read thread
debug!("XMRig | Spawning PTY read thread..."); debug!("XMRig | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enclose!((pub_api_xvb, process_xp) async move { spawn(enclose!((pub_api_xvb, process_xp) async move {
Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, process_xp, &pub_api_xvb).await; Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, process_xp, &pub_api_xvb).await;
})); }));
@ -428,19 +431,19 @@ impl Helper {
// a) Sleep to wait for [sudo]'s non-echo prompt (on Unix). // a) 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.
sleep!(3000); sleep!(3000);
if let Err(e) = writeln!(stdin, "{}", lock!(sudo).pass) { if let Err(e) = writeln!(stdin, "{}", sudo.lock().unwrap().pass) {
error!("XMRig | Sudo STDIN error: {}", e); error!("XMRig | Sudo STDIN error: {}", e);
}; };
SudoState::wipe(&sudo); SudoState::wipe(&sudo);
// b) Reset GUI STDOUT just in case. // b) Reset GUI STDOUT just in case.
debug!("XMRig | Clearing GUI output..."); debug!("XMRig | Clearing GUI output...");
lock!(gui_api).output.clear(); gui_api.lock().unwrap().output.clear();
} }
// 3. Set process state // 3. Set process state
debug!("XMRig | Setting process state..."); debug!("XMRig | Setting process state...");
let mut lock = lock!(process); let mut lock = process.lock().unwrap();
lock.state = ProcessState::NotMining; lock.state = ProcessState::NotMining;
lock.signal = ProcessSignal::None; lock.signal = ProcessSignal::None;
lock.start = Instant::now(); lock.start = Instant::now();
@ -448,16 +451,16 @@ impl Helper {
// // 4. Spawn PTY read thread // // 4. Spawn PTY read thread
// debug!("XMRig | Spawning PTY read thread..."); // debug!("XMRig | Spawning PTY read thread...");
// let output_parse = Arc::clone(&lock!(process).output_parse); // let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
// let output_pub = Arc::clone(&lock!(process).output_pub); // let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
// spawn(enclose!((pub_api_xvb) async move { // spawn(enclose!((pub_api_xvb) async move {
// Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await; // Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await;
// })); // }));
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
let client = Client::new(); let client = Client::new();
let start = lock!(process).start; let start = process.lock().unwrap().start;
let api_uri = { let api_uri = {
if !api_ip_port.ends_with('/') { if !api_ip_port.ends_with('/') {
api_ip_port.push('/'); api_ip_port.push('/');
@ -467,10 +470,14 @@ impl Helper {
info!("XMRig | Final API URI: {}", api_uri); info!("XMRig | Final API URI: {}", api_uri);
// Reset stats before loop // Reset stats before loop
*lock!(pub_api) = PubXmrigApi::new(); *pub_api.lock().unwrap() = PubXmrigApi::new();
*lock!(gui_api) = PubXmrigApi::new(); *gui_api.lock().unwrap() = PubXmrigApi::new();
// node used for process Status tab // node used for process Status tab
lock!(gui_api).node.clone_from(&lock!(img_xmrig).url); gui_api
.lock()
.unwrap()
.node
.clone_from(&img_xmrig.lock().unwrap().url);
// 5. Loop as watchdog // 5. Loop as watchdog
info!("XMRig | Entering watchdog mode... woof!"); info!("XMRig | Entering watchdog mode... woof!");
// needs xmrig to be in belownormal priority or else Gupaxx will be in trouble if it does not have enough cpu time. // needs xmrig to be in belownormal priority or else Gupaxx will be in trouble if it does not have enough cpu time.
@ -499,9 +506,9 @@ impl Helper {
// Check if the process secretly died without us knowing :) // Check if the process secretly died without us knowing :)
if check_died( if check_died(
&child_pty, &child_pty,
&mut lock!(process), &mut process.lock().unwrap(),
&start, &start,
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
) { ) {
break; break;
} }
@ -510,7 +517,7 @@ impl Helper {
&process, &process,
&child_pty, &child_pty,
&start, &start,
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&sudo, &sudo,
) { ) {
break; break;
@ -520,7 +527,7 @@ impl Helper {
// Check if logs need resetting // Check if logs need resetting
debug!("XMRig Watchdog | Attempting GUI log reset check"); debug!("XMRig Watchdog | Attempting GUI log reset check");
{ {
let mut lock = lock!(gui_api); let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::Xmrig); Self::check_reset_gui_output(&mut lock.output, ProcessName::Xmrig);
} }
// Always update from output // Always update from output
@ -547,8 +554,8 @@ impl Helper {
} }
} }
// if mining on proxy and proxy is not alive, switch back to p2pool node // if mining on proxy and proxy is not alive, switch back to p2pool node
if lock!(gui_api).node == XvbNode::XmrigProxy.to_string() if gui_api.lock().unwrap().node == XvbNode::XmrigProxy.to_string()
&& !lock!(process_xp).is_alive() && !process_xp.lock().unwrap().is_alive()
{ {
info!("XMRig Process | redirect xmrig to p2pool since XMRig-Proxy is not alive anymore"); info!("XMRig Process | redirect xmrig to p2pool since XMRig-Proxy is not alive anymore");
if let Err(err) = update_xmrig_config( if let Err(err) = update_xmrig_config(
@ -564,7 +571,7 @@ impl Helper {
// show to console error about updating xmrig config // show to console error about updating xmrig config
warn!("XMRig Process | Failed request HTTP API Xmrig"); warn!("XMRig Process | Failed request HTTP API Xmrig");
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to update xmrig config with HTTP API.\nError: {}", "Failure to update xmrig config with HTTP API.\nError: {}",
err err
@ -572,7 +579,7 @@ impl Helper {
ProcessName::Xmrig, ProcessName::Xmrig,
); );
} else { } else {
lock!(gui_api).node = XvbNode::P2pool.to_string(); gui_api.lock().unwrap().node = XvbNode::P2pool.to_string();
debug!("XMRig Process | mining on P2Pool pool"); debug!("XMRig Process | mining on P2Pool pool");
} }
} }
@ -590,7 +597,7 @@ impl Helper {
gui_api_output_raw: &mut String, gui_api_output_raw: &mut String,
sudo: &Arc<Mutex<SudoState>>, sudo: &Arc<Mutex<SudoState>>,
) -> bool { ) -> bool {
let signal = lock!(process).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"); debug!("XMRig Watchdog | Stop/Restart SIGNAL caught");
// macOS requires [sudo] again to kill [XMRig] // macOS requires [sudo] again to kill [XMRig]
@ -598,18 +605,18 @@ impl Helper {
// If we're at this point, that means the user has // If we're at this point, that means the user has
// entered their [sudo] pass again, after we wiped it. // entered their [sudo] pass again, after we wiped it.
// So, we should be able to find it in our [Arc<Mutex<SudoState>>]. // So, we should be able to find it in our [Arc<Mutex<SudoState>>].
Self::sudo_kill(lock!(child_pty).process_id().unwrap(), sudo); Self::sudo_kill(child_pty.lock().unwrap().process_id().unwrap(), sudo);
// And... wipe it again (only if we're stopping full). // And... wipe it again (only if we're stopping full).
// If we're restarting, the next start will wipe it for us. // If we're restarting, the next start will wipe it for us.
if signal != ProcessSignal::Restart { if signal != ProcessSignal::Restart {
SudoState::wipe(sudo); SudoState::wipe(sudo);
} }
} else if let Err(e) = lock!(child_pty).kill() { } else if let Err(e) = child_pty.lock().unwrap().kill() {
error!("XMRig Watchdog | Kill error: {}", e); error!("XMRig Watchdog | Kill error: {}", e);
} }
let exit_status = match lock!(child_pty).wait() { let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => { Ok(e) => {
let mut process = lock!(process); let mut process = process.lock().unwrap();
if e.success() { if e.success() {
if process.signal == ProcessSignal::Stop { if process.signal == ProcessSignal::Stop {
process.state = ProcessState::Dead; process.state = ProcessState::Dead;
@ -623,7 +630,7 @@ impl Helper {
} }
} }
_ => { _ => {
let mut process = lock!(process); let mut process = process.lock().unwrap();
if process.signal == ProcessSignal::Stop { if process.signal == ProcessSignal::Stop {
process.state = ProcessState::Failed; process.state = ProcessState::Failed;
} }
@ -645,7 +652,7 @@ impl Helper {
e e
); );
} }
let mut process = lock!(process); let mut process = process.lock().unwrap();
match process.signal { match process.signal {
ProcessSignal::Stop => process.signal = ProcessSignal::None, ProcessSignal::Stop => process.signal = ProcessSignal::None,
ProcessSignal::Restart => process.state = ProcessState::Waiting, ProcessSignal::Restart => process.state = ProcessState::Waiting,
@ -746,10 +753,10 @@ impl PubXmrigApi {
process: &Arc<Mutex<Process>>, process: &Arc<Mutex<Process>>,
) { ) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty) // 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub); let mut output_pub = output_pub.lock().unwrap();
{ {
let mut public = lock!(public); let mut public = public.lock().unwrap();
if !output_pub.is_empty() { if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub)); public.output.push_str(&std::mem::take(&mut *output_pub));
} }
@ -758,11 +765,11 @@ impl PubXmrigApi {
} }
// 2. Check for "new job"/"no active...". // 2. Check for "new job"/"no active...".
let mut output_parse = lock!(output_parse); let mut output_parse = output_parse.lock().unwrap();
if XMRIG_REGEX.new_job.is_match(&output_parse) { if XMRIG_REGEX.new_job.is_match(&output_parse) {
lock!(process).state = ProcessState::Alive; process.lock().unwrap().state = ProcessState::Alive;
} else if XMRIG_REGEX.not_mining.is_match(&output_parse) { } else if XMRIG_REGEX.not_mining.is_match(&output_parse) {
lock!(process).state = ProcessState::NotMining; process.lock().unwrap().state = ProcessState::NotMining;
} }
// 3. Throw away [output_parse] // 3. Throw away [output_parse]
@ -772,7 +779,7 @@ impl PubXmrigApi {
// Formats raw private data into ready-to-print human readable version. // Formats raw private data into ready-to-print human readable version.
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigApi) { fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigApi) {
let mut public = lock!(public); let mut public = public.lock().unwrap();
let hashrate_raw = match private.hashrate.total.first() { let hashrate_raw = match private.hashrate.total.first() {
Some(Some(h)) => *h, Some(Some(h)) => *h,
_ => 0.0, _ => 0.0,

View file

@ -19,7 +19,7 @@ use crate::{
xvb::{nodes::XvbNode, PubXvbApi}, xvb::{nodes::XvbNode, PubXvbApi},
Helper, Process, ProcessName, ProcessSignal, ProcessState, Helper, Process, ProcessName, ProcessSignal, ProcessState,
}, },
macros::{arc_mut, lock, lock2, sleep}, macros::{arc_mut, sleep},
miscs::output_console, miscs::output_console,
regex::{contains_timeout, contains_usepool, detect_new_node_xmrig, XMRIG_REGEX}, regex::{contains_timeout, contains_usepool, detect_new_node_xmrig, XMRIG_REGEX},
GUPAX_VERSION_UNDERSCORE, UNKNOWN_DATA, GUPAX_VERSION_UNDERSCORE, UNKNOWN_DATA,
@ -46,10 +46,10 @@ impl Helper {
let mut i = 0; let mut i = 0;
while let Some(Ok(line)) = stdout.next() { while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line); let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Parse | Output error: {}", e); error!("XMRig-Proxy PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Pub | Output error: {}", e); error!("XMRig-Proxy PTY Pub | Output error: {}", e);
} }
if i > 7 { if i > 7 {
@ -63,9 +63,9 @@ impl Helper {
// need to verify if node still working // need to verify if node still working
// for that need to catch "connect error" // for that need to catch "connect error"
// only switch nodes of XvB if XvB process is used // only switch nodes of XvB if XvB process is used
if lock!(process_xvb).is_alive() { if process_xvb.lock().unwrap().is_alive() {
if contains_timeout(&line) { if contains_timeout(&line) {
let current_node = lock!(pub_api_xvb).current_node; let current_node = pub_api_xvb.lock().unwrap().current_node;
if let Some(current_node) = current_node { if let Some(current_node) = current_node {
// updating current node to None, will stop sending signal of FailedNode until new node is set // updating current node to None, will stop sending signal of FailedNode until new node is set
// send signal to update node. // send signal to update node.
@ -73,9 +73,10 @@ impl Helper {
"XMRig-Proxy PTY Parse | node is offline, sending signal to update nodes." "XMRig-Proxy PTY Parse | node is offline, sending signal to update nodes."
); );
if current_node != XvbNode::P2pool { if current_node != XvbNode::P2pool {
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(current_node); process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(current_node);
} }
lock!(pub_api_xvb).current_node = None; pub_api_xvb.lock().unwrap().current_node = None;
} }
} }
if contains_usepool(&line) { if contains_usepool(&line) {
@ -89,16 +90,17 @@ impl Helper {
"XMRig-Proxy PTY Parse | node is not understood, switching to backup." "XMRig-Proxy PTY Parse | node is not understood, switching to backup."
); );
// update with default will choose which XvB to prefer. Will update XvB to use p2pool. // update with default will choose which XvB to prefer. Will update XvB to use p2pool.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default()); process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(XvbNode::default());
} }
lock!(pub_api_xvb).current_node = node; pub_api_xvb.lock().unwrap().current_node = node;
} }
} }
// println!("{}", line); // For debugging. // println!("{}", line); // For debugging.
if let Err(e) = writeln!(lock!(output_parse), "{}", line) { if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Parse | Output error: {}", e); error!("XMRig-Proxy PTY Parse | Output error: {}", e);
} }
if let Err(e) = writeln!(lock!(output_pub), "{}", line) { if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Pub | Output error: {}", e); error!("XMRig-Proxy PTY Pub | Output error: {}", e);
} }
} }
@ -131,7 +133,8 @@ impl Helper {
args.push("127.0.0.1".to_string()); // HTTP API IP args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string()); args.push("--http-port".to_string());
args.push("18089".to_string()); // HTTP API Port args.push("18089".to_string()); // HTTP API Port
lock2!(helper, pub_api_xp).node = "127.0.0.1:3333 (Local P2Pool)".to_string(); helper.lock().unwrap().pub_api_xp.lock().unwrap().node =
"127.0.0.1:3333 (Local P2Pool)".to_string();
// [Advanced] // [Advanced]
} else if !state.arguments.is_empty() { } else if !state.arguments.is_empty() {
@ -191,7 +194,7 @@ impl Helper {
if state.keepalive { if state.keepalive {
args.push("--keepalive".to_string()); args.push("--keepalive".to_string());
} // Keepalive } // Keepalive
lock2!(helper, pub_api_xp).node = p2pool_url; helper.lock().unwrap().pub_api_xp.lock().unwrap().node = p2pool_url;
} }
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string()); args.push("--http-no-restricted".to_string());
@ -200,17 +203,17 @@ impl Helper {
pub fn stop_xp(helper: &Arc<Mutex<Self>>) { pub fn stop_xp(helper: &Arc<Mutex<Self>>) {
info!("XMRig-Proxy | Attempting to stop..."); info!("XMRig-Proxy | Attempting to stop...");
lock2!(helper, xmrig_proxy).signal = ProcessSignal::Stop; helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Stop;
info!("locked signal ok"); info!("locked signal ok");
lock2!(helper, xmrig_proxy).state = ProcessState::Middle; helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
info!("locked state ok"); info!("locked state ok");
let gui_api = Arc::clone(&lock!(helper).gui_api_xp); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xp);
info!("clone gui ok"); info!("clone gui ok");
let pub_api = Arc::clone(&lock!(helper).pub_api_xp); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xp);
info!("clone pub ok"); info!("clone pub ok");
*lock!(pub_api) = PubXmrigProxyApi::new(); *pub_api.lock().unwrap() = PubXmrigProxyApi::new();
info!("pub api reset ok"); info!("pub api reset ok");
*lock!(gui_api) = PubXmrigProxyApi::new(); *gui_api.lock().unwrap() = PubXmrigProxyApi::new();
info!("gui api reset ok"); info!("gui api reset ok");
} }
// The "restart frontend" to a "frontend" function. // The "restart frontend" to a "frontend" function.
@ -222,8 +225,8 @@ impl Helper {
path: &Path, path: &Path,
) { ) {
info!("XMRig-Proxy | Attempting to restart..."); info!("XMRig-Proxy | Attempting to restart...");
lock2!(helper, xmrig_proxy).state = ProcessState::Middle; helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
lock2!(helper, xmrig_proxy).signal = ProcessSignal::Restart; helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Restart;
let helper = Arc::clone(helper); let helper = Arc::clone(helper);
let state = state.clone(); let state = state.clone();
@ -231,7 +234,8 @@ impl Helper {
let path = path.to_path_buf(); let path = path.to_path_buf();
// This thread lives to wait, start xmrig_proxy then die. // This thread lives to wait, start xmrig_proxy then die.
thread::spawn(move || { thread::spawn(move || {
while lock2!(helper, xmrig_proxy).state != ProcessState::Waiting { while helper.lock().unwrap().xmrig_proxy.lock().unwrap().state != ProcessState::Waiting
{
warn!("XMRig-proxy | Want to restart but process is still alive, waiting..."); warn!("XMRig-proxy | Want to restart but process is still alive, waiting...");
sleep!(1000); sleep!(1000);
} }
@ -247,7 +251,7 @@ impl Helper {
state_xmrig: &Xmrig, state_xmrig: &Xmrig,
path: &Path, path: &Path,
) { ) {
lock2!(helper, xmrig_proxy).state = ProcessState::Middle; helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_xp_args(helper, state_proxy); let args = Self::build_xp_args(helper, state_proxy);
// Print arguments & user settings to console // Print arguments & user settings to console
@ -255,17 +259,17 @@ impl Helper {
info!("XMRig-Proxy | Using path: [{}]", path.display()); info!("XMRig-Proxy | Using path: [{}]", path.display());
// Spawn watchdog thread // Spawn watchdog thread
let process = Arc::clone(&lock!(helper).xmrig_proxy); let process = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let gui_api = Arc::clone(&lock!(helper).gui_api_xp); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xp);
let pub_api = Arc::clone(&lock!(helper).pub_api_xp); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xp);
let process_xvb = Arc::clone(&lock!(helper).xvb); let process_xvb = Arc::clone(&helper.lock().unwrap().xvb);
let process_xmrig = Arc::clone(&lock!(helper).xmrig); let process_xmrig = Arc::clone(&helper.lock().unwrap().xmrig);
let path = path.to_path_buf(); let path = path.to_path_buf();
let token = state_proxy.token.clone(); let token = state_proxy.token.clone();
let state_xmrig = state_xmrig.clone(); let state_xmrig = state_xmrig.clone();
let redirect_xmrig = state_proxy.redirect_local_xmrig; let redirect_xmrig = state_proxy.redirect_local_xmrig;
let pub_api_xvb = Arc::clone(&lock!(helper).pub_api_xvb); let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
let gui_api_xmrig = Arc::clone(&lock!(helper).gui_api_xmrig); let gui_api_xmrig = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
thread::spawn(move || { thread::spawn(move || {
Self::spawn_xp_watchdog( Self::spawn_xp_watchdog(
&process, &process,
@ -300,7 +304,7 @@ impl Helper {
pub_api_xvb: &Arc<Mutex<PubXvbApi>>, pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>, gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
) { ) {
lock!(process).start = Instant::now(); process.lock().unwrap().start = Instant::now();
// spawn pty // spawn pty
debug!("XMRig-Proxy | Creating PTY..."); debug!("XMRig-Proxy | Creating PTY...");
let pty = portable_pty::native_pty_system(); let pty = portable_pty::native_pty_system();
@ -315,8 +319,8 @@ impl Helper {
// 4. Spawn PTY read thread // 4. Spawn PTY read thread
debug!("XMRig-Proxy | Spawning PTY read thread..."); debug!("XMRig-Proxy | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse); let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub); let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enc!((pub_api_xvb, output_parse, output_pub) async move { spawn(enc!((pub_api_xvb, output_parse, output_pub) async move {
Self::read_pty_xp(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await; Self::read_pty_xp(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await;
})); }));
@ -336,15 +340,15 @@ impl Helper {
// set state // set state
let client = Client::new(); let client = Client::new();
lock!(process).state = ProcessState::NotMining; process.lock().unwrap().state = ProcessState::NotMining;
lock!(process).signal = ProcessSignal::None; process.lock().unwrap().signal = ProcessSignal::None;
// reset stats // reset stats
let node = lock!(pub_api).node.to_string(); let node = pub_api.lock().unwrap().node.to_string();
*lock!(pub_api) = PubXmrigProxyApi::new(); *pub_api.lock().unwrap() = PubXmrigProxyApi::new();
*lock!(gui_api) = PubXmrigProxyApi::new(); *gui_api.lock().unwrap() = PubXmrigProxyApi::new();
lock!(gui_api).node = node; gui_api.lock().unwrap().node = node;
// loop // loop
let start = lock!(process).start; let start = process.lock().unwrap().start;
debug!("Xmrig-Proxy Watchdog | enabling verbose mode"); debug!("Xmrig-Proxy Watchdog | enabling verbose mode");
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
if let Err(e) = write!(stdin, "v\r\n") { if let Err(e) = write!(stdin, "v\r\n") {
@ -370,14 +374,19 @@ impl Helper {
// check state // check state
if check_died( if check_died(
&child_pty, &child_pty,
&mut lock!(process), &mut process.lock().unwrap(),
&start, &start,
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
) { ) {
break; break;
} }
// check signal // check signal
if signal_end(process, &child_pty, &start, &mut lock!(gui_api).output) { if signal_end(
process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break; break;
} }
// check user input // check user input
@ -387,7 +396,7 @@ impl Helper {
// Check if logs need resetting // Check if logs need resetting
debug!("XMRig-Proxy Watchdog | Attempting GUI log reset check"); debug!("XMRig-Proxy Watchdog | Attempting GUI log reset check");
{ {
let mut lock = lock!(gui_api); let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::XmrigProxy); Self::check_reset_gui_output(&mut lock.output, ProcessName::XmrigProxy);
} }
// Always update from output // Always update from output
@ -416,9 +425,9 @@ impl Helper {
} }
// update xmrig to use xmrig-proxy if option enabled and local xmrig alive // update xmrig to use xmrig-proxy if option enabled and local xmrig alive
if xmrig_redirect if xmrig_redirect
&& lock!(gui_api_xmrig).node != XvbNode::XmrigProxy.to_string() && gui_api_xmrig.lock().unwrap().node != XvbNode::XmrigProxy.to_string()
&& (lock!(process_xmrig).state == ProcessState::Alive && (process_xmrig.lock().unwrap().state == ProcessState::Alive
|| lock!(process_xmrig).state == ProcessState::NotMining) || process_xmrig.lock().unwrap().state == ProcessState::NotMining)
{ {
info!("redirect local xmrig instance to xmrig-proxy"); info!("redirect local xmrig instance to xmrig-proxy");
if let Err(err) = update_xmrig_config( if let Err(err) = update_xmrig_config(
@ -434,7 +443,7 @@ impl Helper {
// show to console error about updating xmrig config // show to console error about updating xmrig config
warn!("XMRig-Proxy Process | Failed request HTTP API Xmrig"); warn!("XMRig-Proxy Process | Failed request HTTP API Xmrig");
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to update xmrig config with HTTP API.\nError: {}", "Failure to update xmrig config with HTTP API.\nError: {}",
err err
@ -442,7 +451,7 @@ impl Helper {
ProcessName::XmrigProxy, ProcessName::XmrigProxy,
); );
} else { } else {
lock!(gui_api_xmrig).node = XvbNode::XmrigProxy.to_string(); gui_api_xmrig.lock().unwrap().node = XvbNode::XmrigProxy.to_string();
debug!("XMRig-Proxy Process | mining on Xmrig-Proxy pool"); debug!("XMRig-Proxy Process | mining on Xmrig-Proxy pool");
} }
} }
@ -497,10 +506,10 @@ impl PubXmrigProxyApi {
process: &Arc<Mutex<Process>>, process: &Arc<Mutex<Process>>,
) { ) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty) // 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub); let mut output_pub = output_pub.lock().unwrap();
{ {
let mut public = lock!(public); let mut public = public.lock().unwrap();
if !output_pub.is_empty() { if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub)); public.output.push_str(&std::mem::take(&mut *output_pub));
} }
@ -509,16 +518,16 @@ impl PubXmrigProxyApi {
} }
// 2. Check for "new job"/"no active...". // 2. Check for "new job"/"no active...".
let mut output_parse = lock!(output_parse); let mut output_parse = output_parse.lock().unwrap();
if XMRIG_REGEX.new_job.is_match(&output_parse) if XMRIG_REGEX.new_job.is_match(&output_parse)
|| XMRIG_REGEX.valid_conn.is_match(&output_parse) || XMRIG_REGEX.valid_conn.is_match(&output_parse)
{ {
lock!(process).state = ProcessState::Alive; process.lock().unwrap().state = ProcessState::Alive;
} else if XMRIG_REGEX.timeout.is_match(&output_parse) } else if XMRIG_REGEX.timeout.is_match(&output_parse)
|| XMRIG_REGEX.invalid_conn.is_match(&output_parse) || XMRIG_REGEX.invalid_conn.is_match(&output_parse)
|| XMRIG_REGEX.error.is_match(&output_parse) || XMRIG_REGEX.error.is_match(&output_parse)
{ {
lock!(process).state = ProcessState::NotMining; process.lock().unwrap().state = ProcessState::NotMining;
} }
// 3. Throw away [output_parse] // 3. Throw away [output_parse]
output_parse.clear(); output_parse.clear();
@ -539,7 +548,7 @@ impl PubXmrigProxyApi {
} }
} }
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigProxyApi) { fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigProxyApi) {
let mut public = lock!(public); let mut public = public.lock().unwrap();
*public = Self { *public = Self {
accepted: private.results.accepted, accepted: private.results.accepted,
rejected: private.results.rejected, rejected: private.results.rejected,

View file

@ -18,7 +18,6 @@ use crate::{
xrig::{update_xmrig_config, xmrig::PubXmrigApi}, xrig::{update_xmrig_config, xmrig::PubXmrigApi},
xvb::{nodes::XvbNode, priv_stats::RuntimeMode}, xvb::{nodes::XvbNode, priv_stats::RuntimeMode},
}, },
macros::lock,
BLOCK_PPLNS_WINDOW_MAIN, BLOCK_PPLNS_WINDOW_MINI, SECOND_PER_BLOCK_P2POOL, BLOCK_PPLNS_WINDOW_MAIN, BLOCK_PPLNS_WINDOW_MINI, SECOND_PER_BLOCK_P2POOL,
XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR, XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR,
XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_TIME_ALGO, XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_TIME_ALGO,
@ -119,24 +118,27 @@ impl<'a> Algorithm<'a> {
let address = state_p2pool.address.clone(); let address = state_p2pool.address.clone();
let runtime_mode = lock!(gui_api_xvb).stats_priv.runtime_mode.clone(); let runtime_mode = gui_api_xvb.lock().unwrap().stats_priv.runtime_mode.clone();
let runtime_donation_level = lock!(gui_api_xvb) let runtime_donation_level = gui_api_xvb
.lock()
.unwrap()
.stats_priv .stats_priv
.runtime_manual_donation_level .runtime_manual_donation_level
.clone(); .clone();
let runtime_amount = lock!(gui_api_xvb).stats_priv.runtime_manual_amount; let runtime_amount = gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount;
let p2pool_total_hashrate = lock!(gui_api_p2pool).sidechain_ehr; let p2pool_total_hashrate = gui_api_p2pool.lock().unwrap().sidechain_ehr;
let avg_last_hour_hashrate = let avg_last_hour_hashrate = Self::calc_last_hour_avg_hash_rate(
Self::calc_last_hour_avg_hash_rate(&lock!(gui_api_xvb).p2pool_sent_last_hour_samples); &gui_api_xvb.lock().unwrap().p2pool_sent_last_hour_samples,
);
let mut p2pool_external_hashrate = p2pool_total_hashrate - avg_last_hour_hashrate; let mut p2pool_external_hashrate = p2pool_total_hashrate - avg_last_hour_hashrate;
if p2pool_external_hashrate < 0.0 { if p2pool_external_hashrate < 0.0 {
p2pool_external_hashrate = 0.0; p2pool_external_hashrate = 0.0;
} }
let share_min_hashrate = Self::minimum_hashrate_share( let share_min_hashrate = Self::minimum_hashrate_share(
lock!(gui_api_p2pool).p2pool_difficulty_u64, gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64,
state_p2pool.mini, state_p2pool.mini,
p2pool_external_hashrate, p2pool_external_hashrate,
p2pool_buffer, p2pool_buffer,
@ -149,8 +151,8 @@ impl<'a> Algorithm<'a> {
let msg_xmrig_or_xp = (if xp_alive { "XMRig-Proxy" } else { "XMRig" }).to_string(); let msg_xmrig_or_xp = (if xp_alive { "XMRig-Proxy" } else { "XMRig" }).to_string();
info!("xp alive: {:?}", xp_alive); info!("xp alive: {:?}", xp_alive);
let xvb_24h_avg = lock!(pub_api).stats_priv.donor_24hr_avg * 1000.0; let xvb_24h_avg = pub_api.lock().unwrap().stats_priv.donor_24hr_avg * 1000.0;
let xvb_1h_avg = lock!(pub_api).stats_priv.donor_1hr_avg * 1000.0; let xvb_1h_avg = pub_api.lock().unwrap().stats_priv.donor_1hr_avg * 1000.0;
let stats = Stats { let stats = Stats {
share, share,
@ -218,7 +220,7 @@ impl<'a> Algorithm<'a> {
} }
async fn target_p2pool_node(&self) { async fn target_p2pool_node(&self) {
if lock!(self.gui_api_xvb).current_node != Some(XvbNode::P2pool) { if self.gui_api_xvb.lock().unwrap().current_node != Some(XvbNode::P2pool) {
info!( info!(
"Algorithm | request {} to mine on p2pool", "Algorithm | request {} to mine on p2pool",
self.stats.msg_xmrig_or_xp self.stats.msg_xmrig_or_xp
@ -239,7 +241,7 @@ impl<'a> Algorithm<'a> {
self.stats.msg_xmrig_or_xp self.stats.msg_xmrig_or_xp
); );
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
&format!( &format!(
"Failure to update {} config with HTTP API.\nError: {}", "Failure to update {} config with HTTP API.\nError: {}",
self.stats.msg_xmrig_or_xp, err self.stats.msg_xmrig_or_xp, err
@ -256,15 +258,18 @@ impl<'a> Algorithm<'a> {
} }
async fn target_xvb_node(&self) { async fn target_xvb_node(&self) {
let node = lock!(self.gui_api_xvb).stats_priv.node; let node = self.gui_api_xvb.lock().unwrap().stats_priv.node;
info!( info!(
"Algorithm | request {} to mine on XvB", "Algorithm | request {} to mine on XvB",
self.stats.msg_xmrig_or_xp self.stats.msg_xmrig_or_xp
); );
if lock!(self.gui_api_xvb).current_node.is_none() if self.gui_api_xvb.lock().unwrap().current_node.is_none()
|| lock!(self.gui_api_xvb) || self
.gui_api_xvb
.lock()
.unwrap()
.current_node .current_node
.as_ref() .as_ref()
.is_some_and(|n| n == &XvbNode::P2pool) .is_some_and(|n| n == &XvbNode::P2pool)
@ -285,7 +290,7 @@ impl<'a> Algorithm<'a> {
self.stats.msg_xmrig_or_xp self.stats.msg_xmrig_or_xp
); );
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
&format!( &format!(
"Failure to update {} config with HTTP API.\nError: {}", "Failure to update {} config with HTTP API.\nError: {}",
self.stats.msg_xmrig_or_xp, err self.stats.msg_xmrig_or_xp, err
@ -294,9 +299,9 @@ impl<'a> Algorithm<'a> {
); );
} else { } else {
if self.xp_alive { if self.xp_alive {
lock!(self.gui_api_xp).node = node.to_string(); self.gui_api_xp.lock().unwrap().node = node.to_string();
} else { } else {
lock!(self.gui_api_xmrig).node = node.to_string(); self.gui_api_xmrig.lock().unwrap().node = node.to_string();
} }
info!( info!(
"Algorithm | {} mining on XvB pool", "Algorithm | {} mining on XvB pool",
@ -315,11 +320,15 @@ impl<'a> Algorithm<'a> {
); );
sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await; sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await;
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples .p2pool_sent_last_hour_samples
.0 .0
.push_back(lock!(self.gui_api_xmrig).hashrate_raw_15m); .push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m);
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples .xvb_sent_last_hour_samples
.0 .0
.push_back(0.0); .push_back(0.0);
@ -334,11 +343,15 @@ impl<'a> Algorithm<'a> {
); );
sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await; sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await;
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples .p2pool_sent_last_hour_samples
.0 .0
.push_back(lock!(self.gui_api_xmrig).hashrate_raw_15m); .push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m);
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples .xvb_sent_last_hour_samples
.0 .0
.push_back(0.0); .push_back(0.0);
@ -368,7 +381,9 @@ impl<'a> Algorithm<'a> {
); );
sleep(Duration::from_secs(self.stats.spared_time.into())).await; sleep(Duration::from_secs(self.stats.spared_time.into())).await;
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples .p2pool_sent_last_hour_samples
.0 .0
.push_back( .push_back(
@ -376,7 +391,9 @@ impl<'a> Algorithm<'a> {
* ((XVB_TIME_ALGO as f32 - self.stats.spared_time as f32) * ((XVB_TIME_ALGO as f32 - self.stats.spared_time as f32)
/ XVB_TIME_ALGO as f32), / XVB_TIME_ALGO as f32),
); );
lock!(self.gui_api_xvb) self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples .xvb_sent_last_hour_samples
.0 .0
.push_back( .push_back(
@ -496,7 +513,7 @@ impl<'a> Algorithm<'a> {
async fn fulfill_share(&self) { async fn fulfill_share(&self) {
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
"There are no shares in p2pool. Sending all hashrate to p2pool!", "There are no shares in p2pool. Sending all hashrate to p2pool!",
crate::helper::ProcessName::Xvb, crate::helper::ProcessName::Xvb,
); );
@ -508,21 +525,21 @@ impl<'a> Algorithm<'a> {
async fn fulfill_xvb_24_avg(&self) { async fn fulfill_xvb_24_avg(&self) {
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
"24H avg XvB target not achieved. Sending all hashrate to XvB!", "24H avg XvB target not achieved. Sending all hashrate to XvB!",
crate::helper::ProcessName::Xvb, crate::helper::ProcessName::Xvb,
); );
info!("Algorithm | 24H avg XvB target not achieved. Sending all hashrate to XvB!"); info!("Algorithm | 24H avg XvB target not achieved. Sending all hashrate to XvB!");
*lock!(self.time_donated) = XVB_TIME_ALGO; *self.time_donated.lock().unwrap() = XVB_TIME_ALGO;
self.send_all_xvb().await self.send_all_xvb().await
} }
async fn fulfill_normal_cycles(&self) { async fn fulfill_normal_cycles(&self) {
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
&format!( &format!(
"There is a share in p2pool and 24H avg XvB is achieved. Sending {} seconds to XvB!", "There is a share in p2pool and 24H avg XvB is achieved. Sending {} seconds to XvB!",
self.stats.spared_time self.stats.spared_time
@ -532,7 +549,7 @@ impl<'a> Algorithm<'a> {
info!("Algorithm | There is a share in p2pool and 24H avg XvB is achieved. Sending seconds {} to XvB!", self.stats.spared_time); info!("Algorithm | There is a share in p2pool and 24H avg XvB is achieved. Sending seconds {} to XvB!", self.stats.spared_time);
*lock!(self.time_donated) = self.stats.spared_time; *self.time_donated.lock().unwrap() = self.stats.spared_time;
self.target_p2pool_node().await; self.target_p2pool_node().await;
self.sleep_then_update_node_xmrig().await; self.sleep_then_update_node_xmrig().await;
@ -540,7 +557,7 @@ impl<'a> Algorithm<'a> {
pub async fn run(&mut self) { pub async fn run(&mut self) {
output_console( output_console(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
"Algorithm of HR distribution started for the next 10 minutes.", "Algorithm of HR distribution started for the next 10 minutes.",
crate::helper::ProcessName::Xvb, crate::helper::ProcessName::Xvb,
); );
@ -557,7 +574,7 @@ impl<'a> Algorithm<'a> {
} }
output_console_without_time( output_console_without_time(
&mut lock!(self.gui_api_xvb).output, &mut self.gui_api_xvb.lock().unwrap().output,
"", "",
crate::helper::ProcessName::Xvb, crate::helper::ProcessName::Xvb,
) )

View file

@ -24,7 +24,7 @@ use crate::helper::xvb::rounds::round_type;
use crate::utils::constants::{XVB_PUBLIC_ONLY, XVB_TIME_ALGO}; use crate::utils::constants::{XVB_PUBLIC_ONLY, XVB_TIME_ALGO};
use crate::{ use crate::{
helper::{ProcessSignal, ProcessState}, helper::{ProcessSignal, ProcessState},
utils::macros::{lock, lock2, sleep}, utils::macros::sleep,
}; };
use self::nodes::XvbNode; use self::nodes::XvbNode;
@ -44,8 +44,8 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on. // Just sets some signals for the watchdog thread to pick up on.
pub fn stop_xvb(helper: &Arc<Mutex<Self>>) { pub fn stop_xvb(helper: &Arc<Mutex<Self>>) {
info!("XvB | Attempting to stop..."); info!("XvB | Attempting to stop...");
lock2!(helper, xvb).signal = ProcessSignal::Stop; helper.lock().unwrap().xvb.lock().unwrap().signal = ProcessSignal::Stop;
lock2!(helper, xvb).state = ProcessState::Middle; helper.lock().unwrap().xvb.lock().unwrap().state = ProcessState::Middle;
} }
pub fn restart_xvb( pub fn restart_xvb(
helper: &Arc<Mutex<Self>>, helper: &Arc<Mutex<Self>>,
@ -55,8 +55,8 @@ impl Helper {
state_xp: &crate::disk::state::XmrigProxy, state_xp: &crate::disk::state::XmrigProxy,
) { ) {
info!("XvB | Attempting to restart..."); info!("XvB | Attempting to restart...");
lock2!(helper, xvb).signal = ProcessSignal::Restart; helper.lock().unwrap().xvb.lock().unwrap().signal = ProcessSignal::Restart;
lock2!(helper, xvb).state = ProcessState::Middle; helper.lock().unwrap().xvb.lock().unwrap().state = ProcessState::Middle;
let helper = helper.clone(); let helper = helper.clone();
let state_xvb = state_xvb.clone(); let state_xvb = state_xvb.clone();
let state_p2pool = state_p2pool.clone(); let state_p2pool = state_p2pool.clone();
@ -64,7 +64,7 @@ impl Helper {
let state_xp = state_xp.clone(); let state_xp = state_xp.clone();
// This thread lives to wait, start xmrig then die. // This thread lives to wait, start xmrig then die.
thread::spawn(move || { thread::spawn(move || {
while lock2!(helper, xvb).state != ProcessState::Waiting { while helper.lock().unwrap().xvb.lock().unwrap().state != ProcessState::Waiting {
warn!("XvB | Want to restart but process is still alive, waiting..."); warn!("XvB | Want to restart but process is still alive, waiting...");
sleep!(1000); sleep!(1000);
} }
@ -88,17 +88,17 @@ impl Helper {
info!("XvB | cloning helper arc fields"); info!("XvB | cloning helper arc fields");
// without xmrig alive, it doesn't make sense to use XvB. // without xmrig alive, it doesn't make sense to use XvB.
// needed to see if it is alive. For XvB process to function completely, p2pool node must be alive to check the shares in the pplns window. // needed to see if it is alive. For XvB process to function completely, p2pool node must be alive to check the shares in the pplns window.
let gui_api = Arc::clone(&lock!(helper).gui_api_xvb); let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xvb);
let pub_api = Arc::clone(&lock!(helper).pub_api_xvb); let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
let process = Arc::clone(&lock!(helper).xvb); let process = Arc::clone(&helper.lock().unwrap().xvb);
let process_p2pool = Arc::clone(&lock!(helper).p2pool); let process_p2pool = Arc::clone(&helper.lock().unwrap().p2pool);
let gui_api_p2pool = Arc::clone(&lock!(helper).gui_api_p2pool); let gui_api_p2pool = Arc::clone(&helper.lock().unwrap().gui_api_p2pool);
let process_xmrig = Arc::clone(&lock!(helper).xmrig); let process_xmrig = Arc::clone(&helper.lock().unwrap().xmrig);
let process_xp = Arc::clone(&lock!(helper).xmrig_proxy); let process_xp = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let gui_api_xmrig = Arc::clone(&lock!(helper).gui_api_xmrig); let gui_api_xmrig = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api_xmrig = Arc::clone(&lock!(helper).pub_api_xmrig); let pub_api_xmrig = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
let gui_api_xp = Arc::clone(&lock!(helper).gui_api_xp); let gui_api_xp = Arc::clone(&helper.lock().unwrap().gui_api_xp);
let pub_api_xp = Arc::clone(&lock!(helper).gui_api_xp); let pub_api_xp = Arc::clone(&helper.lock().unwrap().gui_api_xp);
// Reset before printing to output. // Reset before printing to output.
// Need to reset because values of stats would stay otherwise which could bring confusion even if panel is with a disabled theme. // Need to reset because values of stats would stay otherwise which could bring confusion even if panel is with a disabled theme.
// at the start of a process, values must be default. // at the start of a process, values must be default.
@ -107,14 +107,14 @@ impl Helper {
); );
reset_data_xvb(&pub_api, &gui_api); reset_data_xvb(&pub_api, &gui_api);
// we reset the console output because it is complete start. // we reset the console output because it is complete start.
lock!(gui_api).output.clear(); gui_api.lock().unwrap().output.clear();
// 2. Set process state // 2. Set process state
// XvB has not yet decided if it can continue. // XvB has not yet decided if it can continue.
// it could fail if XvB server is offline or start partially if token/address is invalid or if p2pool or xmrig are offline. // it could fail if XvB server is offline or start partially if token/address is invalid or if p2pool or xmrig are offline.
// this state will be received accessed by the UI directly and put the status on yellow. // this state will be received accessed by the UI directly and put the status on yellow.
info!("XvB | Setting process state..."); info!("XvB | Setting process state...");
{ {
let mut lock = lock!(process); let mut lock = process.lock().unwrap();
lock.state = ProcessState::Middle; lock.state = ProcessState::Middle;
lock.signal = ProcessSignal::None; lock.signal = ProcessSignal::None;
lock.start = std::time::Instant::now(); lock.start = std::time::Instant::now();
@ -188,7 +188,7 @@ impl Helper {
.await; .await;
let mut xp_alive = false; let mut xp_alive = false;
// uptime for log of signal check ? // uptime for log of signal check ?
let start = lock!(process).start; let start = process.lock().unwrap().start;
// uptime of last run of algo // uptime of last run of algo
let last_algorithm = Arc::new(Mutex::new(tokio::time::Instant::now())); let last_algorithm = Arc::new(Mutex::new(tokio::time::Instant::now()));
// uptime of last request (public and private) // uptime of last request (public and private)
@ -210,9 +210,9 @@ impl Helper {
let start_loop = std::time::Instant::now(); let start_loop = std::time::Instant::now();
// check if first loop the state of Xmrig-Proxy // check if first loop the state of Xmrig-Proxy
if first_loop { if first_loop {
xp_alive = lock!(process_xp).state == ProcessState::Alive; xp_alive = process_xp.lock().unwrap().state == ProcessState::Alive;
msg_retry_done = false; msg_retry_done = false;
*lock!(retry) = false; *retry.lock().unwrap() = false;
} }
// verify if p2pool and xmrig are running, else XvB must be reloaded with another token/address to start verifying the other process. // verify if p2pool and xmrig are running, else XvB must be reloaded with another token/address to start verifying the other process.
if check_state_outcauses_xvb( if check_state_outcauses_xvb(
@ -255,26 +255,31 @@ impl Helper {
info!("XvB Watchdog | Signal has stopped the loop"); info!("XvB Watchdog | Signal has stopped the loop");
break; break;
} }
// let handle_algo_c = lock!(handle_algo); // let handle_algo_c = handle_algo.lock().unwrap();
let is_algo_started_once = lock!(handle_algo).is_some(); let is_algo_started_once = handle_algo.lock().unwrap().is_some();
let is_algo_finished = lock!(handle_algo) let is_algo_finished = handle_algo
.lock()
.unwrap()
.as_ref() .as_ref()
.is_some_and(|algo| algo.is_finished()); .is_some_and(|algo| algo.is_finished());
let is_request_finished = lock!(handle_request) let is_request_finished = handle_request
.lock()
.unwrap()
.as_ref() .as_ref()
.is_some_and(|request: &JoinHandle<()>| request.is_finished()) .is_some_and(|request: &JoinHandle<()>| request.is_finished())
|| lock!(handle_request).is_none(); || handle_request.lock().unwrap().is_none();
// Send an HTTP API request only if one minute is passed since the last request or if first loop or if algorithm need to retry or if request is finished and algo is finished or almost finished (only public and private stats). We make sure public and private stats are refreshed before doing another run of the algo. // Send an HTTP API request only if one minute is passed since the last request or if first loop or if algorithm need to retry or if request is finished and algo is finished or almost finished (only public and private stats). We make sure public and private stats are refreshed before doing another run of the algo.
// We make sure algo or request are not rerun when they are not over. // We make sure algo or request are not rerun when they are not over.
// in the case of quick refresh before new run of algo, make sure it doesn't happen multiple times. // in the case of quick refresh before new run of algo, make sure it doesn't happen multiple times.
let last_request_expired = lock!(last_request).elapsed() >= Duration::from_secs(60); let last_request_expired =
last_request.lock().unwrap().elapsed() >= Duration::from_secs(60);
let should_refresh_before_next_algo = is_algo_started_once let should_refresh_before_next_algo = is_algo_started_once
&& lock!(last_algorithm).elapsed() && last_algorithm.lock().unwrap().elapsed()
>= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95) as u64) >= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95) as u64)
&& lock!(last_request).elapsed() >= Duration::from_secs(25); && last_request.lock().unwrap().elapsed() >= Duration::from_secs(25);
let process_alive = lock!(process).state == ProcessState::Alive; let process_alive = process.lock().unwrap().state == ProcessState::Alive;
if ((last_request_expired || first_loop) if ((last_request_expired || first_loop)
|| (*lock!(retry) || is_algo_finished || should_refresh_before_next_algo) || (*retry.lock().unwrap() || is_algo_finished || should_refresh_before_next_algo)
&& process_alive) && process_alive)
&& is_request_finished && is_request_finished
{ {
@ -282,19 +287,19 @@ impl Helper {
// Private API will also use this instant if XvB is Alive. // Private API will also use this instant if XvB is Alive.
// first_loop is false here but could be changed to true under some conditions. // first_loop is false here but could be changed to true under some conditions.
// will send a stop signal if public stats failed or update data with new one. // will send a stop signal if public stats failed or update data with new one.
*lock!(handle_request) = Some(spawn( *handle_request.lock().unwrap() = Some(spawn(
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, gui_api_xp, state_xvb, state_p2pool, state_xmrig, state_xp, process, last_algorithm, retry, handle_algo, time_donated, last_request) async move { enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, gui_api_xp, state_xvb, state_p2pool, state_xmrig, state_xp, process, last_algorithm, retry, handle_algo, time_donated, last_request) async move {
// needs to wait here for public stats to get private stats. // needs to wait here for public stats to get private stats.
if last_request_expired || first_loop || should_refresh_before_next_algo { if last_request_expired || first_loop || should_refresh_before_next_algo {
XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await; XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await;
*lock!(last_request) = Instant::now(); *last_request.lock().unwrap() = Instant::now();
} }
// private stats needs valid token and address. // private stats needs valid token and address.
// other stats needs everything to be alive, so just require alive here for now. // other stats needs everything to be alive, so just require alive here for now.
// maybe later differentiate to add a way to get private stats without running the algo ? // maybe later differentiate to add a way to get private stats without running the algo ?
if lock!(process).state == ProcessState::Alive { if process.lock().unwrap().state == ProcessState::Alive {
// get current share to know if we are in a round and this is a required data for algo. // get current share to know if we are in a round and this is a required data for algo.
let share = lock!(gui_api_p2pool).sidechain_shares; let share = gui_api_p2pool.lock().unwrap().sidechain_shares;
debug!("XvB | Number of current shares: {}", share); debug!("XvB | Number of current shares: {}", share);
// private stats can be requested every minute or first loop or if the have almost finished. // private stats can be requested every minute or first loop or if the have almost finished.
if last_request_expired || first_loop || should_refresh_before_next_algo { if last_request_expired || first_loop || should_refresh_before_next_algo {
@ -304,29 +309,29 @@ impl Helper {
&client, &state_p2pool.address, &state_xvb.token, &pub_api, &gui_api, &process, &client, &state_p2pool.address, &state_xvb.token, &pub_api, &gui_api, &process,
) )
.await; .await;
*lock!(last_request) = Instant::now(); *last_request.lock().unwrap() = Instant::now();
// verify in which round type we are // verify in which round type we are
let round = round_type(share, &pub_api); let round = round_type(share, &pub_api);
// refresh the round we participate in. // refresh the round we participate in.
debug!("XvB | Round type: {:#?}", round); debug!("XvB | Round type: {:#?}", round);
lock!(pub_api).stats_priv.round_participate = round; pub_api.lock().unwrap().stats_priv.round_participate = round;
// verify if we are the winner of the current round // verify if we are the winner of the current round
if lock!(pub_api).stats_pub.winner if pub_api.lock().unwrap().stats_pub.winner
== Helper::head_tail_of_monero_address(&state_p2pool.address).as_str() == Helper::head_tail_of_monero_address(&state_p2pool.address).as_str()
{ {
lock!(pub_api).stats_priv.win_current = true pub_api.lock().unwrap().stats_priv.win_current = true
} }
} }
let hashrate = current_controllable_hr(xp_alive, &gui_api_xp, &gui_api_xmrig); let hashrate = current_controllable_hr(xp_alive, &gui_api_xp, &gui_api_xmrig);
let difficulty_data_is_ready = lock!(gui_api_p2pool).p2pool_difficulty_u64 > 100_000; let difficulty_data_is_ready = gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 > 100_000;
if (first_loop || *lock!(retry)|| is_algo_finished) && hashrate > 0.0 && lock!(process).state == ProcessState::Alive && difficulty_data_is_ready if (first_loop || *retry.lock().unwrap()|| is_algo_finished) && hashrate > 0.0 && process.lock().unwrap().state == ProcessState::Alive && difficulty_data_is_ready
{ {
// if algo was started, it must not retry next loop. // if algo was started, it must not retry next loop.
*lock!(retry) = false; *retry.lock().unwrap() = false;
// reset instant because algo will start. // reset instant because algo will start.
*lock!(last_algorithm) = Instant::now(); *last_algorithm.lock().unwrap() = Instant::now();
*lock!(handle_algo) = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, state_xp, time_donated, state_xvb) async move { *handle_algo.lock().unwrap() = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, state_xp, time_donated, state_xvb) async move {
let token_xmrig = if xp_alive { let token_xmrig = if xp_alive {
&state_xp.token &state_xp.token
} else { } else {
@ -356,8 +361,8 @@ impl Helper {
} else { } else {
// if xmrig is still at 0 HR but is alive and algorithm is skipped, recheck first 10s of xmrig inside algorithm next time (in one minute). Don't check if algo failed to start because state was not alive after getting private stats. // if xmrig is still at 0 HR but is alive and algorithm is skipped, recheck first 10s of xmrig inside algorithm next time (in one minute). Don't check if algo failed to start because state was not alive after getting private stats.
if (hashrate == 0.0 || !difficulty_data_is_ready) && lock!(process).state == ProcessState::Alive { if (hashrate == 0.0 || !difficulty_data_is_ready) && process.lock().unwrap().state == ProcessState::Alive {
*lock!(retry) = true *retry.lock().unwrap() = true
} }
} }
@ -366,18 +371,18 @@ impl Helper {
)); ));
} }
// if retry is false, next time the message about waiting for xmrig HR can be shown. // if retry is false, next time the message about waiting for xmrig HR can be shown.
if !*lock!(retry) { if !*retry.lock().unwrap() {
msg_retry_done = false; msg_retry_done = false;
} }
// inform user that algorithm has not yet started because it is waiting for xmrig HR. // inform user that algorithm has not yet started because it is waiting for xmrig HR.
// show this message only once before the start of algo // show this message only once before the start of algo
if *lock!(retry) && !msg_retry_done { if *retry.lock().unwrap() && !msg_retry_done {
let msg = if xp_alive { let msg = if xp_alive {
"Algorithm is waiting for 1 minute average HR of XMRig-Proxy or p2pool data" "Algorithm is waiting for 1 minute average HR of XMRig-Proxy or p2pool data"
} else { } else {
"Algorithm is waiting for 10 seconds average HR of XMRig or p2pool data" "Algorithm is waiting for 10 seconds average HR of XMRig or p2pool data"
}; };
output_console(&mut lock!(gui_api).output, msg, ProcessName::Xvb); output_console(&mut gui_api.lock().unwrap().output, msg, ProcessName::Xvb);
msg_retry_done = true; msg_retry_done = true;
} }
// update indicator (time before switch and mining location) in private stats // update indicator (time before switch and mining location) in private stats
@ -392,7 +397,7 @@ impl Helper {
is_algo_finished, is_algo_finished,
process, process,
pub_api, pub_api,
*lock!(time_donated), *time_donated.lock().unwrap(),
&last_algorithm, &last_algorithm,
); );
// first_loop is done, but maybe retry will allow the algorithm to retry again. // first_loop is done, but maybe retry will allow the algorithm to retry again.
@ -483,27 +488,27 @@ async fn check_conditions_for_start(
info!("XvB | verify address and token"); info!("XvB | verify address and token");
// send to console: token non existent for address on XvB server // send to console: token non existent for address on XvB server
warn!("Xvb | Start ... Partially failed because token and associated address are not existent on XvB server: {}\n", err); warn!("Xvb | Start ... Partially failed because token and associated address are not existent on XvB server: {}\n", err);
output_console(&mut lock!(gui_api).output, &format!("Token and associated address are not valid on XvB API.\nCheck if you are registered.\nError: {}", err), ProcessName::Xvb); output_console(&mut gui_api.lock().unwrap().output, &format!("Token and associated address are not valid on XvB API.\nCheck if you are registered.\nError: {}", err), ProcessName::Xvb);
ProcessState::NotMining ProcessState::NotMining
} else if lock!(process_p2pool).state != ProcessState::Alive { } else if process_p2pool.lock().unwrap().state != ProcessState::Alive {
info!("XvB | verify p2pool node"); info!("XvB | verify p2pool node");
// send to console: p2pool process is not running // send to console: p2pool process is not running
warn!("Xvb | Start ... Partially failed because P2pool instance is not ready."); warn!("Xvb | Start ... Partially failed because P2pool instance is not ready.");
let msg = if lock!(process_p2pool).state == ProcessState::Syncing { let msg = if process_p2pool.lock().unwrap().state == ProcessState::Syncing {
"P2pool process is not ready.\nCheck the P2pool Tab" "P2pool process is not ready.\nCheck the P2pool Tab"
} else { } else {
"P2pool process is not running.\nCheck the P2pool Tab" "P2pool process is not running.\nCheck the P2pool Tab"
}; };
output_console(&mut lock!(gui_api).output, msg, ProcessName::Xvb); output_console(&mut gui_api.lock().unwrap().output, msg, ProcessName::Xvb);
ProcessState::Syncing ProcessState::Syncing
} else if lock!(process_xmrig).state != ProcessState::Alive } else if process_xmrig.lock().unwrap().state != ProcessState::Alive
&& lock!(process_xp).state != ProcessState::Alive && process_xp.lock().unwrap().state != ProcessState::Alive
{ {
// send to console: xmrig process is not running // send to console: xmrig process is not running
warn!("Xvb | Start ... Partially failed because Xmrig or Xmrig-Proxy instance is not running."); warn!("Xvb | Start ... Partially failed because Xmrig or Xmrig-Proxy instance is not running.");
// output the error to console // output the error to console
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"XMRig or Xmrig-Proxy process is not running.\nCheck the Xmrig or Xmrig-Proxy Tab. One of them must be running to start the XvB algorithm.", "XMRig or Xmrig-Proxy process is not running.\nCheck the Xmrig or Xmrig-Proxy Tab. One of them must be running to start the XvB algorithm.",
ProcessName::Xvb, ProcessName::Xvb,
); );
@ -517,14 +522,14 @@ async fn check_conditions_for_start(
// while waiting for xmrig and p2pool or getting right address/token, it can get public stats // while waiting for xmrig and p2pool or getting right address/token, it can get public stats
info!("XvB | print to console state"); info!("XvB | print to console state");
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&["XvB partially started.\n", XVB_PUBLIC_ONLY].concat(), &["XvB partially started.\n", XVB_PUBLIC_ONLY].concat(),
ProcessName::Xvb, ProcessName::Xvb,
); );
} }
// will update the preferred node for the first loop, even if partially started. // will update the preferred node for the first loop, even if partially started.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default()); process_xvb.lock().unwrap().signal = ProcessSignal::UpdateNodes(XvbNode::default());
lock!(process_xvb).state = state; process_xvb.lock().unwrap().state = state;
} }
/// return a bool to continue to next loop if needed. /// return a bool to continue to next loop if needed.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -547,18 +552,18 @@ async fn check_state_outcauses_xvb(
) -> bool { ) -> bool {
// will check if the state can stay as it is. // will check if the state can stay as it is.
// p2pool and xmrig are alive if ready and running (syncing is not alive). // p2pool and xmrig are alive if ready and running (syncing is not alive).
let state = lock!(process).state; let state = process.lock().unwrap().state;
let xp_is_alive = lock!(process_xp).state == ProcessState::Alive; let xp_is_alive = process_xp.lock().unwrap().state == ProcessState::Alive;
let msg_xmrig_or_proxy = if xp_is_alive { "Xmrig-Proxy" } else { "Xmrig" }; let msg_xmrig_or_proxy = if xp_is_alive { "Xmrig-Proxy" } else { "Xmrig" };
// if state is not alive, the algo should stop if it was running and p2pool should be used by xmrig. // if state is not alive, the algo should stop if it was running and p2pool should be used by xmrig.
if let Some(handle) = lock!(handle_algo).as_ref() { if let Some(handle) = handle_algo.lock().unwrap().as_ref() {
// XvB should stop the algo if the state of xp is different from the start. // XvB should stop the algo if the state of xp is different from the start.
if xp_is_alive != xp_start_alive && !handle.is_finished() { if xp_is_alive != xp_start_alive && !handle.is_finished() {
warn!("XvB Process | stop the algorithm because Xmrig-Proxy state changed"); warn!("XvB Process | stop the algorithm because Xmrig-Proxy state changed");
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"Algorithm stopped because Xmrig-Proxy state changed", "Algorithm stopped because Xmrig-Proxy state changed",
ProcessName::Xvb, ProcessName::Xvb,
); );
@ -567,13 +572,13 @@ async fn check_state_outcauses_xvb(
if state != ProcessState::Alive && !handle.is_finished() { if state != ProcessState::Alive && !handle.is_finished() {
handle.abort(); handle.abort();
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"XvB process can not completely continue, algorithm of distribution of HR is stopped.", "XvB process can not completely continue, algorithm of distribution of HR is stopped.",
ProcessName::Xvb ProcessName::Xvb
); );
// only update xmrig if it is alive and wasn't on p2pool already. // only update xmrig if it is alive and wasn't on p2pool already.
if lock!(gui_api).current_node != Some(XvbNode::P2pool) if gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool)
&& (lock!(process_xmrig).state == ProcessState::Alive || xp_is_alive) && (process_xmrig.lock().unwrap().state == ProcessState::Alive || xp_is_alive)
{ {
let token_xmrig = if xp_is_alive { let token_xmrig = if xp_is_alive {
state_xp.token.clone() state_xp.token.clone()
@ -601,7 +606,7 @@ async fn check_state_outcauses_xvb(
{ {
// show to console error about updating xmrig config // show to console error about updating xmrig config
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}", "Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
err err
@ -609,10 +614,10 @@ async fn check_state_outcauses_xvb(
ProcessName::Xvb ProcessName::Xvb
); );
} else { } else {
if xp_is_alive {lock!(pub_api_xp).node = XvbNode::P2pool.to_string();} else {lock!(pub_api_xmrig).node = XvbNode::P2pool.to_string();} if xp_is_alive {pub_api_xp.lock().unwrap().node = XvbNode::P2pool.to_string();} else {pub_api_xmrig.lock().unwrap().node = XvbNode::P2pool.to_string();}
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!("XvB process can not completely continue, falling back to {}", XvbNode::P2pool), &format!("XvB process can not completely continue, falling back to {}", XvbNode::P2pool),
ProcessName::Xvb ProcessName::Xvb
); );
@ -629,9 +634,9 @@ async fn check_state_outcauses_xvb(
return true; return true;
} }
let is_xmrig_alive = lock!(process_xp).state == ProcessState::Alive let is_xmrig_alive = process_xp.lock().unwrap().state == ProcessState::Alive
|| lock!(process_xmrig).state == ProcessState::Alive; || process_xmrig.lock().unwrap().state == ProcessState::Alive;
let is_p2pool_alive = lock!(process_p2pool).state == ProcessState::Alive; let is_p2pool_alive = process_p2pool.lock().unwrap().state == ProcessState::Alive;
let p2pool_xmrig_alive = is_xmrig_alive && is_p2pool_alive; let p2pool_xmrig_alive = is_xmrig_alive && is_p2pool_alive;
// if state is middle because start is not finished yet, it will not do anything. // if state is middle because start is not finished yet, it will not do anything.
match state { match state {
@ -643,25 +648,25 @@ async fn check_state_outcauses_xvb(
// request from public API must be executed at next loop, do not wait for 1 minute. // request from public API must be executed at next loop, do not wait for 1 minute.
*first_loop = true; *first_loop = true;
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"XvB is now partially stopped because p2pool node or XMRig/XMRig-Proxy came offline.\nCheck P2pool and Xmrig/Xmrig-Proxy Tabs", "XvB is now partially stopped because p2pool node or XMRig/XMRig-Proxy came offline.\nCheck P2pool and Xmrig/Xmrig-Proxy Tabs",
ProcessName::Xvb ProcessName::Xvb
); );
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
XVB_PUBLIC_ONLY, XVB_PUBLIC_ONLY,
ProcessName::Xvb, ProcessName::Xvb,
); );
lock!(process).state = ProcessState::Syncing; process.lock().unwrap().state = ProcessState::Syncing;
} }
ProcessState::Syncing if p2pool_xmrig_alive => { ProcessState::Syncing if p2pool_xmrig_alive => {
info!("XvB | started this time with p2pool and xmrig"); info!("XvB | started this time with p2pool and xmrig");
// will put state on middle and update nodes // will put state on middle and update nodes
lock!(process).state = ProcessState::Alive; process.lock().unwrap().state = ProcessState::Alive;
reset_data_xvb(pub_api, gui_api); reset_data_xvb(pub_api, gui_api);
*first_loop = true; *first_loop = true;
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&[ &[
"XvB is now started because p2pool and ", "XvB is now started because p2pool and ",
msg_xmrig_or_proxy, msg_xmrig_or_proxy,
@ -699,7 +704,7 @@ fn signal_interrupt(
// check if STOP or RESTART Signal is given. // check if STOP or RESTART Signal is given.
// if STOP, will put Signal to None, if Restart to Wait // if STOP, will put Signal to None, if Restart to Wait
// in either case, will break from loop. // in either case, will break from loop.
let signal = lock!(process).signal; let signal = process.lock().unwrap().signal;
match signal { match signal {
ProcessSignal::Stop => { ProcessSignal::Stop => {
debug!("P2Pool Watchdog | Stop SIGNAL caught"); debug!("P2Pool Watchdog | Stop SIGNAL caught");
@ -712,13 +717,13 @@ fn signal_interrupt(
// insert the signal into output of XvB // insert the signal into output of XvB
// 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.
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"\n\n\nXvB stopped\n\n\n", "\n\n\nXvB stopped\n\n\n",
ProcessName::Xvb, ProcessName::Xvb,
); );
debug!("XvB Watchdog | Stop SIGNAL done, breaking"); debug!("XvB Watchdog | Stop SIGNAL done, breaking");
lock!(process).signal = ProcessSignal::None; process.lock().unwrap().signal = ProcessSignal::None;
lock!(process).state = ProcessState::Dead; process.lock().unwrap().state = ProcessState::Dead;
// reset stats // reset stats
reset_data_xvb(pub_api, gui_api); reset_data_xvb(pub_api, gui_api);
return true; return true;
@ -729,12 +734,12 @@ fn signal_interrupt(
info!("XvB Watchdog | Stopped ... Uptime was: [{}]", uptime); info!("XvB Watchdog | Stopped ... Uptime was: [{}]", uptime);
// no output to console because service will be started with fresh output. // no output to console because service will be started with fresh output.
debug!("XvB Watchdog | Restart SIGNAL done, breaking"); debug!("XvB Watchdog | Restart SIGNAL done, breaking");
lock!(process).state = ProcessState::Waiting; process.lock().unwrap().state = ProcessState::Waiting;
reset_data_xvb(pub_api, gui_api); reset_data_xvb(pub_api, gui_api);
return true; return true;
} }
ProcessSignal::UpdateNodes(node) => { ProcessSignal::UpdateNodes(node) => {
if lock!(process).state != ProcessState::Waiting { if process.lock().unwrap().state != ProcessState::Waiting {
warn!("received the UpdateNode signal"); warn!("received the UpdateNode signal");
let token_xmrig = if xp_alive { let token_xmrig = if xp_alive {
state_xp.token.clone() state_xp.token.clone()
@ -752,10 +757,10 @@ fn signal_interrupt(
// if both XvB nodes fail after checking, process will be partially stopped and a new spawn will verify if nodes are again online and so will continue the process completely if that's the case. // if both XvB nodes fail after checking, process will be partially stopped and a new spawn will verify if nodes are again online and so will continue the process completely if that's the case.
// if P2pool, the process has to stop the algo and continue partially. The process will continue completely if the confitions are met again. // if P2pool, the process has to stop the algo and continue partially. The process will continue completely if the confitions are met again.
// if XvB was not alive, then if it is for XvB nodes, it will check and update preferred node and set XMRig to P2pool if that's not the case. // if XvB was not alive, then if it is for XvB nodes, it will check and update preferred node and set XMRig to P2pool if that's not the case.
let was_alive = lock!(process).state == ProcessState::Alive; let was_alive = process.lock().unwrap().state == ProcessState::Alive;
// so it won't execute another signal of update nodes if it is already doing it. // so it won't execute another signal of update nodes if it is already doing it.
lock!(process).state = ProcessState::Waiting; process.lock().unwrap().state = ProcessState::Waiting;
lock!(process).signal = ProcessSignal::None; process.lock().unwrap().signal = ProcessSignal::None;
spawn( spawn(
enc!((node, process, client, gui_api, pub_api, was_alive, address, token_xmrig, gui_api_xmrig, gui_api_xp,process_xrig) async move { enc!((node, process, client, gui_api, pub_api, was_alive, address, token_xmrig, gui_api_xmrig, gui_api_xp,process_xrig) async move {
warn!("in spawn of UpdateNodes"); warn!("in spawn of UpdateNodes");
@ -764,11 +769,11 @@ fn signal_interrupt(
warn!("current is XvB node ? update to see which is available"); warn!("current is XvB node ? update to see which is available");
// a node is failing. We need to first verify if a node is available // a node is failing. We need to first verify if a node is available
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await; XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
if lock!(process).state == ProcessState::OfflineNodesAll { if process.lock().unwrap().state == ProcessState::OfflineNodesAll {
// No available nodes, so launch a process to verify periodically. // No available nodes, so launch a process to verify periodically.
sleep(Duration::from_secs(10)).await; sleep(Duration::from_secs(10)).await;
warn!("node fail, set spawn that will retry nodes and update state."); warn!("node fail, set spawn that will retry nodes and update state.");
while lock!(process).state == ProcessState::OfflineNodesAll { while process.lock().unwrap().state == ProcessState::OfflineNodesAll {
// this spawn will stay alive until nodes are joignable or XvB process is stopped or failed. // this spawn will stay alive until nodes are joignable or XvB process is stopped or failed.
XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await; XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await;
sleep(Duration::from_secs(10)).await; sleep(Duration::from_secs(10)).await;
@ -780,12 +785,12 @@ fn signal_interrupt(
}, },
XvbNode::NorthAmerica|XvbNode::Europe if !was_alive => { XvbNode::NorthAmerica|XvbNode::Europe if !was_alive => {
lock!(process).state = ProcessState::Syncing; process.lock().unwrap().state = ProcessState::Syncing;
// Probably a start. We don't consider XMRig using XvB nodes without algo. // Probably a start. We don't consider XMRig using XvB nodes without algo.
// can update xmrig and check status of state in the same time. // can update xmrig and check status of state in the same time.
// Need to set XMRig to P2Pool if it wasn't. XMRig should have populated this value at his start. // Need to set XMRig to P2Pool if it wasn't. XMRig should have populated this value at his start.
// but if xmrig didn't start, don't update it. // but if xmrig didn't start, don't update it.
if lock!(process_xrig).state == ProcessState::Alive && lock!(gui_api).current_node != Some(XvbNode::P2pool) { if process_xrig.lock().unwrap().state == ProcessState::Alive && gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool) {
spawn(enc!((client, token_xmrig, address, gui_api_xmrig, gui_api_xp, gui_api) async move{ spawn(enc!((client, token_xmrig, address, gui_api_xmrig, gui_api_xp, gui_api) async move{
let url_api = api_url_xmrig(xp_alive, true); let url_api = api_url_xmrig(xp_alive, true);
warn!("update xmrig to use node ?"); warn!("update xmrig to use node ?");
@ -804,7 +809,7 @@ fn signal_interrupt(
"XMRig" "XMRig"
}; };
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}", "Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
err err
@ -813,9 +818,9 @@ fn signal_interrupt(
} else { } else {
// update node xmrig // update node xmrig
if xp_alive { if xp_alive {
lock!(gui_api_xp).node = XvbNode::P2pool.to_string(); gui_api_xp.lock().unwrap().node = XvbNode::P2pool.to_string();
} else { } else {
lock!(gui_api_xmrig).node = XvbNode::P2pool.to_string(); gui_api_xmrig.lock().unwrap().node = XvbNode::P2pool.to_string();
}; };
} }
} }
@ -832,20 +837,21 @@ fn signal_interrupt(
false false
} }
fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) { fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) {
let current_node = mem::take(&mut lock!(pub_api).current_node.clone()); let current_node = mem::take(&mut pub_api.lock().unwrap().current_node.clone());
let runtime_mode = mem::take(&mut lock!(gui_api).stats_priv.runtime_mode); let runtime_mode = mem::take(&mut gui_api.lock().unwrap().stats_priv.runtime_mode);
let runtime_manual_amount = mem::take(&mut lock!(gui_api).stats_priv.runtime_manual_amount); let runtime_manual_amount =
mem::take(&mut gui_api.lock().unwrap().stats_priv.runtime_manual_amount);
// let output = mem::take(&mut lock!(gui_api).output); // let output = mem::take(&mut gui_api.lock().unwrap().output);
*lock!(pub_api) = PubXvbApi::new(); *pub_api.lock().unwrap() = PubXvbApi::new();
*lock!(gui_api) = PubXvbApi::new(); *gui_api.lock().unwrap() = PubXvbApi::new();
// to keep the value modified by xmrig even if xvb is dead. // to keep the value modified by xmrig even if xvb is dead.
lock!(pub_api).current_node = current_node; pub_api.lock().unwrap().current_node = current_node;
// to not loose the information of runtime hero mode between restart // to not loose the information of runtime hero mode between restart
lock!(gui_api).stats_priv.runtime_mode = runtime_mode; gui_api.lock().unwrap().stats_priv.runtime_mode = runtime_mode;
lock!(gui_api).stats_priv.runtime_manual_amount = runtime_manual_amount; gui_api.lock().unwrap().stats_priv.runtime_manual_amount = runtime_manual_amount;
// message while starting must be preserved. // message while starting must be preserved.
// lock!(pub_api).output = output; // pub_api.lock().unwrap().output = output;
} }
// print date time to console output in same format than xmrig // print date time to console output in same format than xmrig
fn update_indicator_algo( fn update_indicator_algo(
@ -856,14 +862,17 @@ fn update_indicator_algo(
time_donated: u32, time_donated: u32,
last_algorithm: &Arc<Mutex<Instant>>, last_algorithm: &Arc<Mutex<Instant>>,
) { ) {
if is_algo_started_once && !is_algo_finished && lock!(process).state == ProcessState::Alive { if is_algo_started_once
let node = lock!(pub_api).current_node; && !is_algo_finished
&& process.lock().unwrap().state == ProcessState::Alive
{
let node = pub_api.lock().unwrap().current_node;
let msg_indicator = match node { let msg_indicator = match node {
Some(XvbNode::P2pool) if time_donated > 0 => { Some(XvbNode::P2pool) if time_donated > 0 => {
// algo is mining on p2pool but will switch to XvB after // algo is mining on p2pool but will switch to XvB after
// show time remaining on p2pool // show time remaining on p2pool
lock!(pub_api).stats_priv.time_switch_node = XVB_TIME_ALGO pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32) .checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
.unwrap_or_default() .unwrap_or_default()
.checked_sub(time_donated) .checked_sub(time_donated)
@ -874,17 +883,17 @@ fn update_indicator_algo(
// algo is mining on XvB or complelty mining on p2pool. // algo is mining on XvB or complelty mining on p2pool.
// show remaining time before next decision of algo // show remaining time before next decision of algo
// because time of last algorithm could depass a little bit XVB_TIME_ALGO before next run, check the sub. // because time of last algorithm could depass a little bit XVB_TIME_ALGO before next run, check the sub.
lock!(pub_api).stats_priv.time_switch_node = XVB_TIME_ALGO pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32) .checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
.unwrap_or_default(); .unwrap_or_default();
"time until next decision of algorithm".to_string() "time until next decision of algorithm".to_string()
} }
}; };
lock!(pub_api).stats_priv.msg_indicator = msg_indicator; pub_api.lock().unwrap().stats_priv.msg_indicator = msg_indicator;
} else { } else {
// if algo is not running or process not alive // if algo is not running or process not alive
lock!(pub_api).stats_priv.time_switch_node = 0; pub_api.lock().unwrap().stats_priv.time_switch_node = 0;
lock!(pub_api).stats_priv.msg_indicator = "Algorithm is not running".to_string(); pub_api.lock().unwrap().stats_priv.msg_indicator = "Algorithm is not running".to_string();
} }
} }
@ -912,16 +921,16 @@ fn current_controllable_hr(
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>, gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
) -> f32 { ) -> f32 {
if xp_alive { if xp_alive {
if lock!(gui_api_xp).hashrate_10m > 0.0 { if gui_api_xp.lock().unwrap().hashrate_10m > 0.0 {
lock!(gui_api_xp).hashrate_10m gui_api_xp.lock().unwrap().hashrate_10m
} else { } else {
lock!(gui_api_xp).hashrate_1m gui_api_xp.lock().unwrap().hashrate_1m
} }
} else if lock!(gui_api_xmrig).hashrate_raw_15m > 0.0 { } else if gui_api_xmrig.lock().unwrap().hashrate_raw_15m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_15m gui_api_xmrig.lock().unwrap().hashrate_raw_15m
} else if lock!(gui_api_xmrig).hashrate_raw_1m > 0.0 { } else if gui_api_xmrig.lock().unwrap().hashrate_raw_1m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_1m gui_api_xmrig.lock().unwrap().hashrate_raw_1m
} else { } else {
lock!(gui_api_xmrig).hashrate_raw gui_api_xmrig.lock().unwrap().hashrate_raw
} }
} }

View file

@ -11,7 +11,6 @@ use tokio::spawn;
use crate::{ use crate::{
components::node::{GetInfo, TIMEOUT_NODE_PING}, components::node::{GetInfo, TIMEOUT_NODE_PING},
helper::{xvb::output_console, Process, ProcessName, ProcessState}, helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
GUPAX_VERSION_UNDERSCORE, XVB_NODE_EU, XVB_NODE_NA, XVB_NODE_PORT, XVB_NODE_RPC, GUPAX_VERSION_UNDERSCORE, XVB_NODE_EU, XVB_NODE_NA, XVB_NODE_PORT, XVB_NODE_RPC,
}; };
@ -112,16 +111,16 @@ impl XvbNode {
// if both nodes are dead, then the state of the process must be NodesOffline // if both nodes are dead, then the state of the process must be NodesOffline
info!("XvB node ping, all offline or ping failed, switching back to local p2pool",); info!("XvB node ping, all offline or ping failed, switching back to local p2pool",);
output_console( output_console(
&mut lock!(gui_api_xvb).output, &mut gui_api_xvb.lock().unwrap().output,
"XvB node ping, all offline or ping failed, switching back to local p2pool", "XvB node ping, all offline or ping failed, switching back to local p2pool",
ProcessName::Xvb, ProcessName::Xvb,
); );
lock!(process_xvb).state = ProcessState::OfflineNodesAll; process_xvb.lock().unwrap().state = ProcessState::OfflineNodesAll;
} else { } else {
// if node is up and because update_fastest is used only if token/address is valid, it means XvB process is Alive. // if node is up and because update_fastest is used only if token/address is valid, it means XvB process is Alive.
info!("XvB node ping, both online and best is {}", node.url()); info!("XvB node ping, both online and best is {}", node.url());
output_console( output_console(
&mut lock!(gui_api_xvb).output, &mut gui_api_xvb.lock().unwrap().output,
&format!("XvB node ping, {} is selected as the fastest.", node), &format!("XvB node ping, {} is selected as the fastest.", node),
ProcessName::Xvb, ProcessName::Xvb,
); );
@ -129,13 +128,13 @@ impl XvbNode {
// could be used by xmrig who signal that a node is not joignable // could be used by xmrig who signal that a node is not joignable
// or by the start of xvb // or by the start of xvb
// next iteration of the loop of XvB process will verify if all conditions are met to be alive. // next iteration of the loop of XvB process will verify if all conditions are met to be alive.
if lock!(process_xvb).state != ProcessState::Syncing if process_xvb.lock().unwrap().state != ProcessState::Syncing
&& lock!(process_xvb).state != ProcessState::Retry && process_xvb.lock().unwrap().state != ProcessState::Retry
{ {
lock!(process_xvb).state = ProcessState::Syncing; process_xvb.lock().unwrap().state = ProcessState::Syncing;
} }
} }
lock!(pub_api_xvb).stats_priv.node = node; pub_api_xvb.lock().unwrap().stats_priv.node = node;
} }
async fn ping(ip: &str, client: &Client) -> u128 { async fn ping(ip: &str, client: &Client) -> u128 {
let request = client let request = client

View file

@ -12,7 +12,6 @@ use tokio::time::sleep;
use crate::{ use crate::{
disk::state::ManualDonationLevel, disk::state::ManualDonationLevel,
helper::{xvb::output_console, Process, ProcessName, ProcessState}, helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
XVB_URL, XVB_URL,
}; };
use crate::{ use crate::{
@ -122,7 +121,7 @@ impl XvbPrivStats {
match XvbPrivStats::request_api(client, address, token).await { match XvbPrivStats::request_api(client, address, token).await {
Ok(new_data) => { Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK"); debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_priv = new_data; pub_api.lock().unwrap().stats_priv = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop. // if last request failed, we are now ready to show stats again and maybe be alive next loop.
} }
Err(err) => { Err(err) => {
@ -131,17 +130,17 @@ impl XvbPrivStats {
XVB_URL, err XVB_URL, err
); );
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to retrieve private stats from {} because of this error: {}", "Failure to retrieve private stats from {} because of this error: {}",
XVB_URL, err XVB_URL, err
), ),
ProcessName::Xvb, ProcessName::Xvb,
); );
lock!(process).state = ProcessState::Retry; process.lock().unwrap().state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service. // sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"Waiting 10 seconds before trying to get stats again.", "Waiting 10 seconds before trying to get stats again.",
ProcessName::Xvb, ProcessName::Xvb,
); );

View file

@ -11,7 +11,6 @@ use tokio::time::sleep;
use crate::{ use crate::{
helper::{xvb::output_console, Process, ProcessName, ProcessState}, helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
XVB_URL_PUBLIC_API, XVB_URL_PUBLIC_API,
}; };
@ -64,12 +63,12 @@ impl XvbPubStats {
match XvbPubStats::request_api(client).await { match XvbPubStats::request_api(client).await {
Ok(new_data) => { Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK"); debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_pub = new_data; pub_api.lock().unwrap().stats_pub = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop. // if last request failed, we are now ready to show stats again and maybe be alive next loop.
if lock!(process).state == ProcessState::Retry { if process.lock().unwrap().state == ProcessState::Retry {
lock!(process).state = ProcessState::Syncing; process.lock().unwrap().state = ProcessState::Syncing;
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"Stats are now working again after last successful request.", "Stats are now working again after last successful request.",
ProcessName::Xvb, ProcessName::Xvb,
); );
@ -82,9 +81,9 @@ impl XvbPubStats {
); );
// output the error to console // output the error to console
// if error already present, no need to print it multiple times. // if error already present, no need to print it multiple times.
if lock!(process).state != ProcessState::Retry { if process.lock().unwrap().state != ProcessState::Retry {
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
&format!( &format!(
"Failure to retrieve public stats from {}\nWill retry shortly...", "Failure to retrieve public stats from {}\nWill retry shortly...",
XVB_URL_PUBLIC_API XVB_URL_PUBLIC_API
@ -93,10 +92,10 @@ impl XvbPubStats {
); );
} }
// we stop the algo (will be stopped by the check status on next loop) because we can't make the rest work without public stats. (winner in xvb private stats). // we stop the algo (will be stopped by the check status on next loop) because we can't make the rest work without public stats. (winner in xvb private stats).
lock!(process).state = ProcessState::Retry; process.lock().unwrap().state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service. // sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console( output_console(
&mut lock!(gui_api).output, &mut gui_api.lock().unwrap().output,
"Waiting 10 seconds before trying to get stats again.", "Waiting 10 seconds before trying to get stats again.",
ProcessName::Xvb, ProcessName::Xvb,
); );

View file

@ -4,7 +4,7 @@ use derive_more::Display;
use serde::Deserialize; use serde::Deserialize;
use crate::{ use crate::{
macros::lock, XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR, XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR,
XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_SIDE_MARGIN_1H, XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_SIDE_MARGIN_1H,
}; };
@ -30,7 +30,7 @@ pub enum XvbRound {
pub(crate) fn round_type(share: u32, pub_api: &Arc<Mutex<PubXvbApi>>) -> Option<XvbRound> { pub(crate) fn round_type(share: u32, pub_api: &Arc<Mutex<PubXvbApi>>) -> Option<XvbRound> {
if share > 0 { if share > 0 {
let stats_priv = &lock!(pub_api).stats_priv; let stats_priv = &pub_api.lock().unwrap().stats_priv;
match ( match (
((stats_priv.donor_1hr_avg * 1000.0) * XVB_SIDE_MARGIN_1H) as u32, ((stats_priv.donor_1hr_avg * 1000.0) * XVB_SIDE_MARGIN_1H) as u32,
(stats_priv.donor_24hr_avg * 1000.0) as u32, (stats_priv.donor_24hr_avg * 1000.0) as u32,

View file

@ -8,8 +8,8 @@ use crate::utils::regex::Regexes;
use std::io::Write; use std::io::Write;
//---------------------------------------------------------------------------------------------------- Init functions //---------------------------------------------------------------------------------------------------- Init functions
use crate::app::App; use crate::app::App;
use crate::disk::state::*;
use crate::{components::node::Ping, miscs::clamp_scale}; use crate::{components::node::Ping, miscs::clamp_scale};
use crate::{disk::state::*, utils::macros::lock};
use crate::{info, warn}; use crate::{info, warn};
use eframe::NativeOptions; use eframe::NativeOptions;
use egui::TextStyle::Small; use egui::TextStyle::Small;
@ -240,7 +240,7 @@ pub fn init_auto(app: &mut App) {
Arc::clone(&app.sudo), Arc::clone(&app.sudo),
); );
} else { } else {
lock!(app.sudo).signal = ProcessSignal::Start; app.sudo.lock().unwrap().signal = ProcessSignal::Start;
app.error_state.ask_sudo(&app.sudo); app.error_state.ask_sudo(&app.sudo);
} }
} else { } else {

View file

@ -78,7 +78,7 @@ pub fn print_disk_file(path: &PathBuf) {
#[cold] #[cold]
#[inline(never)] #[inline(never)]
pub fn print_gupax_p2pool_api(gupax_p2pool_api: &Arc<Mutex<GupaxP2poolApi>>) { pub fn print_gupax_p2pool_api(gupax_p2pool_api: &Arc<Mutex<GupaxP2poolApi>>) {
let api = lock!(gupax_p2pool_api); let api = gupax_p2pool_api.lock().unwrap();
let log = match std::fs::read_to_string(&api.path_log) { let log = match std::fs::read_to_string(&api.path_log) {
Ok(string) => string, Ok(string) => string,
Err(e) => { Err(e) => {
@ -130,7 +130,6 @@ pub fn cmp_f64(a: f64, b: f64) -> std::cmp::Ordering {
use crate::disk::gupax_p2pool_api::GupaxP2poolApi; use crate::disk::gupax_p2pool_api::GupaxP2poolApi;
use crate::helper::ProcessName; use crate::helper::ProcessName;
use crate::utils::macros::lock;
use chrono::Local; use chrono::Local;
use log::error; use log::error;
use log::warn; use log::warn;

View file

@ -19,40 +19,10 @@
// //
// | MACRO | PURPOSE | EQUIVALENT CODE | // | MACRO | PURPOSE | EQUIVALENT CODE |
// |---------|-----------------------------------------------|------------------------------------------------------------| // |---------|-----------------------------------------------|------------------------------------------------------------|
// | lock | Lock an [Arc<Mutex>] | a.lock().unwrap() |
// | lock2 | Lock a field inside a struct, both Arc<Mutex> | a.lock().unwrap().b.lock().unwrap() |
// | arc_mut | Create a new [Arc<Mutex>] | std::sync::Arc::new(std::sync::Mutex::new(my_value)) | // | arc_mut | Create a new [Arc<Mutex>] | std::sync::Arc::new(std::sync::Mutex::new(my_value)) |
// | sleep | Sleep the current thread for x milliseconds | std::thread::sleep(std::time::Duration::from_millis(1000)) | // | sleep | Sleep the current thread for x milliseconds | std::thread::sleep(std::time::Duration::from_millis(1000)) |
// | flip | Flip a bool in place | my_bool = !my_bool | // | flip | Flip a bool in place | my_bool = !my_bool |
// //
// Hopefully the long ass code on the right justifies usage of macros :D
//
// [lock2!()] works like this: "lock2!(my_first, my_second)"
// and expects it be a [Struct]-[field] relationship, e.g:
//
// let my_first = Arc::new(Mutex::new(Struct {
// my_second: Arc::new(Mutex::new(true)),
// }));
// lock2!(my_first, my_second);
//
// The equivalent code is: "my_first.lock().unwrap().my_second.lock().unwrap()" (see? this is long as hell)
// Locks and unwraps an [Arc<Mutex<T>]
macro_rules! lock {
($arc_mutex:expr) => {
$arc_mutex.lock().unwrap()
};
}
pub(crate) use lock;
// Locks and unwraps a field of a struct, both of them being [Arc<Mutex>]
// Yes, I know this is bad code.
macro_rules! lock2 {
($arc_mutex:expr, $arc_mutex_two:ident) => {
$arc_mutex.lock().unwrap().$arc_mutex_two.lock().unwrap()
};
}
pub(crate) use lock2;
// Creates a new [Arc<Mutex<T>] // Creates a new [Arc<Mutex<T>]
macro_rules! arc_mut { macro_rules! arc_mut {
@ -83,31 +53,11 @@ pub(crate) use flip;
//---------------------------------------------------------------------------------------------------- TESTS //---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#[test]
fn lock() {
use std::sync::{Arc, Mutex};
let arc_mutex = Arc::new(Mutex::new(false));
*lock!(arc_mutex) = true;
assert!(*lock!(arc_mutex));
}
#[test]
fn lock2() {
struct Ab {
a: Arc<Mutex<bool>>,
}
use std::sync::{Arc, Mutex};
let arc_mutex = Arc::new(Mutex::new(Ab {
a: Arc::new(Mutex::new(false)),
}));
*lock2!(arc_mutex, a) = true;
assert!(*lock2!(arc_mutex, a));
}
#[test] #[test]
fn arc_mut() { fn arc_mut() {
let a = arc_mut!(false); let a = arc_mut!(false);
assert!(!(*lock!(a))); assert!(!(*a.lock().unwrap()));
} }
#[test] #[test]

View file

@ -23,7 +23,6 @@ use crate::{
constants::*, constants::*,
disk::state::Xmrig, disk::state::Xmrig,
helper::{Helper, ProcessSignal}, helper::{Helper, ProcessSignal},
macros::*,
}; };
use log::*; use log::*;
use std::{ use std::{
@ -88,7 +87,7 @@ impl SudoState {
// Resets the state. // Resets the state.
pub fn reset(state: &Arc<Mutex<Self>>) { pub fn reset(state: &Arc<Mutex<Self>>) {
Self::wipe(state); Self::wipe(state);
let mut state = lock!(state); let mut state = state.lock().unwrap();
state.testing = false; state.testing = false;
state.success = false; state.success = false;
// state.signal = ProcessSignal::None; // state.signal = ProcessSignal::None;
@ -101,7 +100,7 @@ impl SudoState {
pub fn wipe(state: &Arc<Mutex<Self>>) { pub fn wipe(state: &Arc<Mutex<Self>>) {
let mut new = String::with_capacity(256); let mut new = String::with_capacity(256);
// new is now == old, and vice-versa. // new is now == old, and vice-versa.
std::mem::swap(&mut new, &mut lock!(state).pass); std::mem::swap(&mut new, &mut state.lock().unwrap().pass);
// we're wiping & dropping the old pass here. // we're wiping & dropping the old pass here.
new.zeroize(); new.zeroize();
std::mem::drop(new); std::mem::drop(new);
@ -124,7 +123,7 @@ impl SudoState {
let path = path.to_path_buf(); let path = path.to_path_buf();
thread::spawn(move || { thread::spawn(move || {
// Set to testing // Set to testing
lock!(state).testing = true; state.lock().unwrap().testing = true;
// Make sure sudo timestamp is reset // Make sure sudo timestamp is reset
let reset = Command::new("sudo") let reset = Command::new("sudo")
@ -138,8 +137,8 @@ impl SudoState {
Err(e) => { Err(e) => {
error!("Sudo | Couldn't reset timestamp: {}", e); error!("Sudo | Couldn't reset timestamp: {}", e);
Self::wipe(&state); Self::wipe(&state);
lock!(state).msg = format!("Sudo error: {}", e); state.lock().unwrap().msg = format!("Sudo error: {}", e);
lock!(state).testing = false; state.lock().unwrap().testing = false;
return; return;
} }
} }
@ -155,7 +154,9 @@ impl SudoState {
// Write pass to STDIN // Write pass to STDIN
let mut stdin = sudo.stdin.take().unwrap(); let mut stdin = sudo.stdin.take().unwrap();
stdin.write_all(lock!(state).pass.as_bytes()).unwrap(); stdin
.write_all(state.lock().unwrap().pass.as_bytes())
.unwrap();
drop(stdin); drop(stdin);
// Sudo re-prompts and will hang. // Sudo re-prompts and will hang.
@ -166,7 +167,7 @@ impl SudoState {
Ok(Some(code)) => { Ok(Some(code)) => {
if code.success() { if code.success() {
info!("Sudo | Password ... OK!"); info!("Sudo | Password ... OK!");
lock!(state).success = true; state.lock().unwrap().success = true;
break; break;
} }
} }
@ -177,8 +178,8 @@ impl SudoState {
Err(e) => { Err(e) => {
error!("Sudo | Couldn't reset timestamp: {}", e); error!("Sudo | Couldn't reset timestamp: {}", e);
Self::wipe(&state); Self::wipe(&state);
lock!(state).msg = format!("Sudo error: {}", e); state.lock().unwrap().msg = format!("Sudo error: {}", e);
lock!(state).testing = false; state.lock().unwrap().testing = false;
return; return;
} }
} }
@ -186,8 +187,8 @@ impl SudoState {
if let Err(e) = sudo.kill() { if let Err(e) = sudo.kill() {
warn!("Sudo | Kill error (it probably already exited): {}", e); warn!("Sudo | Kill error (it probably already exited): {}", e);
} }
if lock!(state).success { if state.lock().unwrap().success {
match lock!(state).signal { match state.lock().unwrap().signal {
ProcessSignal::Restart => crate::helper::Helper::restart_xmrig( ProcessSignal::Restart => crate::helper::Helper::restart_xmrig(
&helper, &helper,
&xmrig, &xmrig,
@ -203,11 +204,11 @@ impl SudoState {
), ),
} }
} else { } else {
lock!(state).msg = "Incorrect password! (or sudo timeout)".to_string(); state.lock().unwrap().msg = "Incorrect password! (or sudo timeout)".to_string();
Self::wipe(&state); Self::wipe(&state);
} }
lock!(state).signal = ProcessSignal::None; state.lock().unwrap().signal = ProcessSignal::None;
lock!(state).testing = false; state.lock().unwrap().testing = false;
}); });
} }
} }