mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2025-01-04 13:09:21 +00:00
feat: integrate monerod
This commit is contained in:
parent
bfcaebb82f
commit
40f85893c6
23 changed files with 1641 additions and 173 deletions
|
@ -52,6 +52,12 @@ impl eframe::App for App {
|
||||||
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...");
|
||||||
|
let node = lock!(self.node);
|
||||||
|
let node_is_alive = node.is_alive();
|
||||||
|
let node_is_waiting = node.is_waiting();
|
||||||
|
let node_state = node.state;
|
||||||
|
drop(node);
|
||||||
|
|
||||||
// This sets the top level Ui dimensions.
|
// This sets the top level Ui dimensions.
|
||||||
// Used as a reference for other uis.
|
// Used as a reference for other uis.
|
||||||
|
@ -101,6 +107,7 @@ impl eframe::App for App {
|
||||||
self.top_panel(ctx);
|
self.top_panel(ctx);
|
||||||
self.bottom_panel(
|
self.bottom_panel(
|
||||||
ctx,
|
ctx,
|
||||||
|
node_state,
|
||||||
p2pool_state,
|
p2pool_state,
|
||||||
xmrig_state,
|
xmrig_state,
|
||||||
xmrig_proxy_state,
|
xmrig_proxy_state,
|
||||||
|
@ -109,10 +116,12 @@ impl eframe::App for App {
|
||||||
wants_input,
|
wants_input,
|
||||||
p2pool_is_waiting,
|
p2pool_is_waiting,
|
||||||
xmrig_is_waiting,
|
xmrig_is_waiting,
|
||||||
|
node_is_waiting,
|
||||||
xmrig_proxy_is_waiting,
|
xmrig_proxy_is_waiting,
|
||||||
xvb_is_waiting,
|
xvb_is_waiting,
|
||||||
p2pool_is_alive,
|
p2pool_is_alive,
|
||||||
xmrig_is_alive,
|
xmrig_is_alive,
|
||||||
|
node_is_alive,
|
||||||
xmrig_proxy_is_alive,
|
xmrig_proxy_is_alive,
|
||||||
xvb_is_alive,
|
xvb_is_alive,
|
||||||
);
|
);
|
||||||
|
@ -124,6 +133,7 @@ impl eframe::App for App {
|
||||||
ctx,
|
ctx,
|
||||||
frame,
|
frame,
|
||||||
key,
|
key,
|
||||||
|
node_is_alive,
|
||||||
p2pool_is_alive,
|
p2pool_is_alive,
|
||||||
xmrig_is_alive,
|
xmrig_is_alive,
|
||||||
xmrig_proxy_is_alive,
|
xmrig_proxy_is_alive,
|
||||||
|
|
|
@ -126,7 +126,8 @@ impl App {
|
||||||
Tab::About => self.tab = Tab::Xvb,
|
Tab::About => self.tab = Tab::Xvb,
|
||||||
Tab::Status => self.tab = Tab::About,
|
Tab::Status => self.tab = Tab::About,
|
||||||
Tab::Gupax => self.tab = Tab::Status,
|
Tab::Gupax => self.tab = Tab::Status,
|
||||||
Tab::P2pool => self.tab = Tab::Gupax,
|
Tab::Node => self.tab = Tab::Gupax,
|
||||||
|
Tab::P2pool => self.tab = Tab::Node,
|
||||||
Tab::Xmrig => self.tab = Tab::P2pool,
|
Tab::Xmrig => self.tab = Tab::P2pool,
|
||||||
Tab::XmrigProxy => self.tab = Tab::Xmrig,
|
Tab::XmrigProxy => self.tab = Tab::Xmrig,
|
||||||
Tab::Xvb => self.tab = Tab::XmrigProxy,
|
Tab::Xvb => self.tab = Tab::XmrigProxy,
|
||||||
|
@ -136,7 +137,8 @@ impl App {
|
||||||
match self.tab {
|
match self.tab {
|
||||||
Tab::About => self.tab = Tab::Status,
|
Tab::About => self.tab = Tab::Status,
|
||||||
Tab::Status => self.tab = Tab::Gupax,
|
Tab::Status => self.tab = Tab::Gupax,
|
||||||
Tab::Gupax => self.tab = Tab::P2pool,
|
Tab::Gupax => self.tab = Tab::Node,
|
||||||
|
Tab::Node => self.tab = Tab::P2pool,
|
||||||
Tab::P2pool => self.tab = Tab::Xmrig,
|
Tab::P2pool => self.tab = Tab::Xmrig,
|
||||||
Tab::Xmrig => self.tab = Tab::XmrigProxy,
|
Tab::Xmrig => self.tab = Tab::XmrigProxy,
|
||||||
Tab::XmrigProxy => self.tab = Tab::Xvb,
|
Tab::XmrigProxy => self.tab = Tab::Xvb,
|
||||||
|
@ -151,6 +153,7 @@ impl App {
|
||||||
Submenu::Benchmarks => self.state.status.submenu = Submenu::P2pool,
|
Submenu::Benchmarks => self.state.status.submenu = Submenu::P2pool,
|
||||||
},
|
},
|
||||||
Tab::Gupax => flip!(self.state.gupax.simple),
|
Tab::Gupax => flip!(self.state.gupax.simple),
|
||||||
|
Tab::Node => flip!(self.state.node.simple),
|
||||||
Tab::P2pool => flip!(self.state.p2pool.simple),
|
Tab::P2pool => flip!(self.state.p2pool.simple),
|
||||||
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
||||||
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
||||||
|
@ -170,6 +173,7 @@ impl App {
|
||||||
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
||||||
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
||||||
Tab::Xvb => flip!(self.state.xvb.simple),
|
Tab::Xvb => flip!(self.state.xvb.simple),
|
||||||
|
Tab::Node => flip!(self.state.node.simple),
|
||||||
Tab::About => (),
|
Tab::About => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::disk::state::State;
|
||||||
use crate::errors::ErrorButtons;
|
use crate::errors::ErrorButtons;
|
||||||
use crate::errors::ErrorFerris;
|
use crate::errors::ErrorFerris;
|
||||||
use crate::errors::ErrorState;
|
use crate::errors::ErrorState;
|
||||||
|
use crate::helper::node::PubNodeApi;
|
||||||
use crate::helper::p2pool::ImgP2pool;
|
use crate::helper::p2pool::ImgP2pool;
|
||||||
use crate::helper::p2pool::PubP2poolApi;
|
use crate::helper::p2pool::PubP2poolApi;
|
||||||
use crate::helper::xrig::xmrig::ImgXmrig;
|
use crate::helper::xrig::xmrig::ImgXmrig;
|
||||||
|
@ -103,10 +104,12 @@ pub struct App {
|
||||||
// This includes the "helper" threads public P2Pool/XMRig's API.
|
// This includes the "helper" threads public P2Pool/XMRig's API.
|
||||||
pub helper: Arc<Mutex<Helper>>, // [Helper] state, mostly for Gupax uptime
|
pub helper: Arc<Mutex<Helper>>, // [Helper] state, mostly for Gupax uptime
|
||||||
pub pub_sys: Arc<Mutex<Sys>>, // [Sys] state, read by [Status], mutated by [Helper]
|
pub pub_sys: Arc<Mutex<Sys>>, // [Sys] state, read by [Status], mutated by [Helper]
|
||||||
|
pub node: Arc<Mutex<Process>>, // [Node] process state
|
||||||
pub p2pool: Arc<Mutex<Process>>, // [P2Pool] process state
|
pub p2pool: Arc<Mutex<Process>>, // [P2Pool] process state
|
||||||
pub xmrig: Arc<Mutex<Process>>, // [XMRig] process state
|
pub xmrig: Arc<Mutex<Process>>, // [XMRig] process state
|
||||||
pub xmrig_proxy: Arc<Mutex<Process>>, // [XMRig-Proxy] process state
|
pub xmrig_proxy: Arc<Mutex<Process>>, // [XMRig-Proxy] process state
|
||||||
pub xvb: Arc<Mutex<Process>>, // [Xvb] process state
|
pub xvb: Arc<Mutex<Process>>, // [Xvb] process state
|
||||||
|
pub node_api: Arc<Mutex<PubNodeApi>>, // Public ready-to-print node API made by the "helper" thread
|
||||||
pub p2pool_api: Arc<Mutex<PubP2poolApi>>, // Public ready-to-print P2Pool API made by the "helper" thread
|
pub p2pool_api: Arc<Mutex<PubP2poolApi>>, // Public ready-to-print P2Pool API made by the "helper" thread
|
||||||
pub xmrig_api: Arc<Mutex<PubXmrigApi>>, // Public ready-to-print XMRig API made by the "helper" thread
|
pub xmrig_api: Arc<Mutex<PubXmrigApi>>, // Public ready-to-print XMRig API made by the "helper" thread
|
||||||
pub xmrig_proxy_api: Arc<Mutex<PubXmrigProxyApi>>, // Public ready-to-print XMRigProxy API made by the "helper" thread
|
pub xmrig_proxy_api: Arc<Mutex<PubXmrigProxyApi>>, // Public ready-to-print XMRigProxy API made by the "helper" thread
|
||||||
|
@ -114,8 +117,9 @@ pub struct App {
|
||||||
pub p2pool_img: Arc<Mutex<ImgP2pool>>, // A one-time snapshot of what data P2Pool started with
|
pub p2pool_img: Arc<Mutex<ImgP2pool>>, // A one-time snapshot of what data P2Pool started with
|
||||||
pub xmrig_img: Arc<Mutex<ImgXmrig>>, // A one-time snapshot of what data XMRig started with
|
pub xmrig_img: Arc<Mutex<ImgXmrig>>, // A one-time snapshot of what data XMRig started with
|
||||||
// STDIN Buffer
|
// STDIN Buffer
|
||||||
|
pub node_stdin: String, // The buffer between the node console and the [Helper]
|
||||||
pub p2pool_stdin: String, // The buffer between the p2pool console and the [Helper]
|
pub p2pool_stdin: String, // The buffer between the p2pool console and the [Helper]
|
||||||
pub xmrig_stdin: String, // The buffer between the xmrig console and the [Helper]
|
pub xmrig_stdin: String, // The buffer between the xmrig console and the [Helper]
|
||||||
pub xmrig_proxy_stdin: String, // The buffer between the xmrig-proxy console and the [Helper]
|
pub xmrig_proxy_stdin: String, // The buffer between the xmrig-proxy console and the [Helper]
|
||||||
// Sudo State
|
// Sudo State
|
||||||
pub sudo: Arc<Mutex<SudoState>>, // This is just a dummy struct on [Windows].
|
pub sudo: Arc<Mutex<SudoState>>, // This is just a dummy struct on [Windows].
|
||||||
|
@ -200,10 +204,16 @@ impl App {
|
||||||
String::new(),
|
String::new(),
|
||||||
PathBuf::new()
|
PathBuf::new()
|
||||||
));
|
));
|
||||||
|
let node = arc_mut!(Process::new(
|
||||||
|
ProcessName::Node,
|
||||||
|
String::new(),
|
||||||
|
PathBuf::new()
|
||||||
|
));
|
||||||
let p2pool_api = arc_mut!(PubP2poolApi::new());
|
let p2pool_api = arc_mut!(PubP2poolApi::new());
|
||||||
let xmrig_api = arc_mut!(PubXmrigApi::new());
|
let xmrig_api = arc_mut!(PubXmrigApi::new());
|
||||||
let xmrig_proxy_api = arc_mut!(PubXmrigProxyApi::new());
|
let xmrig_proxy_api = arc_mut!(PubXmrigProxyApi::new());
|
||||||
let xvb_api = arc_mut!(PubXvbApi::new());
|
let xvb_api = arc_mut!(PubXvbApi::new());
|
||||||
|
let node_api = arc_mut!(PubNodeApi::new());
|
||||||
let p2pool_img = arc_mut!(ImgP2pool::new());
|
let p2pool_img = arc_mut!(ImgP2pool::new());
|
||||||
let xmrig_img = arc_mut!(ImgXmrig::new());
|
let xmrig_img = arc_mut!(ImgXmrig::new());
|
||||||
|
|
||||||
|
@ -248,6 +258,7 @@ impl App {
|
||||||
String::new(),
|
String::new(),
|
||||||
PathBuf::new(),
|
PathBuf::new(),
|
||||||
PathBuf::new(),
|
PathBuf::new(),
|
||||||
|
PathBuf::new(),
|
||||||
PathBuf::new()
|
PathBuf::new()
|
||||||
)),
|
)),
|
||||||
file_window: FileWindow::new(),
|
file_window: FileWindow::new(),
|
||||||
|
@ -265,24 +276,29 @@ impl App {
|
||||||
xmrig.clone(),
|
xmrig.clone(),
|
||||||
xmrig_proxy.clone(),
|
xmrig_proxy.clone(),
|
||||||
xvb.clone(),
|
xvb.clone(),
|
||||||
|
node.clone(),
|
||||||
p2pool_api.clone(),
|
p2pool_api.clone(),
|
||||||
xmrig_api.clone(),
|
xmrig_api.clone(),
|
||||||
xvb_api.clone(),
|
xvb_api.clone(),
|
||||||
xmrig_proxy_api.clone(),
|
xmrig_proxy_api.clone(),
|
||||||
|
node_api.clone(),
|
||||||
p2pool_img.clone(),
|
p2pool_img.clone(),
|
||||||
xmrig_img.clone(),
|
xmrig_img.clone(),
|
||||||
arc_mut!(GupaxP2poolApi::new())
|
arc_mut!(GupaxP2poolApi::new())
|
||||||
)),
|
)),
|
||||||
|
node,
|
||||||
p2pool,
|
p2pool,
|
||||||
xmrig,
|
xmrig,
|
||||||
xmrig_proxy,
|
xmrig_proxy,
|
||||||
xvb,
|
xvb,
|
||||||
|
node_api,
|
||||||
p2pool_api,
|
p2pool_api,
|
||||||
xvb_api,
|
xvb_api,
|
||||||
xmrig_api,
|
xmrig_api,
|
||||||
xmrig_proxy_api,
|
xmrig_proxy_api,
|
||||||
p2pool_img,
|
p2pool_img,
|
||||||
xmrig_img,
|
xmrig_img,
|
||||||
|
node_stdin: String::with_capacity(10),
|
||||||
p2pool_stdin: String::with_capacity(10),
|
p2pool_stdin: String::with_capacity(10),
|
||||||
xmrig_stdin: String::with_capacity(10),
|
xmrig_stdin: String::with_capacity(10),
|
||||||
xmrig_proxy_stdin: String::with_capacity(10),
|
xmrig_proxy_stdin: String::with_capacity(10),
|
||||||
|
@ -555,6 +571,7 @@ impl App {
|
||||||
|
|
||||||
// Apply TOML values to [Update]
|
// Apply TOML values to [Update]
|
||||||
info!("App Init | Applying TOML values to [Update]...");
|
info!("App Init | Applying TOML values to [Update]...");
|
||||||
|
let node_path = og.gupax.absolute_node_path.clone();
|
||||||
let p2pool_path = og.gupax.absolute_p2pool_path.clone();
|
let p2pool_path = og.gupax.absolute_p2pool_path.clone();
|
||||||
let xmrig_path = og.gupax.absolute_xmrig_path.clone();
|
let xmrig_path = og.gupax.absolute_xmrig_path.clone();
|
||||||
let xmrig_proxy_path = og.gupax.absolute_xp_path.clone();
|
let xmrig_proxy_path = og.gupax.absolute_xp_path.clone();
|
||||||
|
@ -562,7 +579,8 @@ impl App {
|
||||||
app.exe.clone(),
|
app.exe.clone(),
|
||||||
p2pool_path,
|
p2pool_path,
|
||||||
xmrig_path,
|
xmrig_path,
|
||||||
xmrig_proxy_path
|
xmrig_proxy_path,
|
||||||
|
node_path
|
||||||
));
|
));
|
||||||
|
|
||||||
// Set state version as compiled in version
|
// Set state version as compiled in version
|
||||||
|
@ -688,6 +706,7 @@ pub enum Tab {
|
||||||
About,
|
About,
|
||||||
Status,
|
Status,
|
||||||
Gupax,
|
Gupax,
|
||||||
|
Node,
|
||||||
P2pool,
|
P2pool,
|
||||||
Xmrig,
|
Xmrig,
|
||||||
XmrigProxy,
|
XmrigProxy,
|
||||||
|
|
|
@ -22,6 +22,7 @@ impl crate::app::App {
|
||||||
pub fn bottom_panel(
|
pub fn bottom_panel(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
|
node_state: ProcessState,
|
||||||
p2pool_state: ProcessState,
|
p2pool_state: ProcessState,
|
||||||
xmrig_state: ProcessState,
|
xmrig_state: ProcessState,
|
||||||
xmrig_proxy_state: ProcessState,
|
xmrig_proxy_state: ProcessState,
|
||||||
|
@ -30,10 +31,12 @@ impl crate::app::App {
|
||||||
wants_input: bool,
|
wants_input: bool,
|
||||||
p2pool_is_waiting: bool,
|
p2pool_is_waiting: bool,
|
||||||
xmrig_is_waiting: bool,
|
xmrig_is_waiting: bool,
|
||||||
|
node_is_waiting: bool,
|
||||||
xmrig_proxy_is_waiting: bool,
|
xmrig_proxy_is_waiting: bool,
|
||||||
xvb_is_waiting: bool,
|
xvb_is_waiting: bool,
|
||||||
p2pool_is_alive: bool,
|
p2pool_is_alive: bool,
|
||||||
xmrig_is_alive: bool,
|
xmrig_is_alive: bool,
|
||||||
|
node_is_alive: bool,
|
||||||
xmrig_proxy_is_alive: bool,
|
xmrig_proxy_is_alive: bool,
|
||||||
xvb_is_alive: bool,
|
xvb_is_alive: bool,
|
||||||
) {
|
) {
|
||||||
|
@ -74,6 +77,8 @@ impl crate::app::App {
|
||||||
ui.label(self.os);
|
ui.label(self.os);
|
||||||
// ui.add_sized(size, Label::new(self.os));
|
// ui.add_sized(size, Label::new(self.os));
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
status_node(node_state, ui, size);
|
||||||
|
ui.separator();
|
||||||
status_p2pool(p2pool_state, ui, size);
|
status_p2pool(p2pool_state, ui, size);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
status_xmrig(xmrig_state, ui, size);
|
status_xmrig(xmrig_state, ui, size);
|
||||||
|
@ -96,6 +101,17 @@ impl crate::app::App {
|
||||||
Tab::Gupax => {
|
Tab::Gupax => {
|
||||||
self.gupax_submenu(ui, height);
|
self.gupax_submenu(ui, height);
|
||||||
}
|
}
|
||||||
|
Tab::Node => {
|
||||||
|
self.node_submenu(ui, size);
|
||||||
|
self.node_run_actions(
|
||||||
|
ui,
|
||||||
|
height,
|
||||||
|
node_is_waiting,
|
||||||
|
node_is_alive,
|
||||||
|
wants_input,
|
||||||
|
key,
|
||||||
|
);
|
||||||
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
self.p2pool_submenu(ui, size);
|
self.p2pool_submenu(ui, size);
|
||||||
self.p2pool_run_actions(
|
self.p2pool_run_actions(
|
||||||
|
@ -309,6 +325,30 @@ impl crate::app::App {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
fn node_submenu(&mut self, ui: &mut Ui, size: Vec2) {
|
||||||
|
ui.group(|ui| {
|
||||||
|
let width = size.x / 1.5;
|
||||||
|
let size = vec2(width, size.y);
|
||||||
|
if ui
|
||||||
|
.add_sized(
|
||||||
|
size,
|
||||||
|
SelectableLabel::new(!self.state.node.simple, "Advanced"),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_ADVANCED)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.state.node.simple = false;
|
||||||
|
}
|
||||||
|
ui.separator();
|
||||||
|
if ui
|
||||||
|
.add_sized(size, SelectableLabel::new(self.state.node.simple, "Simple"))
|
||||||
|
.on_hover_text(NODE_SIMPLE)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.state.node.simple = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
fn p2pool_run_actions(
|
fn p2pool_run_actions(
|
||||||
&mut self,
|
&mut self,
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
|
@ -405,6 +445,95 @@ impl crate::app::App {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
fn node_run_actions(
|
||||||
|
&mut self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
height: f32,
|
||||||
|
node_is_waiting: bool,
|
||||||
|
node_is_alive: bool,
|
||||||
|
wants_input: bool,
|
||||||
|
key: &KeyPressed,
|
||||||
|
) {
|
||||||
|
ui.group(|ui| {
|
||||||
|
let width = ((ui.available_width() / 3.0) - 5.0).max(0.0);
|
||||||
|
let size = vec2(width, height);
|
||||||
|
if node_is_waiting {
|
||||||
|
ui.add_enabled_ui(false, |ui| {
|
||||||
|
ui.add_sized(size, Button::new("⟲"))
|
||||||
|
.on_disabled_hover_text(NODE_MIDDLE);
|
||||||
|
ui.add_sized(size, Button::new("⏹"))
|
||||||
|
.on_disabled_hover_text(NODE_MIDDLE);
|
||||||
|
ui.add_sized(size, Button::new("▶"))
|
||||||
|
.on_disabled_hover_text(NODE_MIDDLE);
|
||||||
|
});
|
||||||
|
} else if node_is_alive {
|
||||||
|
if key.is_up() && !wants_input
|
||||||
|
|| ui
|
||||||
|
.add_sized(size, Button::new("⟲"))
|
||||||
|
.on_hover_text("Restart node")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
let _ = lock!(self.og).update_absolute_path();
|
||||||
|
let _ = self.state.update_absolute_path();
|
||||||
|
Helper::restart_node(
|
||||||
|
&self.helper,
|
||||||
|
&self.state.node,
|
||||||
|
&self.state.gupax.absolute_node_path,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if key.is_down() && !wants_input
|
||||||
|
|| ui
|
||||||
|
.add_sized(size, Button::new("⏹"))
|
||||||
|
.on_hover_text("Stop node")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
Helper::stop_node(&self.helper);
|
||||||
|
}
|
||||||
|
ui.add_enabled_ui(false, |ui| {
|
||||||
|
ui.add_sized(size, Button::new("▶"))
|
||||||
|
.on_disabled_hover_text("Start node");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui.add_enabled_ui(false, |ui| {
|
||||||
|
ui.add_sized(size, Button::new("⟲"))
|
||||||
|
.on_disabled_hover_text("Restart node");
|
||||||
|
ui.add_sized(size, Button::new("⏹"))
|
||||||
|
.on_disabled_hover_text("Stop node");
|
||||||
|
});
|
||||||
|
// Check if path is okay before allowing to start.
|
||||||
|
let mut text = String::new();
|
||||||
|
let mut ui_enabled = true;
|
||||||
|
if !Gupax::path_is_file(&self.state.gupax.node_path) {
|
||||||
|
ui_enabled = false;
|
||||||
|
text = format!("Error: {}", NODE_PATH_NOT_FILE);
|
||||||
|
} else if !crate::components::update::check_node_path(&self.state.gupax.node_path) {
|
||||||
|
ui_enabled = false;
|
||||||
|
text = format!("Error: {}", NODE_PATH_NOT_VALID);
|
||||||
|
} else if process_running(crate::helper::ProcessName::Node) {
|
||||||
|
ui_enabled = false;
|
||||||
|
text = format!("Error: {}", PROCESS_OUTSIDE);
|
||||||
|
}
|
||||||
|
ui.add_enabled_ui(ui_enabled, |ui| {
|
||||||
|
let color = if ui_enabled { GREEN } else { RED };
|
||||||
|
if (ui_enabled && key.is_up() && !wants_input)
|
||||||
|
|| ui
|
||||||
|
.add_sized(size, Button::new(RichText::new("▶").color(color)))
|
||||||
|
.on_hover_text("Start Node")
|
||||||
|
.on_disabled_hover_text(text)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
let _ = lock!(self.og).update_absolute_path();
|
||||||
|
let _ = self.state.update_absolute_path();
|
||||||
|
Helper::start_node(
|
||||||
|
&self.helper,
|
||||||
|
&self.state.node,
|
||||||
|
&self.state.gupax.absolute_node_path,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
fn xmrig_submenu(&mut self, ui: &mut Ui, size: Vec2) {
|
fn xmrig_submenu(&mut self, ui: &mut Ui, size: Vec2) {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = size.x / 1.5;
|
let width = size.x / 1.5;
|
||||||
|
@ -790,6 +919,32 @@ fn status_p2pool(state: ProcessState, ui: &mut Ui, size: Vec2) {
|
||||||
};
|
};
|
||||||
status(ui, color, hover_text, size, "P2pool ⏺");
|
status(ui, color, hover_text, size, "P2pool ⏺");
|
||||||
}
|
}
|
||||||
|
fn status_node(state: ProcessState, ui: &mut Ui, size: Vec2) {
|
||||||
|
let color;
|
||||||
|
let hover_text = match state {
|
||||||
|
Alive => {
|
||||||
|
color = GREEN;
|
||||||
|
NODE_ALIVE
|
||||||
|
}
|
||||||
|
Dead => {
|
||||||
|
color = GRAY;
|
||||||
|
NODE_DEAD
|
||||||
|
}
|
||||||
|
Failed => {
|
||||||
|
color = RED;
|
||||||
|
NODE_FAILED
|
||||||
|
}
|
||||||
|
Syncing => {
|
||||||
|
color = ORANGE;
|
||||||
|
NODE_SYNCING
|
||||||
|
}
|
||||||
|
Middle | Waiting | NotMining | OfflineNodesAll | Retry => {
|
||||||
|
color = YELLOW;
|
||||||
|
NODE_MIDDLE
|
||||||
|
}
|
||||||
|
};
|
||||||
|
status(ui, color, hover_text, size, "Node ⏺");
|
||||||
|
}
|
||||||
|
|
||||||
fn status_xmrig(state: ProcessState, ui: &mut Ui, size: Vec2) {
|
fn status_xmrig(state: ProcessState, ui: &mut Ui, size: Vec2) {
|
||||||
let color;
|
let color;
|
||||||
|
|
|
@ -88,43 +88,48 @@ impl Gupax {
|
||||||
debug!("Gupaxx Tab | Rendering bool buttons");
|
debug!("Gupaxx Tab | Rendering bool buttons");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = (size.x - SPACE * 17.0) / 8.0;
|
egui::ScrollArea::horizontal().show(ui, |ui| {
|
||||||
let height = if self.simple {
|
let width = (size.x - SPACE * 17.0) / 8.0;
|
||||||
size.y / 10.0
|
let height = if self.simple {
|
||||||
} else {
|
size.y / 10.0
|
||||||
size.y / 15.0
|
} else {
|
||||||
};
|
size.y / 15.0
|
||||||
let size = vec2(width, height);
|
};
|
||||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Small);
|
let size = vec2(width, height);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.auto_update, "Auto-Update"))
|
ui.style_mut().override_text_style = Some(egui::TextStyle::Small);
|
||||||
.on_hover_text(GUPAX_AUTO_UPDATE);
|
ui.add_sized(size, Checkbox::new(&mut self.auto_update, "Auto-Update"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_AUTO_UPDATE);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.bundled, "Bundle"))
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_BUNDLED_UPDATE);
|
ui.add_sized(size, Checkbox::new(&mut self.bundled, "Bundle"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_BUNDLED_UPDATE);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.auto_p2pool, "Auto-P2Pool"))
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_AUTO_P2POOL);
|
ui.add_sized(size, Checkbox::new(&mut self.auto_node, "Auto-Node"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_AUTO_NODE);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xmrig, "Auto-XMRig"))
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_AUTO_XMRIG);
|
ui.add_sized(size, Checkbox::new(&mut self.auto_p2pool, "Auto-P2Pool"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_AUTO_P2POOL);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xp, "Auto-Proxy"))
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_AUTO_XMRIG_PROXY);
|
ui.add_sized(size, Checkbox::new(&mut self.auto_xmrig, "Auto-XMRig"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_AUTO_XMRIG);
|
||||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xvb, "Auto-XvB"))
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_AUTO_XVB);
|
ui.add_sized(size, Checkbox::new(&mut self.auto_xp, "Auto-Proxy"))
|
||||||
ui.separator();
|
.on_hover_text(GUPAX_AUTO_XMRIG_PROXY);
|
||||||
ui.add_sized(
|
ui.separator();
|
||||||
size,
|
ui.add_sized(size, Checkbox::new(&mut self.auto_xvb, "Auto-XvB"))
|
||||||
Checkbox::new(&mut self.ask_before_quit, "Confirm quit"),
|
.on_hover_text(GUPAX_AUTO_XVB);
|
||||||
)
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
ui.add_sized(
|
||||||
ui.separator();
|
size,
|
||||||
ui.add_sized(
|
Checkbox::new(&mut self.ask_before_quit, "Confirm quit"),
|
||||||
size,
|
)
|
||||||
Checkbox::new(&mut self.save_before_quit, "Save on quit"),
|
.on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
||||||
)
|
ui.separator();
|
||||||
.on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Checkbox::new(&mut self.save_before_quit, "Save on quit"),
|
||||||
|
)
|
||||||
|
.on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -140,13 +145,51 @@ impl Gupax {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[ui.available_width(), height / 2.0],
|
[ui.available_width(), height / 2.0],
|
||||||
Label::new(
|
Label::new(
|
||||||
RichText::new("P2Pool/XMRig/XMRig-Proxy PATHs")
|
RichText::new("Node/P2Pool/XMRig/XMRig-Proxy PATHs")
|
||||||
.underline()
|
.underline()
|
||||||
.color(LIGHT_GRAY),
|
.color(LIGHT_GRAY),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.on_hover_text("Gupaxx is online");
|
.on_hover_text("Gupaxx is online");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if self.node_path.is_empty() {
|
||||||
|
ui.add_sized(
|
||||||
|
[text_edit, height],
|
||||||
|
Label::new(RichText::new("Node Binary Path ➖").color(LIGHT_GRAY)),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_PATH_EMPTY);
|
||||||
|
} else if !Self::path_is_file(&self.node_path) {
|
||||||
|
ui.add_sized(
|
||||||
|
[text_edit, height],
|
||||||
|
Label::new(RichText::new("Node Binary Path ❌").color(RED)),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_PATH_NOT_FILE);
|
||||||
|
} else if !crate::components::update::check_node_path(&self.node_path) {
|
||||||
|
ui.add_sized(
|
||||||
|
[text_edit, height],
|
||||||
|
Label::new(RichText::new("Node Binary Path ❌").color(RED)),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_PATH_NOT_VALID);
|
||||||
|
} else {
|
||||||
|
ui.add_sized(
|
||||||
|
[text_edit, height],
|
||||||
|
Label::new(RichText::new("Node Binary Path ✔").color(GREEN)),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_PATH_OK);
|
||||||
|
}
|
||||||
|
ui.spacing_mut().text_edit_width = ui.available_width() - SPACE;
|
||||||
|
ui.add_enabled_ui(!lock!(file_window).thread, |ui| {
|
||||||
|
if ui.button("Open").on_hover_text(GUPAX_SELECT).clicked() {
|
||||||
|
Self::spawn_file_window_thread(file_window, FileType::Node);
|
||||||
|
}
|
||||||
|
ui.add_sized(
|
||||||
|
[ui.available_width(), height],
|
||||||
|
TextEdit::singleline(&mut self.node_path),
|
||||||
|
)
|
||||||
|
.on_hover_text(GUPAX_PATH_NODE);
|
||||||
|
});
|
||||||
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if self.p2pool_path.is_empty() {
|
if self.p2pool_path.is_empty() {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
|
@ -189,25 +232,25 @@ impl Gupax {
|
||||||
if self.xmrig_path.is_empty() {
|
if self.xmrig_path.is_empty() {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig Binary Path ➖").color(LIGHT_GRAY)),
|
Label::new(RichText::new("XMRig Binary Path ➖").color(LIGHT_GRAY)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PATH_EMPTY);
|
.on_hover_text(XMRIG_PATH_EMPTY);
|
||||||
} else if !Self::path_is_file(&self.xmrig_path) {
|
} else if !Self::path_is_file(&self.xmrig_path) {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig Binary Path ❌").color(RED)),
|
Label::new(RichText::new("XMRig Binary Path ❌").color(RED)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PATH_NOT_FILE);
|
.on_hover_text(XMRIG_PATH_NOT_FILE);
|
||||||
} else if !crate::components::update::check_xmrig_path(&self.xmrig_path) {
|
} else if !crate::components::update::check_xmrig_path(&self.xmrig_path) {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig Binary Path ❌").color(RED)),
|
Label::new(RichText::new("XMRig Binary Path ❌").color(RED)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PATH_NOT_VALID);
|
.on_hover_text(XMRIG_PATH_NOT_VALID);
|
||||||
} else {
|
} else {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig Binary Path ✔").color(GREEN)),
|
Label::new(RichText::new("XMRig Binary Path ✔").color(GREEN)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PATH_OK);
|
.on_hover_text(XMRIG_PATH_OK);
|
||||||
}
|
}
|
||||||
|
@ -228,26 +271,26 @@ impl Gupax {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(
|
Label::new(
|
||||||
RichText::new(" XMRig-Proxy Binary Path ➖").color(LIGHT_GRAY),
|
RichText::new("XMRig-Proxy Binary Path ➖").color(LIGHT_GRAY),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PROXY_PATH_EMPTY);
|
.on_hover_text(XMRIG_PROXY_PATH_EMPTY);
|
||||||
} else if !Self::path_is_file(&self.xmrig_proxy_path) {
|
} else if !Self::path_is_file(&self.xmrig_proxy_path) {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig-Proxy Binary Path ❌").color(RED)),
|
Label::new(RichText::new("XMRig-Proxy Binary Path ❌").color(RED)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PROXY_PATH_NOT_FILE);
|
.on_hover_text(XMRIG_PROXY_PATH_NOT_FILE);
|
||||||
} else if !crate::components::update::check_xp_path(&self.xmrig_proxy_path) {
|
} else if !crate::components::update::check_xp_path(&self.xmrig_proxy_path) {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig-Proxy Binary Path ❌").color(RED)),
|
Label::new(RichText::new("XMRig-Proxy Binary Path ❌").color(RED)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PROXY_PATH_NOT_VALID);
|
.on_hover_text(XMRIG_PROXY_PATH_NOT_VALID);
|
||||||
} else {
|
} else {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[text_edit, height],
|
[text_edit, height],
|
||||||
Label::new(RichText::new(" XMRig-Proxy Binary Path ✔").color(GREEN)),
|
Label::new(RichText::new("XMRig-Proxy Binary Path ✔").color(GREEN)),
|
||||||
)
|
)
|
||||||
.on_hover_text(XMRIG_PROXY_PATH_OK);
|
.on_hover_text(XMRIG_PROXY_PATH_OK);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +316,14 @@ impl Gupax {
|
||||||
self.xmrig_path.clone_from(&guard.xmrig_path);
|
self.xmrig_path.clone_from(&guard.xmrig_path);
|
||||||
guard.picked_xmrig = false;
|
guard.picked_xmrig = false;
|
||||||
}
|
}
|
||||||
|
if guard.picked_xp {
|
||||||
|
self.xmrig_proxy_path.clone_from(&guard.xmrig_proxy_path);
|
||||||
|
guard.picked_xp = false;
|
||||||
|
}
|
||||||
|
if guard.picked_node {
|
||||||
|
self.node_path.clone_from(&guard.node_path);
|
||||||
|
guard.picked_node = false;
|
||||||
|
}
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
let height = ui.available_height() / 6.0;
|
let height = ui.available_height() / 6.0;
|
||||||
|
@ -280,7 +331,7 @@ impl Gupax {
|
||||||
// Saved [Tab]
|
// Saved [Tab]
|
||||||
debug!("Gupaxx Tab | Rendering [Tab] selector");
|
debug!("Gupaxx Tab | Rendering [Tab] selector");
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
let width = (size.x / 6.0) - (SPACE * 1.93);
|
let width = (size.x / 7.0) - (SPACE * 1.93);
|
||||||
let size = vec2(width, height);
|
let size = vec2(width, height);
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[ui.available_width(), height / 2.0],
|
[ui.available_width(), height / 2.0],
|
||||||
|
@ -316,6 +367,14 @@ impl Gupax {
|
||||||
self.tab = Tab::Gupax;
|
self.tab = Tab::Gupax;
|
||||||
}
|
}
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
if ui
|
||||||
|
.add_sized(size, SelectableLabel::new(self.tab == Tab::Node, "Node"))
|
||||||
|
.on_hover_text(GUPAX_TAB_NODE)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.tab = Tab::Node;
|
||||||
|
}
|
||||||
|
ui.separator();
|
||||||
if ui
|
if ui
|
||||||
.add_sized(
|
.add_sized(
|
||||||
size,
|
size,
|
||||||
|
|
|
@ -8,6 +8,7 @@ use egui::*;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
mod gupax;
|
mod gupax;
|
||||||
|
mod node;
|
||||||
mod p2pool;
|
mod p2pool;
|
||||||
mod status;
|
mod status;
|
||||||
mod xmrig;
|
mod xmrig;
|
||||||
|
@ -20,6 +21,7 @@ impl crate::app::App {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
frame: &mut eframe::Frame,
|
frame: &mut eframe::Frame,
|
||||||
key: KeyPressed,
|
key: KeyPressed,
|
||||||
|
node_is_alive: bool,
|
||||||
p2pool_is_alive: bool,
|
p2pool_is_alive: bool,
|
||||||
xmrig_is_alive: bool,
|
xmrig_is_alive: bool,
|
||||||
xmrig_proxy_is_alive: bool,
|
xmrig_proxy_is_alive: bool,
|
||||||
|
@ -156,12 +158,16 @@ path_xmr: {:#?}\n
|
||||||
}
|
}
|
||||||
Tab::Status => {
|
Tab::Status => {
|
||||||
debug!("App | Entering [Status] Tab");
|
debug!("App | Entering [Status] Tab");
|
||||||
crate::disk::state::Status::show(&mut self.state.status, &self.pub_sys, &self.p2pool_api, &self.xmrig_api,&self.xmrig_proxy_api, &self.xvb_api,&self.p2pool_img, &self.xmrig_img, p2pool_is_alive, xmrig_is_alive, xmrig_proxy_is_alive,xvb_is_alive, self.max_threads, &self.gupax_p2pool_api, &self.benchmarks, self.size, ctx, ui);
|
crate::disk::state::Status::show(&mut self.state.status, &self.pub_sys, &self.node_api, &self.p2pool_api, &self.xmrig_api,&self.xmrig_proxy_api, &self.xvb_api,&self.p2pool_img, &self.xmrig_img, node_is_alive, p2pool_is_alive, xmrig_is_alive, xmrig_proxy_is_alive,xvb_is_alive, self.max_threads, &self.gupax_p2pool_api, &self.benchmarks, self.size, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Gupax => {
|
Tab::Gupax => {
|
||||||
debug!("App | Entering [Gupax] Tab");
|
debug!("App | Entering [Gupax] Tab");
|
||||||
crate::disk::state::Gupax::show(&mut self.state.gupax, &self.og, &self.state_path, &self.update, &self.file_window, &mut self.error_state, &self.restart, self.size, frame, ctx, ui);
|
crate::disk::state::Gupax::show(&mut self.state.gupax, &self.og, &self.state_path, &self.update, &self.file_window, &mut self.error_state, &self.restart, self.size, frame, ctx, ui);
|
||||||
}
|
}
|
||||||
|
Tab::Node=> {
|
||||||
|
debug!("App | Entering [Node] Tab");
|
||||||
|
crate::disk::state::Node::show(&mut self.state.node, &self.node, &self.node_api, &mut self.node_stdin, self.size, &self.file_window, ui);
|
||||||
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
debug!("App | Entering [P2Pool] Tab");
|
debug!("App | Entering [P2Pool] Tab");
|
||||||
crate::disk::state::P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, &self.ping, &self.p2pool, &self.p2pool_api, &mut self.p2pool_stdin, self.size, ctx, ui);
|
crate::disk::state::P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, &self.ping, &self.p2pool, &self.p2pool_api, &mut self.p2pool_stdin, self.size, ctx, ui);
|
||||||
|
|
407
src/app/panels/middle/node.rs
Normal file
407
src/app/panels/middle/node.rs
Normal file
|
@ -0,0 +1,407 @@
|
||||||
|
use crate::{
|
||||||
|
GUPAX_SELECT, NODE_API_BIND, NODE_API_PORT, NODE_ARGUMENTS, NODE_DB_DIR, NODE_DB_PATH_EMPTY,
|
||||||
|
NODE_DNS_BLOCKLIST, NODE_DNS_CHECKPOINT, NODE_INPUT, NODE_PATH_OK, NODE_PRUNNING, NODE_URL,
|
||||||
|
NODE_ZMQ_BIND, NODE_ZMQ_PORT,
|
||||||
|
};
|
||||||
|
use egui::{Color32, Label, RichText, Slider, TextEdit, Ui, Vec2};
|
||||||
|
use regex::Regex;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use egui::TextStyle::{self, Name};
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
use crate::components::gupax::{FileType, FileWindow};
|
||||||
|
use crate::disk::state::{Gupax, Node};
|
||||||
|
use crate::helper::node::PubNodeApi;
|
||||||
|
use crate::helper::Process;
|
||||||
|
use crate::regex::{num_lines, REGEXES};
|
||||||
|
use crate::utils::constants::DARK_GRAY;
|
||||||
|
use crate::utils::macros::lock;
|
||||||
|
use crate::{GREEN, LIGHT_GRAY, P2POOL_IN, P2POOL_LOG, P2POOL_OUT, RED, SPACE};
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
#[inline(always)] // called once
|
||||||
|
pub fn show(
|
||||||
|
&mut self,
|
||||||
|
process: &Arc<Mutex<Process>>,
|
||||||
|
api: &Arc<Mutex<PubNodeApi>>,
|
||||||
|
buffer: &mut String,
|
||||||
|
size: Vec2,
|
||||||
|
file_window: &Arc<Mutex<FileWindow>>,
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
) {
|
||||||
|
let width = size.x;
|
||||||
|
let height = size.y;
|
||||||
|
let space_h = height / 48.0;
|
||||||
|
let text_height = size.y / 25.0;
|
||||||
|
let txt_description_width = size.x * 0.1;
|
||||||
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.add_space(space_h);
|
||||||
|
ui.style_mut().override_text_style = Some(TextStyle::Heading);
|
||||||
|
ui.hyperlink_to("Monerod", NODE_URL);
|
||||||
|
ui.style_mut().override_text_style = Some(TextStyle::Body);
|
||||||
|
ui.add(Label::new("C++ Monero Node"));
|
||||||
|
ui.add_space(space_h);
|
||||||
|
});
|
||||||
|
// console output for log
|
||||||
|
debug!("Node Tab | Rendering [Console]");
|
||||||
|
ui.group(|ui| {
|
||||||
|
let text = &lock!(api).output;
|
||||||
|
let nb_lines = num_lines(text);
|
||||||
|
let height = size.y / 2.8;
|
||||||
|
let width = size.x - (space_h / 2.0);
|
||||||
|
egui::Frame::none().fill(DARK_GRAY).show(ui, |ui| {
|
||||||
|
ui.style_mut().override_text_style = Some(Name("MonospaceSmall".into()));
|
||||||
|
egui::ScrollArea::vertical()
|
||||||
|
.stick_to_bottom(true)
|
||||||
|
.max_width(width)
|
||||||
|
.max_height(height)
|
||||||
|
.auto_shrink([false; 2])
|
||||||
|
// .show_viewport(ui, |ui, _| {
|
||||||
|
.show_rows(
|
||||||
|
ui,
|
||||||
|
ui.text_style_height(&TextStyle::Name("MonospaceSmall".into())),
|
||||||
|
nb_lines,
|
||||||
|
|ui, row_range| {
|
||||||
|
for i in row_range {
|
||||||
|
if let Some(line) = text.lines().nth(i) {
|
||||||
|
ui.label(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//---------------------------------------------------------------------------------------------------- [Advanced] Console
|
||||||
|
if !self.simple {
|
||||||
|
ui.separator();
|
||||||
|
let response = ui
|
||||||
|
.add_sized(
|
||||||
|
[width, text_height],
|
||||||
|
TextEdit::hint_text(
|
||||||
|
TextEdit::singleline(buffer),
|
||||||
|
r#"Commands: help, status, set_log <level>, diff"#,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_INPUT);
|
||||||
|
// If the user pressed enter, dump buffer contents into the process STDIN
|
||||||
|
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
|
||||||
|
response.request_focus(); // Get focus back
|
||||||
|
let buffer = std::mem::take(buffer); // Take buffer
|
||||||
|
let mut process = lock!(process); // Lock
|
||||||
|
if process.is_alive() {
|
||||||
|
process.input.push(buffer);
|
||||||
|
} // Push only if alive
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Arguments
|
||||||
|
debug!("Node Tab | Rendering [Arguments]");
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new("Command arguments:"),
|
||||||
|
);
|
||||||
|
ui.add_sized(
|
||||||
|
[ui.available_width(), text_height],
|
||||||
|
TextEdit::hint_text(
|
||||||
|
TextEdit::singleline(&mut self.arguments),
|
||||||
|
r#"--zmq-pub tcp://127.0.0.1:18081"#,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_hover_text(NODE_ARGUMENTS);
|
||||||
|
self.arguments.truncate(1024);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
if !self.arguments.is_empty() {
|
||||||
|
ui.disable();
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------------------------------- Prunned checkbox
|
||||||
|
ui.add_space(space_h);
|
||||||
|
ui.style_mut().spacing.icon_width_inner = width / 45.0;
|
||||||
|
ui.style_mut().spacing.icon_width = width / 35.0;
|
||||||
|
ui.style_mut().spacing.icon_spacing = space_h;
|
||||||
|
ui.checkbox(&mut self.pruned, "Prunned")
|
||||||
|
.on_hover_text(NODE_PRUNNING);
|
||||||
|
|
||||||
|
ui.add_space(space_h);
|
||||||
|
// idea
|
||||||
|
// need to warn the user if local firewall is blocking port
|
||||||
|
// need to warn the user if NAT is blocking port
|
||||||
|
// need to show local ip address
|
||||||
|
// need to show public ip
|
||||||
|
// text edit width is 4x bigger than description. Which makes half of the total width on screen less a space.
|
||||||
|
|
||||||
|
// (width - (width - ui.available_width()) - (ui.spacing().item_spacing.x * 4.5))
|
||||||
|
// / 2.0;
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
rpc_bind_field(self, ui, txt_description_width, text_height, width);
|
||||||
|
rpc_port_field(self, ui, txt_description_width, text_height, width);
|
||||||
|
ui.add_space(space_h);
|
||||||
|
zmq_bind_field(self, ui, txt_description_width, text_height, width);
|
||||||
|
zmq_port_field(self, ui, txt_description_width, text_height, width);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- In/Out peers
|
||||||
|
debug!("Node Tab | Rendering sliders elements");
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.style_mut().override_text_style =
|
||||||
|
Some(Name("MonospaceSmall".into()));
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
// ui.label("Out peers [10-450]:");
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new("Out peers [10-450]:"),
|
||||||
|
);
|
||||||
|
// not sure what's the right calculation to make
|
||||||
|
ui.style_mut().spacing.slider_width = ui.available_width()
|
||||||
|
- ui.spacing().item_spacing.x * 4.0
|
||||||
|
- ui.spacing().scroll.bar_width
|
||||||
|
- (SPACE * 2.0);
|
||||||
|
ui.add(Slider::new(&mut self.out_peers, 10..=450))
|
||||||
|
.on_hover_text(P2POOL_OUT);
|
||||||
|
// ui.add_space(ui.available_width() - 4.0);
|
||||||
|
});
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
// ui.label("In peers [10-450]:");
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new("In peers [10-450]:"),
|
||||||
|
);
|
||||||
|
ui.style_mut().spacing.slider_width = ui.available_width()
|
||||||
|
- ui.spacing().item_spacing.x * 4.0
|
||||||
|
- ui.spacing().scroll.bar_width
|
||||||
|
- (SPACE * 2.0);
|
||||||
|
ui.add(Slider::new(&mut self.in_peers, 10..=450))
|
||||||
|
.on_hover_text(P2POOL_IN);
|
||||||
|
});
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
// ui.label("Log level [ 0-4 ]:");
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new("Log level [ 0-4 ] :"),
|
||||||
|
);
|
||||||
|
ui.style_mut().spacing.slider_width = ui.available_width()
|
||||||
|
- ui.spacing().item_spacing.x * 4.0
|
||||||
|
- ui.spacing().scroll.bar_width
|
||||||
|
- (SPACE * 2.0);
|
||||||
|
ui.add(Slider::new(&mut self.log_level, 0..=4))
|
||||||
|
.on_hover_text(P2POOL_LOG);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//---------------------------------------------------------------------------------------------------- DB path
|
||||||
|
ui.add_space(space_h);
|
||||||
|
ui.group(|ui| {
|
||||||
|
path_db_field(self, ui, txt_description_width, text_height, file_window);
|
||||||
|
});
|
||||||
|
ui.add_space(space_h);
|
||||||
|
debug!("Node Tab | Rendering DNS buttons");
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.checkbox(&mut self.dns_blocklist, "DNS blocklist")
|
||||||
|
.on_hover_text(NODE_DNS_BLOCKLIST);
|
||||||
|
ui.separator();
|
||||||
|
ui.checkbox(&mut self.disable_dns_checkpoint, "DNS checkpoint")
|
||||||
|
.on_hover_text(NODE_DNS_CHECKPOINT);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rpc_bind_field(
|
||||||
|
state: &mut Node,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
width: f32,
|
||||||
|
) {
|
||||||
|
state_edit_field(
|
||||||
|
&mut state.api_ip,
|
||||||
|
ui,
|
||||||
|
txt_description_width,
|
||||||
|
text_height,
|
||||||
|
width,
|
||||||
|
"RPC BIND IP ",
|
||||||
|
255,
|
||||||
|
NODE_API_BIND,
|
||||||
|
vec![®EXES.ipv4, ®EXES.domain],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rpc_port_field(
|
||||||
|
state: &mut Node,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
width: f32,
|
||||||
|
) {
|
||||||
|
state_edit_field(
|
||||||
|
&mut state.api_port,
|
||||||
|
ui,
|
||||||
|
txt_description_width,
|
||||||
|
text_height,
|
||||||
|
width,
|
||||||
|
" RPC PORT ",
|
||||||
|
5,
|
||||||
|
NODE_API_PORT,
|
||||||
|
vec![®EXES.port],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fn zmq_bind_field(
|
||||||
|
state: &mut Node,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
width: f32,
|
||||||
|
) {
|
||||||
|
state_edit_field(
|
||||||
|
&mut state.zmq_ip,
|
||||||
|
ui,
|
||||||
|
txt_description_width,
|
||||||
|
text_height,
|
||||||
|
width,
|
||||||
|
"API BIND IP ",
|
||||||
|
255,
|
||||||
|
NODE_ZMQ_BIND,
|
||||||
|
vec![®EXES.ipv4, ®EXES.domain],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fn zmq_port_field(
|
||||||
|
state: &mut Node,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
width: f32,
|
||||||
|
) {
|
||||||
|
state_edit_field(
|
||||||
|
&mut state.zmq_port,
|
||||||
|
ui,
|
||||||
|
txt_description_width,
|
||||||
|
text_height,
|
||||||
|
width,
|
||||||
|
" ZMQ PORT ",
|
||||||
|
5,
|
||||||
|
NODE_ZMQ_PORT,
|
||||||
|
vec![®EXES.port],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_db_field(
|
||||||
|
state: &mut Node,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
file_window: &Arc<Mutex<FileWindow>>,
|
||||||
|
) {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
let symbol;
|
||||||
|
let color;
|
||||||
|
let hover;
|
||||||
|
if state.path_db.is_empty() {
|
||||||
|
symbol = "➖";
|
||||||
|
color = LIGHT_GRAY;
|
||||||
|
hover = NODE_DB_PATH_EMPTY;
|
||||||
|
} else if !Gupax::path_is_dir(&state.path_db) {
|
||||||
|
symbol = "❌";
|
||||||
|
color = RED;
|
||||||
|
hover = NODE_DB_DIR;
|
||||||
|
} else {
|
||||||
|
symbol = "✔";
|
||||||
|
color = GREEN;
|
||||||
|
hover = NODE_PATH_OK;
|
||||||
|
}
|
||||||
|
let text = ["Node Database Directory ", symbol].concat();
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new(RichText::new(text).color(color)),
|
||||||
|
);
|
||||||
|
ui.spacing_mut().text_edit_width =
|
||||||
|
ui.available_width() - (ui.spacing().item_spacing.x * 8.0) - SPACE * 2.0;
|
||||||
|
let window_busy = lock!(file_window).thread;
|
||||||
|
ui.add_enabled_ui(!window_busy, |ui| {
|
||||||
|
if ui.button("Open").on_hover_text(GUPAX_SELECT).clicked() {
|
||||||
|
Gupax::spawn_file_window_thread(file_window, FileType::NodeDB);
|
||||||
|
}
|
||||||
|
ui.text_edit_singleline(&mut state.path_db)
|
||||||
|
.on_hover_text(hover);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut guard = lock!(file_window);
|
||||||
|
if guard.picked_nodedb {
|
||||||
|
state.path_db.clone_from(&guard.nodedb_path);
|
||||||
|
guard.picked_nodedb = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn state_edit_field(
|
||||||
|
state_field: &mut String,
|
||||||
|
ui: &mut Ui,
|
||||||
|
txt_description_width: f32,
|
||||||
|
text_height: f32,
|
||||||
|
width: f32,
|
||||||
|
description: &str,
|
||||||
|
max_ch: u8,
|
||||||
|
help_msg: &str,
|
||||||
|
validations: Vec<&Regex>,
|
||||||
|
) {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
let color;
|
||||||
|
let symbol;
|
||||||
|
let mut input_validated = true;
|
||||||
|
let len;
|
||||||
|
let inside_space;
|
||||||
|
for v in validations {
|
||||||
|
if !v.is_match(state_field) {
|
||||||
|
input_validated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if state_field.is_empty() {
|
||||||
|
symbol = "➖";
|
||||||
|
color = Color32::LIGHT_GRAY;
|
||||||
|
} else if input_validated {
|
||||||
|
symbol = "✔";
|
||||||
|
color = Color32::from_rgb(100, 230, 100);
|
||||||
|
} else {
|
||||||
|
symbol = "❌";
|
||||||
|
color = Color32::from_rgb(230, 50, 50);
|
||||||
|
}
|
||||||
|
match max_ch {
|
||||||
|
x if x >= 100 => {
|
||||||
|
len = format!("{:03}", state_field.len());
|
||||||
|
inside_space = "";
|
||||||
|
}
|
||||||
|
10..99 => {
|
||||||
|
len = format!("{:02}", state_field.len());
|
||||||
|
inside_space = " ";
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
len = format!("{}", state_field.len());
|
||||||
|
inside_space = " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let text = format!(
|
||||||
|
"{}[{}{}/{}{}]{}",
|
||||||
|
description, inside_space, len, max_ch, inside_space, symbol
|
||||||
|
);
|
||||||
|
ui.add_sized(
|
||||||
|
[txt_description_width, text_height],
|
||||||
|
Label::new(RichText::new(text).color(color)),
|
||||||
|
);
|
||||||
|
// allocate the size to leave half of the total width free.
|
||||||
|
ui.spacing_mut().text_edit_width = (width / 2.0)
|
||||||
|
- (width - ui.available_width() - ui.spacing().scroll.bar_width)
|
||||||
|
- ui.spacing().item_spacing.x * 2.5;
|
||||||
|
ui.text_edit_singleline(state_field).on_hover_text(help_msg);
|
||||||
|
state_field.truncate(max_ch.into());
|
||||||
|
});
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ use crate::{
|
||||||
app::Benchmark,
|
app::Benchmark,
|
||||||
disk::{gupax_p2pool_api::GupaxP2poolApi, state::Status, status::*},
|
disk::{gupax_p2pool_api::GupaxP2poolApi, state::Status, status::*},
|
||||||
helper::{
|
helper::{
|
||||||
|
node::PubNodeApi,
|
||||||
p2pool::{ImgP2pool, PubP2poolApi},
|
p2pool::{ImgP2pool, PubP2poolApi},
|
||||||
xrig::{
|
xrig::{
|
||||||
xmrig::{ImgXmrig, PubXmrigApi},
|
xmrig::{ImgXmrig, PubXmrigApi},
|
||||||
|
@ -42,12 +43,14 @@ impl Status {
|
||||||
pub fn show(
|
pub fn show(
|
||||||
&mut self,
|
&mut self,
|
||||||
sys: &Arc<Mutex<Sys>>,
|
sys: &Arc<Mutex<Sys>>,
|
||||||
|
node_api: &Arc<Mutex<PubNodeApi>>,
|
||||||
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
||||||
xmrig_api: &Arc<Mutex<PubXmrigApi>>,
|
xmrig_api: &Arc<Mutex<PubXmrigApi>>,
|
||||||
xmrig_proxy_api: &Arc<Mutex<PubXmrigProxyApi>>,
|
xmrig_proxy_api: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||||
xvb_api: &Arc<Mutex<PubXvbApi>>,
|
xvb_api: &Arc<Mutex<PubXvbApi>>,
|
||||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||||
|
node_alive: bool,
|
||||||
p2pool_alive: bool,
|
p2pool_alive: bool,
|
||||||
xmrig_alive: bool,
|
xmrig_alive: bool,
|
||||||
xmrig_proxy_alive: bool,
|
xmrig_proxy_alive: bool,
|
||||||
|
@ -65,6 +68,8 @@ impl Status {
|
||||||
sys,
|
sys,
|
||||||
size,
|
size,
|
||||||
ui,
|
ui,
|
||||||
|
node_alive,
|
||||||
|
node_api,
|
||||||
p2pool_alive,
|
p2pool_alive,
|
||||||
p2pool_api,
|
p2pool_api,
|
||||||
p2pool_img,
|
p2pool_img,
|
||||||
|
|
|
@ -3,6 +3,7 @@ use readable::up::UptimeFull;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::disk::state::Status;
|
use crate::disk::state::Status;
|
||||||
|
use crate::helper::node::PubNodeApi;
|
||||||
use crate::helper::p2pool::{ImgP2pool, PubP2poolApi};
|
use crate::helper::p2pool::{ImgP2pool, PubP2poolApi};
|
||||||
use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
|
use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
|
||||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||||
|
@ -21,6 +22,8 @@ impl Status {
|
||||||
sys: &Arc<Mutex<Sys>>,
|
sys: &Arc<Mutex<Sys>>,
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
|
node_alive: bool,
|
||||||
|
node_api: &Arc<Mutex<PubNodeApi>>,
|
||||||
p2pool_alive: bool,
|
p2pool_alive: bool,
|
||||||
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
||||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||||
|
@ -50,6 +53,8 @@ impl Status {
|
||||||
|
|
||||||
// [Gupax]
|
// [Gupax]
|
||||||
gupax(ui, min_size, size, sys);
|
gupax(ui, min_size, size, sys);
|
||||||
|
// [Node]
|
||||||
|
node(ui, min_size, size, node_alive, node_api);
|
||||||
// [P2Pool]
|
// [P2Pool]
|
||||||
p2pool(ui, min_size, size, p2pool_alive, p2pool_api, p2pool_img);
|
p2pool(ui, min_size, size, p2pool_alive, p2pool_api, p2pool_img);
|
||||||
// [XMRig]
|
// [XMRig]
|
||||||
|
@ -554,3 +559,94 @@ fn xvb(ui: &mut Ui, min_size: Vec2, size: Vec2, xvb_alive: bool, xvb_api: &Arc<M
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn node(
|
||||||
|
ui: &mut Ui,
|
||||||
|
min_size: Vec2,
|
||||||
|
size: Vec2,
|
||||||
|
node_alive: bool,
|
||||||
|
node_api: &Arc<Mutex<PubNodeApi>>,
|
||||||
|
) {
|
||||||
|
ui.group(|ui| {
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.set_min_height(min_size.y * 34.0);
|
||||||
|
debug!("Status Tab | Rendering [Node]");
|
||||||
|
ui.add_enabled_ui(node_alive, |ui| {
|
||||||
|
ui.set_min_size(min_size);
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(
|
||||||
|
RichText::new("[Node]")
|
||||||
|
.color(LIGHT_GRAY)
|
||||||
|
.text_style(TextStyle::Name("MonospaceLarge".into())),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.on_hover_text("Node is online")
|
||||||
|
.on_disabled_hover_text("Node is offline");
|
||||||
|
let api = lock!(node_api);
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Uptime").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_UPTIME);
|
||||||
|
ui.add_sized(size, Label::new(api.uptime.to_string()));
|
||||||
|
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Block Height").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_BLOCK_HEIGHT);
|
||||||
|
ui.add_sized(size, Label::new(api.blockheight.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Network Difficulty").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_DIFFICULTY);
|
||||||
|
ui.add_sized(size, Label::new(api.difficulty.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Database size").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_DB_SIZE);
|
||||||
|
ui.add_sized(size, Label::new(api.database_size.to_owned()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Free space").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_FREESPACE);
|
||||||
|
ui.add_sized(size, Label::new(api.free_space.to_owned()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Network Type").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_NETTYPE);
|
||||||
|
ui.add_sized(size, Label::new(api.nettype.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Outgoing peers").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_OUT);
|
||||||
|
ui.add_sized(size, Label::new(api.outgoing_connections.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Incoming peers").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_IN);
|
||||||
|
ui.add_sized(size, Label::new(api.incoming_connections.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Synchronized").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_SYNC);
|
||||||
|
ui.add_sized(size, Label::new(api.synchronized.to_string()));
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
Label::new(RichText::new("Status").underline().color(BONE)),
|
||||||
|
)
|
||||||
|
.on_hover_text(STATUS_NODE_STATUS);
|
||||||
|
ui.add_sized(size, Label::new(api.status.to_string()));
|
||||||
|
drop(api);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use egui::TextStyle::Name;
|
use egui::TextStyle::Name;
|
||||||
use egui::{SelectableLabel, TopBottomPanel};
|
use egui::{ScrollArea, SelectableLabel, TopBottomPanel};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
use crate::{app::Tab, utils::constants::SPACE};
|
use crate::{app::Tab, utils::constants::SPACE};
|
||||||
|
@ -8,82 +8,94 @@ impl crate::app::App {
|
||||||
pub fn top_panel(&mut self, ctx: &egui::Context) {
|
pub fn top_panel(&mut self, ctx: &egui::Context) {
|
||||||
debug!("App | Rendering TOP tabs");
|
debug!("App | Rendering TOP tabs");
|
||||||
TopBottomPanel::top("top").show(ctx, |ui| {
|
TopBottomPanel::top("top").show(ctx, |ui| {
|
||||||
let width = (self.size.x - (SPACE * 16.0)) / 7.0;
|
let width = (self.size.x - (SPACE * 18.0)) / 8.0;
|
||||||
let height = self.size.y / 15.0;
|
let height = self.size.y / 15.0;
|
||||||
ui.add_space(4.0);
|
ui.add_space(4.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
ScrollArea::horizontal().show(ui, |ui| {
|
||||||
if ui
|
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::About, "About"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::About, "About"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::About;
|
{
|
||||||
}
|
self.tab = Tab::About;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::Status, "Status"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::Status, "Status"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::Status;
|
{
|
||||||
}
|
self.tab = Tab::Status;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::Gupax, "Gupaxx"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::Gupax, "Gupaxx"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::Gupax;
|
{
|
||||||
}
|
self.tab = Tab::Gupax;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::P2pool, "P2Pool"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::Node, "Node"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::P2pool;
|
{
|
||||||
}
|
self.tab = Tab::Node;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::Xmrig, "XMRig"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::P2pool, "P2Pool"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::Xmrig;
|
{
|
||||||
}
|
self.tab = Tab::P2pool;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::XmrigProxy, "Proxy"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::Xmrig, "XMRig"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::XmrigProxy;
|
{
|
||||||
}
|
self.tab = Tab::Xmrig;
|
||||||
ui.separator();
|
}
|
||||||
if ui
|
ui.separator();
|
||||||
.add_sized(
|
if ui
|
||||||
[width, height],
|
.add_sized(
|
||||||
SelectableLabel::new(self.tab == Tab::Xvb, "XvB"),
|
[width, height],
|
||||||
)
|
SelectableLabel::new(self.tab == Tab::XmrigProxy, "Proxy"),
|
||||||
.clicked()
|
)
|
||||||
{
|
.clicked()
|
||||||
self.tab = Tab::Xvb;
|
{
|
||||||
}
|
self.tab = Tab::XmrigProxy;
|
||||||
|
}
|
||||||
|
ui.separator();
|
||||||
|
if ui
|
||||||
|
.add_sized(
|
||||||
|
[width, height],
|
||||||
|
SelectableLabel::new(self.tab == Tab::Xvb, "XvB"),
|
||||||
|
)
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
self.tab = Tab::Xvb;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.add_space(4.0);
|
||||||
});
|
});
|
||||||
ui.add_space(4.0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,11 @@ pub struct FileWindow {
|
||||||
pub picked_p2pool: bool, // Did the user pick a path for p2pool?
|
pub picked_p2pool: bool, // Did the user pick a path for p2pool?
|
||||||
pub picked_xmrig: bool, // Did the user pick a path for xmrig?
|
pub picked_xmrig: bool, // Did the user pick a path for xmrig?
|
||||||
pub picked_xp: bool, // Did the user pick a path for xmrig-proxy?
|
pub picked_xp: bool, // Did the user pick a path for xmrig-proxy?
|
||||||
|
pub picked_node: bool, // Did the user pick a path for node?
|
||||||
|
pub picked_nodedb: bool, // Did the user pick a path for node?
|
||||||
pub p2pool_path: String, // The picked p2pool path
|
pub p2pool_path: String, // The picked p2pool path
|
||||||
|
pub node_path: String, // The picked node path
|
||||||
|
pub nodedb_path: String, // The picked node path
|
||||||
pub xmrig_path: String, // The picked xmrig path
|
pub xmrig_path: String, // The picked xmrig path
|
||||||
pub xmrig_proxy_path: String, // The picked xmrig-proxy path
|
pub xmrig_proxy_path: String, // The picked xmrig-proxy path
|
||||||
}
|
}
|
||||||
|
@ -47,7 +51,11 @@ impl FileWindow {
|
||||||
picked_p2pool: false,
|
picked_p2pool: false,
|
||||||
picked_xmrig: false,
|
picked_xmrig: false,
|
||||||
picked_xp: false,
|
picked_xp: false,
|
||||||
|
picked_node: false,
|
||||||
|
picked_nodedb: false,
|
||||||
p2pool_path: String::new(),
|
p2pool_path: String::new(),
|
||||||
|
node_path: String::new(),
|
||||||
|
nodedb_path: String::new(),
|
||||||
xmrig_path: String::new(),
|
xmrig_path: String::new(),
|
||||||
xmrig_proxy_path: String::new(),
|
xmrig_proxy_path: String::new(),
|
||||||
})
|
})
|
||||||
|
@ -59,6 +67,8 @@ pub enum FileType {
|
||||||
P2pool,
|
P2pool,
|
||||||
Xmrig,
|
Xmrig,
|
||||||
XmrigProxy,
|
XmrigProxy,
|
||||||
|
Node,
|
||||||
|
NodeDB,
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Ratio Lock
|
//---------------------------------------------------------------------------------------------------- Ratio Lock
|
||||||
|
@ -80,6 +90,14 @@ impl Gupax {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Checks if a path is a valid path to a directory.
|
||||||
|
pub fn path_is_dir(path: &str) -> bool {
|
||||||
|
let path = path.to_string();
|
||||||
|
match crate::disk::into_absolute_path(path) {
|
||||||
|
Ok(path) => path.is_dir(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cold]
|
#[cold]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
|
@ -89,33 +107,48 @@ impl Gupax {
|
||||||
P2pool => "P2Pool",
|
P2pool => "P2Pool",
|
||||||
Xmrig => "XMRig",
|
Xmrig => "XMRig",
|
||||||
XmrigProxy => "XMRigProxy",
|
XmrigProxy => "XMRigProxy",
|
||||||
|
Node => "Node",
|
||||||
|
NodeDB => "Node DB",
|
||||||
};
|
};
|
||||||
let file_window = file_window.clone();
|
let file_window = file_window.clone();
|
||||||
lock!(file_window).thread = true;
|
lock!(file_window).thread = true;
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
match rfd::FileDialog::new()
|
let path = match file_type {
|
||||||
.set_title(format!("Select {} Binary for Gupaxx", name))
|
NodeDB => rfd::FileDialog::new()
|
||||||
.pick_file()
|
.set_title("Select a directory for the DB of your Node")
|
||||||
{
|
.pick_folder(),
|
||||||
Some(path) => {
|
_ => rfd::FileDialog::new()
|
||||||
info!("Gupaxx | Path selected for {} ... {}", name, path.display());
|
.set_title(format!("Select {} Binary for Gupaxx", name))
|
||||||
match file_type {
|
.pick_file(),
|
||||||
P2pool => {
|
|
||||||
lock!(file_window).p2pool_path = path.display().to_string();
|
|
||||||
lock!(file_window).picked_p2pool = true;
|
|
||||||
}
|
|
||||||
Xmrig => {
|
|
||||||
lock!(file_window).xmrig_path = path.display().to_string();
|
|
||||||
lock!(file_window).picked_xmrig = true;
|
|
||||||
}
|
|
||||||
XmrigProxy => {
|
|
||||||
lock!(file_window).xmrig_proxy_path = path.display().to_string();
|
|
||||||
lock!(file_window).picked_xp = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
None => info!("Gupaxx | No path selected for {}", name),
|
|
||||||
};
|
};
|
||||||
|
if let Some(path) = path {
|
||||||
|
info!("Gupaxx | Path selected for {} ... {}", name, path.display());
|
||||||
|
match file_type {
|
||||||
|
P2pool => {
|
||||||
|
lock!(file_window).p2pool_path = path.display().to_string();
|
||||||
|
lock!(file_window).picked_p2pool = true;
|
||||||
|
}
|
||||||
|
Xmrig => {
|
||||||
|
lock!(file_window).xmrig_path = path.display().to_string();
|
||||||
|
lock!(file_window).picked_xmrig = true;
|
||||||
|
}
|
||||||
|
XmrigProxy => {
|
||||||
|
lock!(file_window).xmrig_proxy_path = path.display().to_string();
|
||||||
|
lock!(file_window).picked_xp = true;
|
||||||
|
}
|
||||||
|
Node => {
|
||||||
|
lock!(file_window).node_path = path.display().to_string();
|
||||||
|
lock!(file_window).picked_node = true;
|
||||||
|
}
|
||||||
|
NodeDB => {
|
||||||
|
lock!(file_window).nodedb_path = path.display().to_string();
|
||||||
|
lock!(file_window).picked_nodedb = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
info!("Gupaxx | No path selected for {}", name);
|
||||||
|
}
|
||||||
|
|
||||||
lock!(file_window).thread = false;
|
lock!(file_window).thread = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ cfg_if::cfg_if! {
|
||||||
if #[cfg(target_family = "unix")] {
|
if #[cfg(target_family = "unix")] {
|
||||||
pub(super) const GUPAX_BINARY: &str = "gupaxx";
|
pub(super) const GUPAX_BINARY: &str = "gupaxx";
|
||||||
pub(super) const P2POOL_BINARY: &str = "p2pool";
|
pub(super) const P2POOL_BINARY: &str = "p2pool";
|
||||||
|
pub(super) const NODE_BINARY: &str = "monerod";
|
||||||
pub(super) const XMRIG_BINARY: &str = "xmrig";
|
pub(super) const XMRIG_BINARY: &str = "xmrig";
|
||||||
pub(super) const XMRIG_PROXY_BINARY: &str = "xmrig-proxy";
|
pub(super) const XMRIG_PROXY_BINARY: &str = "xmrig-proxy";
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,7 @@ cfg_if::cfg_if! {
|
||||||
pub(super) const ARCHIVE_EXT: &str = "zip";
|
pub(super) const ARCHIVE_EXT: &str = "zip";
|
||||||
pub(super) const GUPAX_BINARY: &str = "Gupaxx.exe";
|
pub(super) const GUPAX_BINARY: &str = "Gupaxx.exe";
|
||||||
pub(super) const P2POOL_BINARY: &str = "p2pool.exe";
|
pub(super) const P2POOL_BINARY: &str = "p2pool.exe";
|
||||||
|
pub(super) const NODE_BINARY: &str = "monerod.exe";
|
||||||
pub(super) const XMRIG_BINARY: &str = "xmrig.exe";
|
pub(super) const XMRIG_BINARY: &str = "xmrig.exe";
|
||||||
pub(super) const XMRIG_PROXY_BINARY: &str = "xmrig-proxy.exe";
|
pub(super) const XMRIG_PROXY_BINARY: &str = "xmrig-proxy.exe";
|
||||||
} else if #[cfg(target_os = "linux")] {
|
} else if #[cfg(target_os = "linux")] {
|
||||||
|
@ -153,6 +155,22 @@ pub fn check_p2pool_path(path: &str) -> bool {
|
||||||
path == P2POOL_BINARY
|
path == P2POOL_BINARY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_node_path(path: &str) -> bool {
|
||||||
|
let path = match crate::disk::into_absolute_path(path.to_string()) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
let path = match path.file_name() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => {
|
||||||
|
error!("Couldn't get Node file name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
path == NODE_BINARY
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_xmrig_path(path: &str) -> bool {
|
pub fn check_xmrig_path(path: &str) -> bool {
|
||||||
let path = match crate::disk::into_absolute_path(path.to_string()) {
|
let path = match crate::disk::into_absolute_path(path.to_string()) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
@ -199,7 +217,8 @@ pub struct Update {
|
||||||
pub path_gupax: String, // Full path to current gupax
|
pub path_gupax: String, // Full path to current gupax
|
||||||
pub path_p2pool: String, // Full path to current p2pool
|
pub path_p2pool: String, // Full path to current p2pool
|
||||||
pub path_xmrig: String, // Full path to current xmrig
|
pub path_xmrig: String, // Full path to current xmrig
|
||||||
pub path_xp: String, // Full path to current xmrig
|
pub path_xp: String, // Full path to current xmrig-proxy
|
||||||
|
pub path_node: String, // Full path to current node
|
||||||
pub updating: Arc<Mutex<bool>>, // Is an update in progress?
|
pub updating: Arc<Mutex<bool>>, // Is an update in progress?
|
||||||
pub prog: Arc<Mutex<f32>>, // Holds the 0-100% progress bar number
|
pub prog: Arc<Mutex<f32>>, // Holds the 0-100% progress bar number
|
||||||
pub msg: Arc<Mutex<String>>, // Message to display on [Gupax] tab while updating
|
pub msg: Arc<Mutex<String>>, // Message to display on [Gupax] tab while updating
|
||||||
|
@ -212,12 +231,14 @@ impl Update {
|
||||||
path_p2pool: PathBuf,
|
path_p2pool: PathBuf,
|
||||||
path_xmrig: PathBuf,
|
path_xmrig: PathBuf,
|
||||||
path_xp: PathBuf,
|
path_xp: PathBuf,
|
||||||
|
path_node: PathBuf,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
path_gupax,
|
path_gupax,
|
||||||
path_p2pool: path_p2pool.display().to_string(),
|
path_p2pool: path_p2pool.display().to_string(),
|
||||||
path_xmrig: path_xmrig.display().to_string(),
|
path_xmrig: path_xmrig.display().to_string(),
|
||||||
path_xp: path_xp.display().to_string(),
|
path_xp: path_xp.display().to_string(),
|
||||||
|
path_node: path_node.display().to_string(),
|
||||||
updating: arc_mut!(false),
|
updating: arc_mut!(false),
|
||||||
prog: arc_mut!(0.0),
|
prog: arc_mut!(0.0),
|
||||||
msg: arc_mut!(MSG_NONE.to_string()),
|
msg: arc_mut!(MSG_NONE.to_string()),
|
||||||
|
@ -299,6 +320,21 @@ impl Update {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Check node path for safety
|
||||||
|
let node_path = match into_absolute_path(gupax.node_path.clone()) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
error_state.set(
|
||||||
|
format!(
|
||||||
|
"Provided Node path could not be turned into an absolute path: {}",
|
||||||
|
e
|
||||||
|
),
|
||||||
|
ErrorFerris::Error,
|
||||||
|
ErrorButtons::Okay,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
// Check XMRig-Proxy path for safety
|
// Check XMRig-Proxy path for safety
|
||||||
let xmrig_proxy_path = match into_absolute_path(gupax.xmrig_proxy_path.clone()) {
|
let xmrig_proxy_path = match into_absolute_path(gupax.xmrig_proxy_path.clone()) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
|
@ -317,6 +353,7 @@ impl Update {
|
||||||
lock!(update).path_p2pool = p2pool_path.display().to_string();
|
lock!(update).path_p2pool = p2pool_path.display().to_string();
|
||||||
lock!(update).path_xmrig = xmrig_path.display().to_string();
|
lock!(update).path_xmrig = xmrig_path.display().to_string();
|
||||||
lock!(update).path_xp = xmrig_proxy_path.display().to_string();
|
lock!(update).path_xp = xmrig_proxy_path.display().to_string();
|
||||||
|
lock!(update).path_node = node_path.display().to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone before thread spawn
|
// Clone before thread spawn
|
||||||
|
@ -536,6 +573,7 @@ impl Update {
|
||||||
P2POOL_BINARY => lock!(update).path_p2pool.clone(),
|
P2POOL_BINARY => lock!(update).path_p2pool.clone(),
|
||||||
XMRIG_BINARY => lock!(update).path_xmrig.clone(),
|
XMRIG_BINARY => lock!(update).path_xmrig.clone(),
|
||||||
XMRIG_PROXY_BINARY => lock!(update).path_xp.clone(),
|
XMRIG_PROXY_BINARY => lock!(update).path_xp.clone(),
|
||||||
|
NODE_BINARY => lock!(update).path_node.clone(),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -552,6 +590,7 @@ impl Update {
|
||||||
P2POOL_BINARY => tmp_dir.clone() + "p2pool_old.exe",
|
P2POOL_BINARY => tmp_dir.clone() + "p2pool_old.exe",
|
||||||
XMRIG_BINARY => tmp_dir.clone() + "xmrig_old.exe",
|
XMRIG_BINARY => tmp_dir.clone() + "xmrig_old.exe",
|
||||||
XMRIG_PROXY_BINARY => tmp_dir.clone() + "xmrig-proxy_old.exe",
|
XMRIG_PROXY_BINARY => tmp_dir.clone() + "xmrig-proxy_old.exe",
|
||||||
|
NODE_BINARY => tmp_dir.clone() + "monerod_old.exe",
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
info!(
|
info!(
|
||||||
|
@ -568,7 +607,10 @@ impl Update {
|
||||||
);
|
);
|
||||||
// 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 lock!(og).gupax.bundled
|
||||||
&& (name == P2POOL_BINARY || name == XMRIG_BINARY || name == XMRIG_PROXY_BINARY)
|
&& (name == P2POOL_BINARY
|
||||||
|
|| name == XMRIG_BINARY
|
||||||
|
|| name == XMRIG_PROXY_BINARY
|
||||||
|
|| name == NODE_BINARY)
|
||||||
{
|
{
|
||||||
std::fs::create_dir_all(
|
std::fs::create_dir_all(
|
||||||
path.parent()
|
path.parent()
|
||||||
|
|
|
@ -41,11 +41,15 @@ pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub const DEFAULT_XMRIG_PATH: &str = r"XMRig\xmrig.exe";
|
pub const DEFAULT_XMRIG_PATH: &str = r"XMRig\xmrig.exe";
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
pub const DEFAULT_NODE_PATH: &str = r"node\monerod.exe";
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
pub const DEFAULT_XMRIG_PROXY_PATH: &str = r"XMRig-Proxy\xmrig-proxy.exe";
|
pub const DEFAULT_XMRIG_PROXY_PATH: &str = r"XMRig-Proxy\xmrig-proxy.exe";
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
|
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "xmrig-proxy/xmrig-proxy";
|
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "xmrig-proxy/xmrig-proxy";
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub const DEFAULT_XMRIG_NODE_PATH: &str = "node/monerod";
|
||||||
|
|
||||||
// Default to [/usr/bin/] for Linux distro builds.
|
// Default to [/usr/bin/] for Linux distro builds.
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
@ -58,6 +62,9 @@ pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
|
||||||
#[cfg(not(feature = "distro"))]
|
#[cfg(not(feature = "distro"))]
|
||||||
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "xmrig-proxy/xmrig-proxy";
|
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "xmrig-proxy/xmrig-proxy";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[cfg(not(feature = "distro"))]
|
||||||
|
pub const DEFAULT_NODE_PATH: &str = "node/monerod";
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
#[cfg(feature = "distro")]
|
#[cfg(feature = "distro")]
|
||||||
pub const DEFAULT_P2POOL_PATH: &str = "/usr/bin/p2pool";
|
pub const DEFAULT_P2POOL_PATH: &str = "/usr/bin/p2pool";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
@ -66,3 +73,6 @@ pub const DEFAULT_XMRIG_PATH: &str = "/usr/bin/xmrig";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
#[cfg(feature = "distro")]
|
#[cfg(feature = "distro")]
|
||||||
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "/usr/bin/xmrig-proxy";
|
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "/usr/bin/xmrig-proxy";
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[cfg(feature = "distro")]
|
||||||
|
pub const DEFAULT_NODE_PATH: &str = "/usr/bin/monerod";
|
||||||
|
|
|
@ -21,6 +21,7 @@ impl State {
|
||||||
xmrig: Xmrig::with_threads(max_threads, current_threads),
|
xmrig: Xmrig::with_threads(max_threads, current_threads),
|
||||||
xvb: Xvb::default(),
|
xvb: Xvb::default(),
|
||||||
xmrig_proxy: XmrigProxy::default(),
|
xmrig_proxy: XmrigProxy::default(),
|
||||||
|
node: Node::default(),
|
||||||
version: arc_mut!(Version::default()),
|
version: arc_mut!(Version::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +30,7 @@ impl State {
|
||||||
self.gupax.absolute_p2pool_path = into_absolute_path(self.gupax.p2pool_path.clone())?;
|
self.gupax.absolute_p2pool_path = into_absolute_path(self.gupax.p2pool_path.clone())?;
|
||||||
self.gupax.absolute_xmrig_path = into_absolute_path(self.gupax.xmrig_path.clone())?;
|
self.gupax.absolute_xmrig_path = into_absolute_path(self.gupax.xmrig_path.clone())?;
|
||||||
self.gupax.absolute_xp_path = into_absolute_path(self.gupax.xmrig_proxy_path.clone())?;
|
self.gupax.absolute_xp_path = into_absolute_path(self.gupax.xmrig_proxy_path.clone())?;
|
||||||
|
self.gupax.absolute_node_path = into_absolute_path(self.gupax.node_path.clone())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +165,7 @@ pub struct State {
|
||||||
pub xmrig: Xmrig,
|
pub xmrig: Xmrig,
|
||||||
pub xmrig_proxy: XmrigProxy,
|
pub xmrig_proxy: XmrigProxy,
|
||||||
pub xvb: Xvb,
|
pub xvb: Xvb,
|
||||||
|
pub node: Node,
|
||||||
pub version: Arc<Mutex<Version>>,
|
pub version: Arc<Mutex<Version>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,16 +184,18 @@ pub struct Gupax {
|
||||||
pub simple: bool,
|
pub simple: bool,
|
||||||
pub auto_update: bool,
|
pub auto_update: bool,
|
||||||
pub auto_p2pool: bool,
|
pub auto_p2pool: bool,
|
||||||
|
pub auto_node: bool,
|
||||||
pub auto_xmrig: bool,
|
pub auto_xmrig: bool,
|
||||||
pub auto_xp: bool,
|
pub auto_xp: bool,
|
||||||
pub auto_xvb: bool,
|
pub auto_xvb: bool,
|
||||||
// pub auto_monero: bool,
|
|
||||||
pub ask_before_quit: bool,
|
pub ask_before_quit: bool,
|
||||||
pub save_before_quit: bool,
|
pub save_before_quit: bool,
|
||||||
pub p2pool_path: String,
|
pub p2pool_path: String,
|
||||||
|
pub node_path: String,
|
||||||
pub xmrig_path: String,
|
pub xmrig_path: String,
|
||||||
pub xmrig_proxy_path: String,
|
pub xmrig_proxy_path: String,
|
||||||
pub absolute_p2pool_path: PathBuf,
|
pub absolute_p2pool_path: PathBuf,
|
||||||
|
pub absolute_node_path: PathBuf,
|
||||||
pub absolute_xmrig_path: PathBuf,
|
pub absolute_xmrig_path: PathBuf,
|
||||||
pub absolute_xp_path: PathBuf,
|
pub absolute_xp_path: PathBuf,
|
||||||
pub selected_width: u16,
|
pub selected_width: u16,
|
||||||
|
@ -225,6 +230,43 @@ pub struct P2pool {
|
||||||
pub selected_zmq: String,
|
pub selected_zmq: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Node {
|
||||||
|
pub simple: bool,
|
||||||
|
pub api_ip: String,
|
||||||
|
pub api_port: String,
|
||||||
|
pub out_peers: u16,
|
||||||
|
pub in_peers: u16,
|
||||||
|
pub log_level: u8,
|
||||||
|
pub arguments: String,
|
||||||
|
pub zmq_ip: String,
|
||||||
|
pub zmq_port: String,
|
||||||
|
pub pruned: bool,
|
||||||
|
pub dns_blocklist: bool,
|
||||||
|
pub disable_dns_checkpoint: bool,
|
||||||
|
pub path_db: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Node {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
simple: true,
|
||||||
|
api_ip: String::from("127.0.0.1"),
|
||||||
|
api_port: 18081.to_string(),
|
||||||
|
out_peers: 32,
|
||||||
|
in_peers: 64,
|
||||||
|
log_level: 0,
|
||||||
|
arguments: String::new(),
|
||||||
|
zmq_ip: String::from("127.0.0.1"),
|
||||||
|
zmq_port: 18083.to_string(),
|
||||||
|
pruned: true,
|
||||||
|
dns_blocklist: true,
|
||||||
|
disable_dns_checkpoint: true,
|
||||||
|
path_db: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
||||||
pub struct Xmrig {
|
pub struct Xmrig {
|
||||||
pub simple: bool,
|
pub simple: bool,
|
||||||
|
@ -414,6 +456,7 @@ impl Default for Gupax {
|
||||||
simple: true,
|
simple: true,
|
||||||
auto_update: false,
|
auto_update: false,
|
||||||
auto_p2pool: false,
|
auto_p2pool: false,
|
||||||
|
auto_node: false,
|
||||||
auto_xmrig: false,
|
auto_xmrig: false,
|
||||||
auto_xp: false,
|
auto_xp: false,
|
||||||
auto_xvb: false,
|
auto_xvb: false,
|
||||||
|
@ -421,10 +464,12 @@ impl Default for Gupax {
|
||||||
save_before_quit: true,
|
save_before_quit: true,
|
||||||
p2pool_path: DEFAULT_P2POOL_PATH.to_string(),
|
p2pool_path: DEFAULT_P2POOL_PATH.to_string(),
|
||||||
xmrig_path: DEFAULT_XMRIG_PATH.to_string(),
|
xmrig_path: DEFAULT_XMRIG_PATH.to_string(),
|
||||||
|
node_path: DEFAULT_NODE_PATH.to_string(),
|
||||||
xmrig_proxy_path: DEFAULT_XMRIG_PROXY_PATH.to_string(),
|
xmrig_proxy_path: DEFAULT_XMRIG_PROXY_PATH.to_string(),
|
||||||
absolute_p2pool_path: into_absolute_path(DEFAULT_P2POOL_PATH.to_string()).unwrap(),
|
absolute_p2pool_path: into_absolute_path(DEFAULT_P2POOL_PATH.to_string()).unwrap(),
|
||||||
absolute_xmrig_path: into_absolute_path(DEFAULT_XMRIG_PATH.to_string()).unwrap(),
|
absolute_xmrig_path: into_absolute_path(DEFAULT_XMRIG_PATH.to_string()).unwrap(),
|
||||||
absolute_xp_path: into_absolute_path(DEFAULT_XMRIG_PROXY_PATH.to_string()).unwrap(),
|
absolute_xp_path: into_absolute_path(DEFAULT_XMRIG_PROXY_PATH.to_string()).unwrap(),
|
||||||
|
absolute_node_path: into_absolute_path(DEFAULT_NODE_PATH.to_string()).unwrap(),
|
||||||
selected_width: APP_DEFAULT_WIDTH as u16,
|
selected_width: APP_DEFAULT_WIDTH as u16,
|
||||||
selected_height: APP_DEFAULT_HEIGHT as u16,
|
selected_height: APP_DEFAULT_HEIGHT as u16,
|
||||||
selected_scale: APP_DEFAULT_SCALE,
|
selected_scale: APP_DEFAULT_SCALE,
|
||||||
|
|
|
@ -30,6 +30,7 @@ mod test {
|
||||||
simple = true
|
simple = true
|
||||||
auto_update = true
|
auto_update = true
|
||||||
auto_p2pool = false
|
auto_p2pool = false
|
||||||
|
auto_node = false
|
||||||
auto_xmrig = false
|
auto_xmrig = false
|
||||||
auto_xvb = false
|
auto_xvb = false
|
||||||
auto_xp = false
|
auto_xp = false
|
||||||
|
@ -37,8 +38,10 @@ mod test {
|
||||||
save_before_quit = true
|
save_before_quit = true
|
||||||
p2pool_path = "p2pool/p2pool"
|
p2pool_path = "p2pool/p2pool"
|
||||||
xmrig_path = "xmrig/xmrig"
|
xmrig_path = "xmrig/xmrig"
|
||||||
|
node_path = "node/monerod"
|
||||||
xmrig_proxy_path = "xmrig-proxy/xmrig-proxy"
|
xmrig_proxy_path = "xmrig-proxy/xmrig-proxy"
|
||||||
absolute_p2pool_path = "/home/hinto/p2pool/p2pool"
|
absolute_p2pool_path = "/home/hinto/p2pool/p2pool"
|
||||||
|
absolute_node_path = "/home/hinto/node/monerod"
|
||||||
absolute_xmrig_path = "/home/hinto/xmrig/xmrig"
|
absolute_xmrig_path = "/home/hinto/xmrig/xmrig"
|
||||||
absolute_xp_path = "/home/hinto/xmrig/xmrig-proxy/xmrig-proxy"
|
absolute_xp_path = "/home/hinto/xmrig/xmrig-proxy/xmrig-proxy"
|
||||||
selected_width = 1280
|
selected_width = 1280
|
||||||
|
@ -137,10 +140,26 @@ mod test {
|
||||||
node = "Europe"
|
node = "Europe"
|
||||||
p2pool_buffer = 5
|
p2pool_buffer = 5
|
||||||
|
|
||||||
|
[node]
|
||||||
|
simple = false
|
||||||
|
api_ip = "127.0.0.1"
|
||||||
|
api_port = "18081"
|
||||||
|
out_peers = 32
|
||||||
|
in_peers = 64
|
||||||
|
log_level = 0
|
||||||
|
arguments = ""
|
||||||
|
zmq_ip = "127.0.0.1"
|
||||||
|
zmq_port = "18083"
|
||||||
|
pruned = true
|
||||||
|
dns_blocklist = true
|
||||||
|
disable_dns_checkpoint = true
|
||||||
|
path_db = ""
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
gupax = "v1.3.0"
|
gupax = "v1.3.0"
|
||||||
p2pool = "v2.5"
|
p2pool = "v2.5"
|
||||||
xmrig = "v6.18.0"
|
xmrig = "v6.18.0"
|
||||||
|
node = "v18.3.4"
|
||||||
"#;
|
"#;
|
||||||
let state = State::from_str(state).unwrap();
|
let state = State::from_str(state).unwrap();
|
||||||
State::to_string(&state).unwrap();
|
State::to_string(&state).unwrap();
|
||||||
|
|
|
@ -41,6 +41,7 @@ use crate::helper::{
|
||||||
};
|
};
|
||||||
use crate::{constants::*, disk::gupax_p2pool_api::GupaxP2poolApi, human::*, macros::*};
|
use crate::{constants::*, disk::gupax_p2pool_api::GupaxP2poolApi, human::*, macros::*};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use node::PubNodeApi;
|
||||||
use portable_pty::Child;
|
use portable_pty::Child;
|
||||||
use readable::up::Uptime;
|
use readable::up::Uptime;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -53,6 +54,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::xvb::{nodes::XvbNode, PubXvbApi};
|
use self::xvb::{nodes::XvbNode, PubXvbApi};
|
||||||
|
pub mod node;
|
||||||
pub mod p2pool;
|
pub mod p2pool;
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
pub mod xrig;
|
pub mod xrig;
|
||||||
|
@ -76,6 +78,7 @@ pub struct Helper {
|
||||||
pub uptime: HumanTime, // Gupax uptime formatting for humans
|
pub uptime: HumanTime, // Gupax uptime formatting for humans
|
||||||
pub pub_sys: Arc<Mutex<Sys>>, // The public API for [sysinfo] that the [Status] tab reads from
|
pub pub_sys: Arc<Mutex<Sys>>, // The public API for [sysinfo] that the [Status] tab reads from
|
||||||
pub p2pool: Arc<Mutex<Process>>, // P2Pool process state
|
pub p2pool: Arc<Mutex<Process>>, // P2Pool process state
|
||||||
|
pub node: Arc<Mutex<Process>>, // P2Pool process state
|
||||||
pub xmrig: Arc<Mutex<Process>>, // XMRig process state
|
pub xmrig: Arc<Mutex<Process>>, // XMRig process state
|
||||||
pub xmrig_proxy: Arc<Mutex<Process>>, // XMRig process state
|
pub xmrig_proxy: Arc<Mutex<Process>>, // XMRig process state
|
||||||
pub xvb: Arc<Mutex<Process>>, // XvB process state
|
pub xvb: Arc<Mutex<Process>>, // XvB process state
|
||||||
|
@ -83,11 +86,13 @@ pub struct Helper {
|
||||||
pub gui_api_xmrig: Arc<Mutex<PubXmrigApi>>, // XMRig API state (for GUI thread)
|
pub gui_api_xmrig: Arc<Mutex<PubXmrigApi>>, // XMRig API state (for GUI thread)
|
||||||
pub gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for GUI thread)
|
pub gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for GUI thread)
|
||||||
pub gui_api_xvb: Arc<Mutex<PubXvbApi>>, // XMRig API state (for GUI thread)
|
pub gui_api_xvb: Arc<Mutex<PubXvbApi>>, // XMRig API state (for GUI thread)
|
||||||
|
pub gui_api_node: Arc<Mutex<PubNodeApi>>, // Node API state (for GUI thread)
|
||||||
pub img_p2pool: Arc<Mutex<ImgP2pool>>, // A static "image" of the data P2Pool started with
|
pub img_p2pool: Arc<Mutex<ImgP2pool>>, // A static "image" of the data P2Pool started with
|
||||||
pub img_xmrig: Arc<Mutex<ImgXmrig>>, // A static "image" of the data XMRig started with
|
pub img_xmrig: Arc<Mutex<ImgXmrig>>, // A static "image" of the data XMRig started with
|
||||||
pub_api_p2pool: Arc<Mutex<PubP2poolApi>>, // P2Pool API state (for Helper/P2Pool thread)
|
pub_api_p2pool: Arc<Mutex<PubP2poolApi>>, // P2Pool API state (for Helper/P2Pool thread)
|
||||||
pub_api_xmrig: Arc<Mutex<PubXmrigApi>>, // XMRig API state (for Helper/XMRig thread)
|
pub_api_xmrig: Arc<Mutex<PubXmrigApi>>, // XMRig API state (for Helper/XMRig thread)
|
||||||
pub_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for Helper/XMRig-Proxy thread)
|
pub_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for Helper/XMRig-Proxy thread)
|
||||||
|
pub_api_node: Arc<Mutex<PubNodeApi>>, // Node API state (for Helper/Node thread)
|
||||||
pub_api_xvb: Arc<Mutex<PubXvbApi>>, // XvB API state (for Helper/XvB thread)
|
pub_api_xvb: Arc<Mutex<PubXvbApi>>, // XvB API state (for Helper/XvB thread)
|
||||||
pub gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>, //
|
pub gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>, //
|
||||||
}
|
}
|
||||||
|
@ -251,6 +256,7 @@ pub enum ProcessName {
|
||||||
Xmrig,
|
Xmrig,
|
||||||
XmrigProxy,
|
XmrigProxy,
|
||||||
Xvb,
|
Xvb,
|
||||||
|
Node,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ProcessState {
|
impl std::fmt::Display for ProcessState {
|
||||||
|
@ -270,6 +276,7 @@ impl std::fmt::Display for ProcessName {
|
||||||
ProcessName::Xmrig => write!(f, "XMRig"),
|
ProcessName::Xmrig => write!(f, "XMRig"),
|
||||||
ProcessName::XmrigProxy => write!(f, "XMRig-Proxy"),
|
ProcessName::XmrigProxy => write!(f, "XMRig-Proxy"),
|
||||||
ProcessName::Xvb => write!(f, "XvB"),
|
ProcessName::Xvb => write!(f, "XvB"),
|
||||||
|
ProcessName::Node => write!(f, "Node"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,10 +292,12 @@ impl Helper {
|
||||||
xmrig: Arc<Mutex<Process>>,
|
xmrig: Arc<Mutex<Process>>,
|
||||||
xmrig_proxy: Arc<Mutex<Process>>,
|
xmrig_proxy: Arc<Mutex<Process>>,
|
||||||
xvb: Arc<Mutex<Process>>,
|
xvb: Arc<Mutex<Process>>,
|
||||||
|
node: Arc<Mutex<Process>>,
|
||||||
gui_api_p2pool: Arc<Mutex<PubP2poolApi>>,
|
gui_api_p2pool: Arc<Mutex<PubP2poolApi>>,
|
||||||
gui_api_xmrig: Arc<Mutex<PubXmrigApi>>,
|
gui_api_xmrig: Arc<Mutex<PubXmrigApi>>,
|
||||||
gui_api_xvb: Arc<Mutex<PubXvbApi>>,
|
gui_api_xvb: Arc<Mutex<PubXvbApi>>,
|
||||||
gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>,
|
gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>,
|
||||||
|
gui_api_node: Arc<Mutex<PubNodeApi>>,
|
||||||
img_p2pool: Arc<Mutex<ImgP2pool>>,
|
img_p2pool: Arc<Mutex<ImgP2pool>>,
|
||||||
img_xmrig: Arc<Mutex<ImgXmrig>>,
|
img_xmrig: Arc<Mutex<ImgXmrig>>,
|
||||||
gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>,
|
gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>,
|
||||||
|
@ -301,15 +310,18 @@ impl Helper {
|
||||||
pub_api_xmrig: arc_mut!(PubXmrigApi::new()),
|
pub_api_xmrig: arc_mut!(PubXmrigApi::new()),
|
||||||
pub_api_xp: arc_mut!(PubXmrigProxyApi::new()),
|
pub_api_xp: arc_mut!(PubXmrigProxyApi::new()),
|
||||||
pub_api_xvb: arc_mut!(PubXvbApi::new()),
|
pub_api_xvb: arc_mut!(PubXvbApi::new()),
|
||||||
|
pub_api_node: arc_mut!(PubNodeApi::new()),
|
||||||
// These are created when initializing [App], since it needs a handle to it as well
|
// These are created when initializing [App], since it needs a handle to it as well
|
||||||
p2pool,
|
p2pool,
|
||||||
xmrig,
|
xmrig,
|
||||||
xmrig_proxy,
|
xmrig_proxy,
|
||||||
xvb,
|
xvb,
|
||||||
|
node,
|
||||||
gui_api_p2pool,
|
gui_api_p2pool,
|
||||||
gui_api_xmrig,
|
gui_api_xmrig,
|
||||||
gui_api_xvb,
|
gui_api_xvb,
|
||||||
gui_api_xp,
|
gui_api_xp,
|
||||||
|
gui_api_node,
|
||||||
img_p2pool,
|
img_p2pool,
|
||||||
img_xmrig,
|
img_xmrig,
|
||||||
gupax_p2pool_api,
|
gupax_p2pool_api,
|
||||||
|
@ -419,15 +431,18 @@ impl Helper {
|
||||||
|
|
||||||
let helper = Arc::clone(helper);
|
let helper = Arc::clone(helper);
|
||||||
let lock = lock!(helper);
|
let lock = lock!(helper);
|
||||||
|
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);
|
||||||
let xmrig_proxy = Arc::clone(&lock.xmrig_proxy);
|
let xmrig_proxy = Arc::clone(&lock.xmrig_proxy);
|
||||||
let xvb = Arc::clone(&lock.xvb);
|
let xvb = Arc::clone(&lock.xvb);
|
||||||
let pub_sys = Arc::clone(&lock.pub_sys);
|
let pub_sys = Arc::clone(&lock.pub_sys);
|
||||||
|
let gui_api_node = Arc::clone(&lock.gui_api_node);
|
||||||
let gui_api_p2pool = Arc::clone(&lock.gui_api_p2pool);
|
let gui_api_p2pool = Arc::clone(&lock.gui_api_p2pool);
|
||||||
let gui_api_xmrig = Arc::clone(&lock.gui_api_xmrig);
|
let gui_api_xmrig = Arc::clone(&lock.gui_api_xmrig);
|
||||||
let gui_api_xp = Arc::clone(&lock.gui_api_xp);
|
let gui_api_xp = Arc::clone(&lock.gui_api_xp);
|
||||||
let gui_api_xvb = Arc::clone(&lock.gui_api_xvb);
|
let gui_api_xvb = Arc::clone(&lock.gui_api_xvb);
|
||||||
|
let pub_api_node = Arc::clone(&lock.pub_api_node);
|
||||||
let pub_api_p2pool = Arc::clone(&lock.pub_api_p2pool);
|
let pub_api_p2pool = Arc::clone(&lock.pub_api_p2pool);
|
||||||
let pub_api_xmrig = Arc::clone(&lock.pub_api_xmrig);
|
let pub_api_xmrig = Arc::clone(&lock.pub_api_xmrig);
|
||||||
let pub_api_xp = Arc::clone(&lock.pub_api_xp);
|
let pub_api_xp = Arc::clone(&lock.pub_api_xp);
|
||||||
|
@ -451,35 +466,48 @@ impl Helper {
|
||||||
|
|
||||||
// 2. Lock... EVERYTHING!
|
// 2. Lock... EVERYTHING!
|
||||||
let mut lock = lock!(helper);
|
let mut lock = lock!(helper);
|
||||||
debug!("Helper | Locking (1/12) ... [helper]");
|
debug!("Helper | Locking (1/15) ... [helper]");
|
||||||
|
let node = lock!(node);
|
||||||
|
debug!("Helper | Locking (2/15) ... [helper]");
|
||||||
let p2pool = lock!(p2pool);
|
let p2pool = lock!(p2pool);
|
||||||
debug!("Helper | Locking (2/12) ... [p2pool]");
|
debug!("Helper | Locking (3/15) ... [p2pool]");
|
||||||
let xmrig = lock!(xmrig);
|
let xmrig = lock!(xmrig);
|
||||||
debug!("Helper | Locking (3/12) ... [xmrig]");
|
debug!("Helper | Locking (4/15) ... [xmrig]");
|
||||||
let xmrig_proxy = lock!(xmrig_proxy);
|
let xmrig_proxy = lock!(xmrig_proxy);
|
||||||
debug!("Helper | Locking (3/12) ... [xmrig_proxy]");
|
debug!("Helper | Locking (5/15) ... [xmrig_proxy]");
|
||||||
let xvb = lock!(xvb);
|
let xvb = lock!(xvb);
|
||||||
debug!("Helper | Locking (4/12) ... [xvb]");
|
debug!("Helper | Locking (6/15) ... [xvb]");
|
||||||
let mut lock_pub_sys = lock!(pub_sys);
|
let mut lock_pub_sys = lock!(pub_sys);
|
||||||
debug!("Helper | Locking (5/12) ... [pub_sys]");
|
debug!("Helper | Locking (8/15) ... [gui_api_node]");
|
||||||
|
let mut gui_api_node = lock!(gui_api_node);
|
||||||
|
debug!("Helper | Locking (7/15) ... [pub_sys]");
|
||||||
let mut gui_api_p2pool = lock!(gui_api_p2pool);
|
let mut gui_api_p2pool = lock!(gui_api_p2pool);
|
||||||
debug!("Helper | Locking (6/12) ... [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 = lock!(gui_api_xmrig);
|
||||||
debug!("Helper | Locking (7/12) ... [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 = lock!(gui_api_xp);
|
||||||
debug!("Helper | Locking (7/12) ... [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 = lock!(gui_api_xvb);
|
||||||
debug!("Helper | Locking (8/12) ... [gui_api_xvb]");
|
debug!("Helper | Locking (11/15) ... [gui_api_xvb]");
|
||||||
|
let mut pub_api_node = lock!(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 = lock!(pub_api_p2pool);
|
||||||
debug!("Helper | Locking (9/12) ... [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 = lock!(pub_api_xmrig);
|
||||||
debug!("Helper | Locking (10/12) ... [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 = lock!(pub_api_xp);
|
||||||
debug!("Helper | Locking (11/12) ... [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 = lock!(pub_api_xvb);
|
||||||
debug!("Helper | Locking (12/12) ... [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());
|
||||||
|
// If [Node] is alive...
|
||||||
|
if node.is_alive() {
|
||||||
|
debug!("Helper | Node is alive! Running [combine_gui_pub_api()]");
|
||||||
|
PubNodeApi::combine_gui_pub_api(&mut gui_api_node, &mut pub_api_node);
|
||||||
|
} else {
|
||||||
|
debug!("Helper | Node is dead! Skipping...");
|
||||||
|
}
|
||||||
// If [P2Pool] is alive...
|
// If [P2Pool] is alive...
|
||||||
if p2pool.is_alive() {
|
if p2pool.is_alive() {
|
||||||
debug!("Helper | P2Pool is alive! Running [combine_gui_pub_api()]");
|
debug!("Helper | P2Pool is alive! Running [combine_gui_pub_api()]");
|
||||||
|
@ -539,6 +567,8 @@ impl Helper {
|
||||||
debug!("Helper | Unlocking (3/12) ... [xmrig]");
|
debug!("Helper | Unlocking (3/12) ... [xmrig]");
|
||||||
drop(p2pool);
|
drop(p2pool);
|
||||||
debug!("Helper | Unlocking (4/12) ... [p2pool]");
|
debug!("Helper | Unlocking (4/12) ... [p2pool]");
|
||||||
|
drop(node);
|
||||||
|
debug!("Helper | Unlocking (4/12) ... [node]");
|
||||||
drop(pub_api_xvb);
|
drop(pub_api_xvb);
|
||||||
debug!("Helper | Unlocking (5/12) ... [pub_api_xvb]");
|
debug!("Helper | Unlocking (5/12) ... [pub_api_xvb]");
|
||||||
drop(pub_api_xp);
|
drop(pub_api_xp);
|
||||||
|
@ -547,6 +577,8 @@ impl Helper {
|
||||||
debug!("Helper | Unlocking (6/12) ... [pub_api_xmrig]");
|
debug!("Helper | Unlocking (6/12) ... [pub_api_xmrig]");
|
||||||
drop(pub_api_p2pool);
|
drop(pub_api_p2pool);
|
||||||
debug!("Helper | Unlocking (7/12) ... [pub_api_p2pool]");
|
debug!("Helper | Unlocking (7/12) ... [pub_api_p2pool]");
|
||||||
|
drop(pub_api_node);
|
||||||
|
debug!("Helper | Unlocking (7/12) ... [node]");
|
||||||
drop(gui_api_xvb);
|
drop(gui_api_xvb);
|
||||||
debug!("Helper | Unlocking (8/12) ... [gui_api_xvb]");
|
debug!("Helper | Unlocking (8/12) ... [gui_api_xvb]");
|
||||||
drop(gui_api_xp);
|
drop(gui_api_xp);
|
||||||
|
@ -555,6 +587,8 @@ impl Helper {
|
||||||
debug!("Helper | Unlocking (10/12) ... [gui_api_xmrig]");
|
debug!("Helper | Unlocking (10/12) ... [gui_api_xmrig]");
|
||||||
drop(gui_api_p2pool);
|
drop(gui_api_p2pool);
|
||||||
debug!("Helper | Unlocking (11/12) ... [gui_api_p2pool]");
|
debug!("Helper | Unlocking (11/12) ... [gui_api_p2pool]");
|
||||||
|
drop(gui_api_node);
|
||||||
|
debug!("Helper | Unlocking (11/12) ... [node]");
|
||||||
drop(lock);
|
drop(lock);
|
||||||
debug!("Helper | Unlocking (12/12) ... [helper]");
|
debug!("Helper | Unlocking (12/12) ... [helper]");
|
||||||
|
|
||||||
|
|
396
src/helper/node.rs
Normal file
396
src/helper/node.rs
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
use std::{
|
||||||
|
path::Path,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
|
use enclose::enc;
|
||||||
|
use log::{debug, error, info, warn};
|
||||||
|
use readable::byte::Byte;
|
||||||
|
use reqwest::Client;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio::spawn;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
disk::state::Node,
|
||||||
|
helper::{
|
||||||
|
check_died, check_user_input, signal_end, sleep_end_loop, ProcessName, ProcessSignal,
|
||||||
|
ProcessState,
|
||||||
|
},
|
||||||
|
macros::{arc_mut, lock2, sleep},
|
||||||
|
};
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
use super::{lock, Helper, HumanNumber, HumanTime, Process};
|
||||||
|
|
||||||
|
impl Helper {
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
fn read_pty_node(
|
||||||
|
output_parse: Arc<Mutex<String>>,
|
||||||
|
output_pub: Arc<Mutex<String>>,
|
||||||
|
reader: Box<dyn std::io::Read + Send>,
|
||||||
|
) {
|
||||||
|
use std::io::BufRead;
|
||||||
|
let mut stdout = std::io::BufReader::new(reader).lines();
|
||||||
|
|
||||||
|
// // Run a ANSI escape sequence filter for the first few lines.
|
||||||
|
let mut i = 0;
|
||||||
|
while let Some(Ok(line)) = stdout.next() {
|
||||||
|
let line = strip_ansi_escapes::strip_str(line);
|
||||||
|
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
|
||||||
|
error!("Node PTY Parse | Output error: {}", e);
|
||||||
|
}
|
||||||
|
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
|
||||||
|
error!("Node PTY Pub | Output error: {}", e);
|
||||||
|
}
|
||||||
|
if i > 20 {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while let Some(Ok(line)) = stdout.next() {
|
||||||
|
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
|
||||||
|
error!("P2Pool PTY Parse | Output error: {}", e);
|
||||||
|
}
|
||||||
|
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
|
||||||
|
error!("P2Pool PTY Pub | Output error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn build_node_args(state: &crate::disk::state::Node) -> Vec<String> {
|
||||||
|
let mut args = Vec::with_capacity(500);
|
||||||
|
if !state.arguments.is_empty() {
|
||||||
|
args.push(state.arguments.clone());
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [Simple]
|
||||||
|
if state.simple {
|
||||||
|
// Build the node argument to be compatible with p2pool, prune by default
|
||||||
|
args.push("--zmq-pub".to_string());
|
||||||
|
args.push("tcp://127.0.0.1:18083".to_string()); // Local P2Pool (the default)
|
||||||
|
args.push("--out-peers".to_string());
|
||||||
|
args.push("32".to_string());
|
||||||
|
args.push("--in-peers".to_string());
|
||||||
|
args.push("64".to_string()); // Rig name
|
||||||
|
args.push("--add-priority-node".to_string());
|
||||||
|
args.push("p2pmd.xmrvsbeast.com:18080".to_string());
|
||||||
|
args.push("--add-priority-node".to_string());
|
||||||
|
args.push("nodes.hashvault.pro:18080".to_string());
|
||||||
|
args.push("--disable-dns-checkpoints".to_string());
|
||||||
|
args.push("--enable-dns-blocklist".to_string());
|
||||||
|
args.push("--sync-pruned-blocks".to_string());
|
||||||
|
args.push("--prune-blockchain".to_string());
|
||||||
|
|
||||||
|
// [Advanced]
|
||||||
|
} else {
|
||||||
|
let dir = if state.path_db.is_empty() {
|
||||||
|
String::from(".bitmonero")
|
||||||
|
} else {
|
||||||
|
state.path_db.to_string()
|
||||||
|
};
|
||||||
|
args.push("--data-dir".to_string());
|
||||||
|
args.push(dir);
|
||||||
|
args.push("--zmq-pub".to_string());
|
||||||
|
args.push(format!("tcp://{}:{}", state.zmq_ip, state.zmq_port));
|
||||||
|
args.push("--rpc-bind-ip".to_string());
|
||||||
|
args.push(state.api_ip.clone());
|
||||||
|
args.push("--rpc-bind-port".to_string());
|
||||||
|
args.push(state.api_port.to_string());
|
||||||
|
args.push("--out-peers".to_string());
|
||||||
|
args.push(state.out_peers.to_string());
|
||||||
|
args.push("--in-peers".to_string());
|
||||||
|
args.push(state.in_peers.to_string());
|
||||||
|
args.push("--sync-pruned-blocks".to_string());
|
||||||
|
if state.dns_blocklist {
|
||||||
|
args.push("--enable-dns-blocklist".to_string());
|
||||||
|
}
|
||||||
|
if state.disable_dns_checkpoint {
|
||||||
|
args.push("--disable-dns-checkpoints".to_string());
|
||||||
|
}
|
||||||
|
if state.pruned {
|
||||||
|
args.push("--prune-blockchain".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args
|
||||||
|
}
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
// Just sets some signals for the watchdog thread to pick up on.
|
||||||
|
pub fn stop_node(helper: &Arc<Mutex<Self>>) {
|
||||||
|
info!("Node | Attempting to stop...");
|
||||||
|
lock2!(helper, node).signal = ProcessSignal::Stop;
|
||||||
|
lock2!(helper, node).state = ProcessState::Middle;
|
||||||
|
let gui_api = Arc::clone(&lock!(helper).gui_api_node);
|
||||||
|
let pub_api = Arc::clone(&lock!(helper).pub_api_node);
|
||||||
|
*lock!(pub_api) = PubNodeApi::new();
|
||||||
|
*lock!(gui_api) = PubNodeApi::new();
|
||||||
|
}
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
// The "restart frontend" to a "frontend" function.
|
||||||
|
// 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) {
|
||||||
|
info!("Node | Attempting to restart...");
|
||||||
|
lock2!(helper, node).signal = ProcessSignal::Restart;
|
||||||
|
lock2!(helper, node).state = ProcessState::Middle;
|
||||||
|
|
||||||
|
let helper = Arc::clone(helper);
|
||||||
|
let state = state.clone();
|
||||||
|
let path = path.to_path_buf();
|
||||||
|
// This thread lives to wait, start p2pool then die.
|
||||||
|
thread::spawn(move || {
|
||||||
|
while lock2!(helper, node).state != ProcessState::Waiting {
|
||||||
|
warn!("Node | Want to restart but process is still alive, waiting...");
|
||||||
|
sleep!(1000);
|
||||||
|
}
|
||||||
|
// Ok, process is not alive, start the new one!
|
||||||
|
info!("Node | Old process seems dead, starting new one!");
|
||||||
|
Self::start_node(&helper, &state, &path);
|
||||||
|
});
|
||||||
|
info!("Node | Restart ... OK");
|
||||||
|
}
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
// 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) {
|
||||||
|
lock2!(helper, node).state = ProcessState::Middle;
|
||||||
|
|
||||||
|
let args = Self::build_node_args(state);
|
||||||
|
|
||||||
|
// Print arguments & user settings to console
|
||||||
|
crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args));
|
||||||
|
|
||||||
|
// Spawn watchdog thread
|
||||||
|
let process = Arc::clone(&lock!(helper).node);
|
||||||
|
let gui_api = Arc::clone(&lock!(helper).gui_api_node);
|
||||||
|
let pub_api = Arc::clone(&lock!(helper).pub_api_node);
|
||||||
|
let path = path.to_path_buf();
|
||||||
|
let state = state.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
Self::spawn_node_watchdog(&process, &gui_api, &pub_api, args, path, state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[tokio::main]
|
||||||
|
#[allow(clippy::await_holding_lock)]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
async fn spawn_node_watchdog(
|
||||||
|
process: &Arc<Mutex<Process>>,
|
||||||
|
gui_api: &Arc<Mutex<PubNodeApi>>,
|
||||||
|
pub_api: &Arc<Mutex<PubNodeApi>>,
|
||||||
|
args: Vec<String>,
|
||||||
|
path: std::path::PathBuf,
|
||||||
|
state: Node,
|
||||||
|
) {
|
||||||
|
lock!(process).start = Instant::now();
|
||||||
|
// spawn pty
|
||||||
|
debug!("Node | Creating PTY...");
|
||||||
|
let pty = portable_pty::native_pty_system();
|
||||||
|
let pair = pty
|
||||||
|
.openpty(portable_pty::PtySize {
|
||||||
|
rows: 100,
|
||||||
|
cols: 1000,
|
||||||
|
pixel_width: 0,
|
||||||
|
pixel_height: 0,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
// 4. Spawn 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 output_parse = Arc::clone(&lock!(process).output_parse);
|
||||||
|
let output_pub = Arc::clone(&lock!(process).output_pub);
|
||||||
|
spawn(enc!((output_parse, output_pub) async move {
|
||||||
|
Self::read_pty_node(output_parse, output_pub, reader);
|
||||||
|
}));
|
||||||
|
// 1b. Create command
|
||||||
|
debug!("Node | Creating command...");
|
||||||
|
let mut cmd = portable_pty::cmdbuilder::CommandBuilder::new(path.clone());
|
||||||
|
cmd.args(args);
|
||||||
|
cmd.cwd(path.as_path().parent().unwrap());
|
||||||
|
// 1c. Create child
|
||||||
|
debug!("Node | Creating child...");
|
||||||
|
let child_pty = arc_mut!(pair.slave.spawn_command(cmd).unwrap());
|
||||||
|
drop(pair.slave);
|
||||||
|
let mut stdin = pair.master.take_writer().unwrap();
|
||||||
|
// set state
|
||||||
|
let client = Client::new();
|
||||||
|
lock!(process).state = ProcessState::Syncing;
|
||||||
|
lock!(process).signal = ProcessSignal::None;
|
||||||
|
// reset stats
|
||||||
|
*lock!(pub_api) = PubNodeApi::new();
|
||||||
|
*lock!(gui_api) = PubNodeApi::new();
|
||||||
|
// loop
|
||||||
|
let start = lock!(process).start;
|
||||||
|
info!("Node | Entering watchdog mode... woof!");
|
||||||
|
loop {
|
||||||
|
let now = Instant::now();
|
||||||
|
debug!("Node Watchdog | ----------- Start of loop -----------");
|
||||||
|
|
||||||
|
// check state
|
||||||
|
if check_died(
|
||||||
|
&child_pty,
|
||||||
|
&mut lock!(process),
|
||||||
|
&start,
|
||||||
|
&mut lock!(gui_api).output,
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check signal
|
||||||
|
if signal_end(process, &child_pty, &start, &mut lock!(gui_api).output) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check user input
|
||||||
|
check_user_input(process, &mut stdin);
|
||||||
|
// get data output/api
|
||||||
|
|
||||||
|
// Check if logs need resetting
|
||||||
|
debug!("Node Watchdog | Attempting GUI log reset check");
|
||||||
|
{
|
||||||
|
let mut lock = lock!(gui_api);
|
||||||
|
Self::check_reset_gui_output(&mut lock.output, ProcessName::Node);
|
||||||
|
}
|
||||||
|
// No need to check output since monerod has a sufficient API
|
||||||
|
// Always update from output
|
||||||
|
debug!("Node Watchdog | Starting [update_from_output()]");
|
||||||
|
PubNodeApi::update_from_output(pub_api, &output_pub, start.elapsed());
|
||||||
|
// update data from api
|
||||||
|
debug!("Node Watchdog | Attempting HTTP API request...");
|
||||||
|
match PrivNodeApi::request_api(&client, &state).await {
|
||||||
|
Ok(priv_api) => {
|
||||||
|
debug!("Node Watchdog | HTTP API request OK, attempting [update_from_priv()]");
|
||||||
|
PubNodeApi::update_from_priv(pub_api, priv_api);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
// if node is just starting, do not throw an error
|
||||||
|
if start.elapsed() > Duration::from_secs(10) {
|
||||||
|
warn!(
|
||||||
|
"Node Watchdog | Could not send HTTP API request to node\n{}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// do not use more than 1 second for the loop
|
||||||
|
sleep_end_loop(now, ProcessName::Node).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. If loop broke, we must be done here.
|
||||||
|
info!("XMRig-Proxy Watchdog | Watchdog thread exiting... Goodbye!");
|
||||||
|
// sleep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct PubNodeApi {
|
||||||
|
pub output: String,
|
||||||
|
pub uptime: HumanTime,
|
||||||
|
pub blockheight: HumanNumber,
|
||||||
|
pub difficulty: HumanNumber,
|
||||||
|
pub database_size: String,
|
||||||
|
pub free_space: String,
|
||||||
|
pub nettype: String,
|
||||||
|
pub outgoing_connections: u16,
|
||||||
|
pub incoming_connections: u16,
|
||||||
|
pub status: String,
|
||||||
|
pub synchronized: bool,
|
||||||
|
}
|
||||||
|
impl Default for PubNodeApi {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubNodeApi {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
output: String::new(),
|
||||||
|
uptime: HumanTime::new(),
|
||||||
|
blockheight: HumanNumber::unknown(),
|
||||||
|
difficulty: HumanNumber::unknown(),
|
||||||
|
database_size: HumanNumber::unknown().to_string(),
|
||||||
|
free_space: HumanNumber::unknown().to_string(),
|
||||||
|
nettype: String::from("???"),
|
||||||
|
outgoing_connections: 0,
|
||||||
|
incoming_connections: 0,
|
||||||
|
status: String::from("Offline"),
|
||||||
|
synchronized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn combine_gui_pub_api(gui_api: &mut Self, pub_api: &mut Self) {
|
||||||
|
let output = std::mem::take(&mut gui_api.output);
|
||||||
|
let buf = std::mem::take(&mut pub_api.output);
|
||||||
|
*gui_api = Self {
|
||||||
|
output,
|
||||||
|
..pub_api.clone()
|
||||||
|
};
|
||||||
|
if !buf.is_empty() {
|
||||||
|
gui_api.output.push_str(&buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivNodeApi) {
|
||||||
|
let mut public = lock!(public);
|
||||||
|
*public = Self {
|
||||||
|
blockheight: HumanNumber::from_u64(private.result.height),
|
||||||
|
difficulty: HumanNumber::from_u64(private.result.difficulty),
|
||||||
|
database_size: Byte::from(private.result.database_size).to_string(),
|
||||||
|
free_space: Byte::from(private.result.free_space).to_string(),
|
||||||
|
nettype: private.result.nettype,
|
||||||
|
outgoing_connections: private.result.outgoing_connections_count,
|
||||||
|
incoming_connections: private.result.incoming_connections_count,
|
||||||
|
status: private.result.status,
|
||||||
|
synchronized: private.result.synchronized,
|
||||||
|
..std::mem::take(&mut *public)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn update_from_output(
|
||||||
|
public: &Arc<Mutex<Self>>,
|
||||||
|
output_pub: &Arc<Mutex<String>>,
|
||||||
|
elapsed: std::time::Duration,
|
||||||
|
) {
|
||||||
|
// 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 public = lock!(public);
|
||||||
|
if !output_pub.is_empty() {
|
||||||
|
public.output.push_str(&std::mem::take(&mut *output_pub));
|
||||||
|
}
|
||||||
|
// Update uptime
|
||||||
|
public.uptime = HumanTime::into_human(elapsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
struct PrivNodeApi {
|
||||||
|
result: ResultNodeJson,
|
||||||
|
}
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
struct ResultNodeJson {
|
||||||
|
pub height: u64,
|
||||||
|
pub difficulty: u64,
|
||||||
|
pub database_size: u64,
|
||||||
|
pub free_space: u64,
|
||||||
|
pub nettype: String,
|
||||||
|
pub outgoing_connections_count: u16,
|
||||||
|
pub incoming_connections_count: u16,
|
||||||
|
pub status: String,
|
||||||
|
pub synchronized: bool,
|
||||||
|
}
|
||||||
|
impl PrivNodeApi {
|
||||||
|
async fn request_api(
|
||||||
|
client: &Client,
|
||||||
|
state: &Node,
|
||||||
|
) -> std::result::Result<Self, anyhow::Error> {
|
||||||
|
let adr = format!("http://{}:{}/json_rpc", state.api_ip, state.api_port);
|
||||||
|
let private = client
|
||||||
|
.post(adr)
|
||||||
|
.body(r#"{"jsonrpc":"2.0","id":"0","method":"get_info"}"#)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json::<PrivNodeApi>()
|
||||||
|
.await?;
|
||||||
|
Ok(private)
|
||||||
|
}
|
||||||
|
}
|
29
src/inits.rs
29
src/inits.rs
|
@ -1,4 +1,5 @@
|
||||||
use crate::components::update::Update;
|
use crate::components::update::Update;
|
||||||
|
use crate::errors::process_running;
|
||||||
use crate::helper::{Helper, ProcessSignal};
|
use crate::helper::{Helper, ProcessSignal};
|
||||||
use crate::utils::constants::{
|
use crate::utils::constants::{
|
||||||
APP_MAX_HEIGHT, APP_MAX_WIDTH, APP_MIN_HEIGHT, APP_MIN_WIDTH, BYTES_ICON,
|
APP_MAX_HEIGHT, APP_MAX_WIDTH, APP_MIN_HEIGHT, APP_MIN_WIDTH, BYTES_ICON,
|
||||||
|
@ -43,7 +44,7 @@ pub fn init_text_styles(ctx: &egui::Context, width: f32, pixels_per_point: f32)
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Name("Tab".into()),
|
Name("Tab".into()),
|
||||||
FontId::new(scale * 1.2, egui::FontFamily::Monospace),
|
FontId::new(scale * 1.05, egui::FontFamily::Monospace),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Name("Bottom".into()),
|
Name("Bottom".into()),
|
||||||
|
@ -180,6 +181,26 @@ pub fn init_auto(app: &mut App) {
|
||||||
info!("Skipping auto-ping...");
|
info!("Skipping auto-ping...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [Auto-Node]
|
||||||
|
if app.state.gupax.auto_node {
|
||||||
|
if !Gupax::path_is_file(&app.state.gupax.node_path) {
|
||||||
|
warn!("Gupaxx | Node path is not a file! Skipping auto-node...");
|
||||||
|
} else if !crate::components::update::check_node_path(&app.state.gupax.node_path) {
|
||||||
|
warn!("Gupaxx | Node path is not valid! Skipping auto-node...");
|
||||||
|
} else if process_running(crate::helper::ProcessName::Node) {
|
||||||
|
warn!("Gupaxx | Node instance is already running outside of Gupaxx ! Skipping auto-node...");
|
||||||
|
} else {
|
||||||
|
// enable hugepage on linux
|
||||||
|
// sudo sysctl vm.nr_hugepages=3072
|
||||||
|
Helper::start_node(
|
||||||
|
&app.helper,
|
||||||
|
&app.state.node,
|
||||||
|
&app.state.gupax.absolute_node_path,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("Skipping auto-p2pool...");
|
||||||
|
}
|
||||||
// [Auto-P2Pool]
|
// [Auto-P2Pool]
|
||||||
if app.state.gupax.auto_p2pool {
|
if app.state.gupax.auto_p2pool {
|
||||||
if !Regexes::addr_ok(&app.state.p2pool.address) {
|
if !Regexes::addr_ok(&app.state.p2pool.address) {
|
||||||
|
@ -188,6 +209,8 @@ pub fn init_auto(app: &mut App) {
|
||||||
warn!("Gupaxx | P2Pool path is not a file! Skipping auto-p2pool...");
|
warn!("Gupaxx | P2Pool path is not a file! Skipping auto-p2pool...");
|
||||||
} else if !crate::components::update::check_p2pool_path(&app.state.gupax.p2pool_path) {
|
} else if !crate::components::update::check_p2pool_path(&app.state.gupax.p2pool_path) {
|
||||||
warn!("Gupaxx | P2Pool path is not valid! Skipping auto-p2pool...");
|
warn!("Gupaxx | P2Pool path is not valid! Skipping auto-p2pool...");
|
||||||
|
} else if process_running(crate::helper::ProcessName::P2pool) {
|
||||||
|
warn!("Gupaxx | P2pool instance is already running outside of Gupaxx ! Skipping auto-node...");
|
||||||
} else {
|
} else {
|
||||||
let backup_hosts = app.gather_backup_hosts();
|
let backup_hosts = app.gather_backup_hosts();
|
||||||
Helper::start_p2pool(
|
Helper::start_p2pool(
|
||||||
|
@ -207,6 +230,8 @@ pub fn init_auto(app: &mut App) {
|
||||||
warn!("Gupaxx | XMRig path is not an executable! Skipping auto-xmrig...");
|
warn!("Gupaxx | XMRig path is not an executable! Skipping auto-xmrig...");
|
||||||
} else if !crate::components::update::check_xmrig_path(&app.state.gupax.xmrig_path) {
|
} else if !crate::components::update::check_xmrig_path(&app.state.gupax.xmrig_path) {
|
||||||
warn!("Gupaxx | XMRig path is not valid! Skipping auto-xmrig...");
|
warn!("Gupaxx | XMRig path is not valid! Skipping auto-xmrig...");
|
||||||
|
} else if process_running(crate::helper::ProcessName::Xmrig) {
|
||||||
|
warn!("Gupaxx | Xmrig instance is already running outside of Gupaxx ! Skipping auto-node...");
|
||||||
} else if cfg!(windows) {
|
} else if cfg!(windows) {
|
||||||
Helper::start_xmrig(
|
Helper::start_xmrig(
|
||||||
&app.helper,
|
&app.helper,
|
||||||
|
@ -227,6 +252,8 @@ pub fn init_auto(app: &mut App) {
|
||||||
warn!("Gupaxx | Xmrig-Proxy path is not a file! Skipping auto-xmrig_proxy...");
|
warn!("Gupaxx | Xmrig-Proxy path is not a file! Skipping auto-xmrig_proxy...");
|
||||||
} else if !crate::components::update::check_xp_path(&app.state.gupax.xmrig_proxy_path) {
|
} else if !crate::components::update::check_xp_path(&app.state.gupax.xmrig_proxy_path) {
|
||||||
warn!("Gupaxx | Xmrig-Proxy path is not valid! Skipping auto-xmrig_proxy...");
|
warn!("Gupaxx | Xmrig-Proxy path is not valid! Skipping auto-xmrig_proxy...");
|
||||||
|
} else if process_running(crate::helper::ProcessName::XmrigProxy) {
|
||||||
|
warn!("Gupaxx | Xmrig-Proxy instance is already running outside of Gupaxx ! Skipping auto-node...");
|
||||||
} else {
|
} else {
|
||||||
Helper::start_xp(
|
Helper::start_xp(
|
||||||
&app.helper,
|
&app.helper,
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); // e.g:
|
||||||
pub const P2POOL_VERSION: &str = "v4.1";
|
pub const P2POOL_VERSION: &str = "v4.1";
|
||||||
pub const XMRIG_VERSION: &str = "v6.21.1";
|
pub const XMRIG_VERSION: &str = "v6.21.1";
|
||||||
pub const XMRIG_PROXY_VERSION: &str = "v6.21.1";
|
pub const XMRIG_PROXY_VERSION: &str = "v6.21.1";
|
||||||
|
pub const NODE_VERSION: &str = "v18.3.4";
|
||||||
pub const COMMIT: &str = env!("COMMIT"); // set in build.rs
|
pub const COMMIT: &str = env!("COMMIT"); // set in build.rs
|
||||||
// e.g: Gupax_v1_0_0
|
// e.g: Gupax_v1_0_0
|
||||||
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
|
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
|
||||||
|
@ -102,6 +103,12 @@ pub const P2POOL_MIDDLE: &str = "P2Pool is in the middle of (re)starting/stoppin
|
||||||
pub const P2POOL_SYNCING: &str =
|
pub const P2POOL_SYNCING: &str =
|
||||||
"P2Pool is still syncing. This indicator will turn GREEN when P2Pool is ready";
|
"P2Pool is still syncing. This indicator will turn GREEN when P2Pool is ready";
|
||||||
|
|
||||||
|
pub const NODE_ALIVE: &str = "Node is online and fully synchronized";
|
||||||
|
pub const NODE_DEAD: &str = "Node is offline";
|
||||||
|
pub const NODE_FAILED: &str = "Node is offline and failed when exiting";
|
||||||
|
pub const NODE_MIDDLE: &str = "Node is in the middle of (re)starting/stopping";
|
||||||
|
pub const NODE_SYNCING: &str =
|
||||||
|
"Node is still syncing. This indicator will turn GREEN when Node is ready";
|
||||||
pub const XMRIG_ALIVE: &str = "XMRig is online and mining";
|
pub const XMRIG_ALIVE: &str = "XMRig is online and mining";
|
||||||
pub const XMRIG_DEAD: &str = "XMRig is offline";
|
pub const XMRIG_DEAD: &str = "XMRig is offline";
|
||||||
pub const XMRIG_FAILED: &str = "XMRig is offline and failed when exiting";
|
pub const XMRIG_FAILED: &str = "XMRig is offline and failed when exiting";
|
||||||
|
@ -236,6 +243,17 @@ pub const STATUS_XVB_WINNER: &str = "Current Raffle Winner";
|
||||||
pub const STATUS_XVB_SHARE: &str = "Share effort";
|
pub const STATUS_XVB_SHARE: &str = "Share effort";
|
||||||
pub const STATUS_XVB_BLOCK_REWARD: &str = "Block reward";
|
pub const STATUS_XVB_BLOCK_REWARD: &str = "Block reward";
|
||||||
pub const STATUS_XVB_YEARLY: &str = "Estimated Reward (Yearly)";
|
pub const STATUS_XVB_YEARLY: &str = "Estimated Reward (Yearly)";
|
||||||
|
// Status Node
|
||||||
|
pub const STATUS_NODE_UPTIME: &str = "How long the Node has been online";
|
||||||
|
pub const STATUS_NODE_BLOCK_HEIGHT: &str = "The height of where the node is synchronized";
|
||||||
|
pub const STATUS_NODE_DIFFICULTY: &str = "current difficulty of the network";
|
||||||
|
pub const STATUS_NODE_DB_SIZE: &str = "Size of the database";
|
||||||
|
pub const STATUS_NODE_FREESPACE: &str = "Free space left on the partition storing the database";
|
||||||
|
pub const STATUS_NODE_NETTYPE: &str = "Type of network (mainnet, stagenet, testnet)";
|
||||||
|
pub const STATUS_NODE_OUT: &str = "Current number of active outbound connections";
|
||||||
|
pub const STATUS_NODE_IN: &str = "Current number of active incoming connections";
|
||||||
|
pub const STATUS_NODE_SYNC: &str = "Does the node is synchronized with the network ?";
|
||||||
|
pub const STATUS_NODE_STATUS: &str = "General status of the node";
|
||||||
// Status Submenus
|
// Status Submenus
|
||||||
pub const STATUS_SUBMENU_PROCESSES: &str =
|
pub const STATUS_SUBMENU_PROCESSES: &str =
|
||||||
"View the status of process related data for [Gupaxx|P2Pool|XMRig]";
|
"View the status of process related data for [Gupaxx|P2Pool|XMRig]";
|
||||||
|
@ -311,6 +329,7 @@ pub const GUPAX_SHOULD_RESTART: &str =
|
||||||
pub const GUPAX_ASK_BEFORE_QUIT: &str = "Ask before quitting Gupaxx";
|
pub const GUPAX_ASK_BEFORE_QUIT: &str = "Ask before quitting Gupaxx";
|
||||||
pub const GUPAX_SAVE_BEFORE_QUIT: &str = "Automatically save any changed settings before quitting";
|
pub const GUPAX_SAVE_BEFORE_QUIT: &str = "Automatically save any changed settings before quitting";
|
||||||
pub const GUPAX_AUTO_P2POOL: &str = "Automatically start P2Pool on Gupaxx startup. If you are using [P2Pool Simple], this will NOT wait for your [Auto-Ping] to finish, it will start P2Pool on the pool you already have selected. This option will fail if your P2Pool settings aren't valid!";
|
pub const GUPAX_AUTO_P2POOL: &str = "Automatically start P2Pool on Gupaxx startup. If you are using [P2Pool Simple], this will NOT wait for your [Auto-Ping] to finish, it will start P2Pool on the pool you already have selected. This option will fail if your P2Pool settings aren't valid!";
|
||||||
|
pub const GUPAX_AUTO_NODE: &str = "Automatically start Node on Gupaxx startup. This option will fail if your P2Pool settings aren't valid!";
|
||||||
pub const GUPAX_AUTO_XMRIG: &str = "Automatically start XMRig on Gupaxx startup. This option will fail if your XMRig settings aren't valid!";
|
pub const GUPAX_AUTO_XMRIG: &str = "Automatically start XMRig on Gupaxx startup. This option will fail if your XMRig settings aren't valid!";
|
||||||
pub const GUPAX_AUTO_XMRIG_PROXY: &str = "Automatically start XMRig-Proxy on Gupaxx startup.";
|
pub const GUPAX_AUTO_XMRIG_PROXY: &str = "Automatically start XMRig-Proxy on Gupaxx startup.";
|
||||||
pub const GUPAX_AUTO_XVB: &str = "Automatically start XvB on Gupaxx startup. This option will fail if your XvB settings aren't valid!";
|
pub const GUPAX_AUTO_XVB: &str = "Automatically start XvB on Gupaxx startup. This option will fail if your XvB settings aren't valid!";
|
||||||
|
@ -332,6 +351,7 @@ pub const GUPAX_TAB_GUPAX: &str = "Set the tab Gupaxx starts on to: Gupaxx";
|
||||||
pub const GUPAX_TAB_P2POOL: &str = "Set the tab Gupaxx starts on to: P2Pool";
|
pub const GUPAX_TAB_P2POOL: &str = "Set the tab Gupaxx starts on to: P2Pool";
|
||||||
pub const GUPAX_TAB_XMRIG: &str = "Set the tab Gupaxx starts on to: XMRig";
|
pub const GUPAX_TAB_XMRIG: &str = "Set the tab Gupaxx starts on to: XMRig";
|
||||||
pub const GUPAX_TAB_XVB: &str = "Set the tab Gupaxx starts on to: XvB";
|
pub const GUPAX_TAB_XVB: &str = "Set the tab Gupaxx starts on to: XvB";
|
||||||
|
pub const GUPAX_TAB_NODE: &str = "Set the default tab Gupaxx starts on to: Node";
|
||||||
|
|
||||||
pub const GUPAX_SIMPLE: &str = r#"Use simple Gupaxx settings:
|
pub const GUPAX_SIMPLE: &str = r#"Use simple Gupaxx settings:
|
||||||
- Update button
|
- Update button
|
||||||
|
@ -407,6 +427,39 @@ pub const LIST_ADD: &str = "Add the current values to the list";
|
||||||
pub const LIST_SAVE: &str = "Save the current values to the already existing entry";
|
pub const LIST_SAVE: &str = "Save the current values to the already existing entry";
|
||||||
pub const LIST_DELETE: &str = "Delete the currently selected entry";
|
pub const LIST_DELETE: &str = "Delete the currently selected entry";
|
||||||
pub const LIST_CLEAR: &str = "Clear all current values";
|
pub const LIST_CLEAR: &str = "Clear all current values";
|
||||||
|
// Node
|
||||||
|
pub const NODE_ARGUMENTS: &str = r#"WARNING: Make sure to set [--zmq-pub <tcp://127.0.0.1:18081>] so that P2Pool can connect to it !"#;
|
||||||
|
pub const NODE_INPUT: &str = "Send a command to Node";
|
||||||
|
pub const NODE_PRUNNING: &str = "Reduce the database size to a third. Does not have any security/privacy impact.If you have enough storage, a full node is preferable to make the network even more decentralized.";
|
||||||
|
pub const NODE_DB_PATH_EMPTY: &str =
|
||||||
|
"If the PATH of the DB is empty, the default ~/.bitmonero will be used.";
|
||||||
|
pub const NODE_DB_DIR: &str = "The PATH needs to be a correct path to a directory";
|
||||||
|
pub const NODE_SIMPLE: &str = r#"Use simple Node settings:
|
||||||
|
- Default Node settings"#;
|
||||||
|
pub const NODE_ADVANCED: &str = r#"Use advanced Node settings:
|
||||||
|
- Prunning
|
||||||
|
- Custom path for database
|
||||||
|
- Terminal input
|
||||||
|
- Overriding command arguments
|
||||||
|
- Manual zmq port
|
||||||
|
- Out/In peer setting
|
||||||
|
- Log level setting
|
||||||
|
- Disable DNS checkpoint
|
||||||
|
- DNS blocking"#;
|
||||||
|
pub const GUPAX_PATH_NODE: &str = "The location of the DB for the Node: Both absolute and relative paths are accepted; A red [X] will appear if there is no directory found at the given path";
|
||||||
|
pub const NODE_PATH_OK: &str = "PATH for DB is valid.";
|
||||||
|
pub const NODE_PATH_NOT_FILE: &str = "Node binary not found at the given PATH in the Gupaxx tab! To fix: goto the [Gupaxx Advanced] tab, select [Open] and specify where NODE is located.";
|
||||||
|
pub const NODE_PATH_NOT_VALID: &str = "Node binary at the given PATH in the Gupaxx tab doesn't look like Node! To fix: goto the [Gupaxx Advanced] tab, select [Open] and specify where Node is located.";
|
||||||
|
pub const NODE_PATH_EMPTY: &str = "Node PATH is empty! To fix: goto the [Gupaxx Advanced] tab, select [Open] and specify where Node is located.";
|
||||||
|
pub const NODE_URL: &str = "https://github.com/monero-project/monero";
|
||||||
|
pub const NODE_DNS_BLOCKLIST: &str =
|
||||||
|
"Apply realtime blocklist from DNS to ban known malicious nodes. (recommended)";
|
||||||
|
pub const NODE_DNS_CHECKPOINT: &str =
|
||||||
|
"Do not retrieve checkpoints from DNS to prevent periodic lags (recommended)";
|
||||||
|
pub const NODE_API_BIND: &str = "bind address of RPC API";
|
||||||
|
pub const NODE_API_PORT: &str = "RPC API listen port";
|
||||||
|
pub const NODE_ZMQ_BIND: &str = "bind address of ZMQ API";
|
||||||
|
pub const NODE_ZMQ_PORT: &str = "ZMQ API listen port";
|
||||||
// XMRig
|
// XMRig
|
||||||
pub const XMRIG_SIMPLE: &str = r#"Use simple XMRig settings:
|
pub const XMRIG_SIMPLE: &str = r#"Use simple XMRig settings:
|
||||||
- Mine to local P2Pool (localhost:3333)
|
- Mine to local P2Pool (localhost:3333)
|
||||||
|
|
|
@ -98,6 +98,7 @@ impl ErrorState {
|
||||||
|
|
||||||
pub fn process_running(process_name: ProcessName) -> bool {
|
pub fn process_running(process_name: ProcessName) -> bool {
|
||||||
let name = match process_name {
|
let name = match process_name {
|
||||||
|
ProcessName::Node => "monerod",
|
||||||
ProcessName::P2pool => "p2pool",
|
ProcessName::P2pool => "p2pool",
|
||||||
ProcessName::Xmrig => "xmrig",
|
ProcessName::Xmrig => "xmrig",
|
||||||
ProcessName::XmrigProxy => "xmrig-proxy",
|
ProcessName::XmrigProxy => "xmrig-proxy",
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//---------------------------------------------------------------------------------------------------- Use
|
//---------------------------------------------------------------------------------------------------- Use
|
||||||
use crate::constants::{COMMIT, GUPAX_VERSION, OS_NAME, P2POOL_VERSION, XMRIG_VERSION};
|
use crate::constants::{
|
||||||
|
COMMIT, GUPAX_VERSION, NODE_VERSION, OS_NAME, P2POOL_VERSION, XMRIG_VERSION,
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
#[cold]
|
#[cold]
|
||||||
|
@ -17,13 +19,15 @@ pub(crate) fn set_panic_hook(now: std::time::Instant) {
|
||||||
"{panic_info:#?}
|
"{panic_info:#?}
|
||||||
|
|
||||||
info:
|
info:
|
||||||
OS | {OS_NAME}
|
OS | {OS_NAME}
|
||||||
args | {args:?}
|
args | {args:?}
|
||||||
commit | {COMMIT}
|
commit | {COMMIT}
|
||||||
gupaxx | {GUPAX_VERSION}
|
gupaxx | {GUPAX_VERSION}
|
||||||
p2pool | {P2POOL_VERSION} (bundled)
|
monerod | {NODE_VERSION} (bundled)
|
||||||
xmrig | {XMRIG_VERSION} (bundled)
|
p2pool | {P2POOL_VERSION} (bundled)
|
||||||
uptime | {uptime} seconds
|
xmrig | {XMRIG_VERSION} (bundled)
|
||||||
|
xmrig-proxy | {XMRIG_VERSION} (bundled)
|
||||||
|
uptime | {uptime} seconds
|
||||||
|
|
||||||
stack backtrace:\n{stack_trace}",
|
stack backtrace:\n{stack_trace}",
|
||||||
);
|
);
|
||||||
|
|
|
@ -93,6 +93,32 @@ mv p2pool-v4.1-windows-x64/p2pool.exe /tmp/${FOLDER}/skel/windows_b/P2Pool/p2poo
|
||||||
rm -r p2pool-v4.1-windows-x64
|
rm -r p2pool-v4.1-windows-x64
|
||||||
rm p2pool-v4.1-windows-x64.zip
|
rm p2pool-v4.1-windows-x64.zip
|
||||||
|
|
||||||
|
## Download Monero Binaries
|
||||||
|
# download monero into directory linux
|
||||||
|
wget https://downloads.getmonero.org/cli/monero-linux-x64-v0.18.3.4.tar.bz2
|
||||||
|
tar -xf monero-linux-x64-v0.18.3.4.tar.bz2
|
||||||
|
mv monero-x86_64-linux-gnu-v0.18.3.4/monerod /tmp/${FOLDER}/skel/linux_b/node/monerod
|
||||||
|
rm -r monero-x86_64-linux-gnu-v0.18.3.4
|
||||||
|
rm monero-linux-x64-v0.18.3.4.tar.bz2
|
||||||
|
# download monero into directory macos-arm64
|
||||||
|
wget https://downloads.getmonero.org/cli/monero-mac-armv8-v0.18.3.4.tar.bz2
|
||||||
|
tar -xf monero-mac-armv8-v0.18.3.4.tar.bz2
|
||||||
|
mv monero-aarch64-apple-darwin11-v0.18.3.4/monerod /tmp/${FOLDER}/skel/macos-arm64_b/Gupaxx.app/Contents/MacOS/node/monerod
|
||||||
|
rm -r monero-aarch64-apple-darwin11-v0.18.3.4
|
||||||
|
rm monero-mac-armv8-v0.18.3.4.tar.bz2
|
||||||
|
# download monero into directory macos-x64
|
||||||
|
wget https://downloads.getmonero.org/cli/monero-mac-x64-v0.18.3.4.tar.bz2
|
||||||
|
tar -xf monero-mac-x64-v0.18.3.4.tar.bz2
|
||||||
|
mv monero-x86_64-apple-darwin11-v0.18.3.4/monerod /tmp/${FOLDER}/skel/macos-x64_b/Gupaxx.app/Contents/MacOS/node/monerod
|
||||||
|
rm -r monero-x86_64-apple-darwin11-v0.18.3.4
|
||||||
|
rm monero-mac-x64-v0.18.3.4.tar.bz2
|
||||||
|
# download monero into directory windows
|
||||||
|
wget https://downloads.getmonero.org/cli/monero-win-x64-v0.18.3.4.zip
|
||||||
|
unzip monero-win-x64-v0.18.3.4.zip
|
||||||
|
mv monero-x86_64-w64-mingw32-v0.18.3.4/monerod.exe /tmp/${FOLDER}/skel/windows_b/node/monerod.exe
|
||||||
|
rm -r monero-x86_64-w64-mingw32-v0.18.3.4
|
||||||
|
rm monero-win-x64-v0.18.3.4.zip
|
||||||
|
|
||||||
set +ex
|
set +ex
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -34,12 +34,14 @@ title "Linux folder check"
|
||||||
[[ -f linux_b/p2pool/p2pool ]]; check "linux_b/p2pool/p2pool"
|
[[ -f linux_b/p2pool/p2pool ]]; check "linux_b/p2pool/p2pool"
|
||||||
[[ -f linux_b/xmrig/xmrig ]]; check "linux_b/xmrig/xmrig"
|
[[ -f linux_b/xmrig/xmrig ]]; check "linux_b/xmrig/xmrig"
|
||||||
[[ -f linux_b/xmrig-proxy/xmrig-proxy ]]; check "linux_b/xmrig-proxy/xmrig-proxy"
|
[[ -f linux_b/xmrig-proxy/xmrig-proxy ]]; check "linux_b/xmrig-proxy/xmrig-proxy"
|
||||||
|
[[ -f linux_b/node/monerod ]]; check "linux_b/node/monerod"
|
||||||
title "macOS-x64 folder check"
|
title "macOS-x64 folder check"
|
||||||
[[ -d macos-x64/Gupaxx.app ]]; check "macos-x64/Gupaxx.app"
|
[[ -d macos-x64/Gupaxx.app ]]; check "macos-x64/Gupaxx.app"
|
||||||
[[ -d macos-x64_b/Gupaxx.app ]]; check "macos-x64_b/Gupaxx.app"
|
[[ -d macos-x64_b/Gupaxx.app ]]; check "macos-x64_b/Gupaxx.app"
|
||||||
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/p2pool/p2pool ]]; check "macos-x64_b/p2pool/p2pool"
|
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/p2pool/p2pool ]]; check "macos-x64_b/p2pool/p2pool"
|
||||||
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/xmrig/xmrig ]]; check "macos-x64_b/xmrig/xmrig"
|
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/xmrig/xmrig ]]; check "macos-x64_b/xmrig/xmrig"
|
||||||
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/xmrig-proxy/xmrig-proxy ]]; check "macos-x64_b/xmrig-proxy/xmrig-proxy"
|
[[ -f macos-x64_b/Gupaxx.app/Contents/MacOS/xmrig-proxy/xmrig-proxy ]]; check "macos-x64_b/xmrig-proxy/xmrig-proxy"
|
||||||
|
[[ -f macos-x64_b/node/monerod ]]; check "macos-x64_b/node/monerod"
|
||||||
title "macOS-arm64 folder check"
|
title "macOS-arm64 folder check"
|
||||||
[[ -d macos-arm64/Gupaxx.app ]]; check "macos-arm64/Gupaxx.app"
|
[[ -d macos-arm64/Gupaxx.app ]]; check "macos-arm64/Gupaxx.app"
|
||||||
[[ -d macos-arm64_b/Gupaxx.app ]]; check "macos-arm64_b/Gupaxx.app"
|
[[ -d macos-arm64_b/Gupaxx.app ]]; check "macos-arm64_b/Gupaxx.app"
|
||||||
|
@ -47,12 +49,14 @@ title "macOS-arm64 folder check"
|
||||||
[[ -f macos-arm64_b/Gupaxx.app/Contents/MacOS/xmrig/xmrig ]]; check "macos-arm64_b/xmrig/xmrig"
|
[[ -f macos-arm64_b/Gupaxx.app/Contents/MacOS/xmrig/xmrig ]]; check "macos-arm64_b/xmrig/xmrig"
|
||||||
## no macos-arm64 xmrig-proxy released todo
|
## no macos-arm64 xmrig-proxy released todo
|
||||||
# [[ -f macos-arm64_b/Gupaxx.app/Contents/MacOS/xmrig-proxy/xmrig-proxy ]]; check "macos-arm64_b/xmrig-proxy/xmrig-proxy"
|
# [[ -f macos-arm64_b/Gupaxx.app/Contents/MacOS/xmrig-proxy/xmrig-proxy ]]; check "macos-arm64_b/xmrig-proxy/xmrig-proxy"
|
||||||
|
[[ -f macos-arm64_b/node/monerod ]]; check "macos-arm64_b/node/monerod"
|
||||||
title "Windows folder check"
|
title "Windows folder check"
|
||||||
[[ -f windows/Gupaxx.exe ]]; check "windows/Gupaxx.exe"
|
[[ -f windows/Gupaxx.exe ]]; check "windows/Gupaxx.exe"
|
||||||
[[ -f windows_b/Gupaxx.exe ]]; check "windows_b/Gupaxx.exe"
|
[[ -f windows_b/Gupaxx.exe ]]; check "windows_b/Gupaxx.exe"
|
||||||
[[ -f windows_b/P2Pool/p2pool.exe ]]; check "windows_b/P2Pool/p2pool.exe"
|
[[ -f windows_b/P2Pool/p2pool.exe ]]; check "windows_b/P2Pool/p2pool.exe"
|
||||||
[[ -f windows_b/XMRig/xmrig.exe ]]; check "windows_b/XMRig/xmrig.exe"
|
[[ -f windows_b/XMRig/xmrig.exe ]]; check "windows_b/XMRig/xmrig.exe"
|
||||||
[[ -f windows_b/XMRig-Proxy/xmrig-proxy.exe ]]; check "windows_b/XMRig-Proxy/xmrig-proxy.exe"
|
[[ -f windows_b/XMRig-Proxy/xmrig-proxy.exe ]]; check "windows_b/XMRig-Proxy/xmrig-proxy.exe"
|
||||||
|
[[ -f windows_b/node/monerod.exe ]]; check "windows_b/node/monerod.exe"
|
||||||
|
|
||||||
# Get random date for tar/zip
|
# Get random date for tar/zip
|
||||||
title "RNG Date"
|
title "RNG Date"
|
||||||
|
@ -67,6 +71,7 @@ chmod +x linux_b/gupaxx
|
||||||
chmod +x linux_b/p2pool/p2pool
|
chmod +x linux_b/p2pool/p2pool
|
||||||
chmod +x linux_b/xmrig/xmrig
|
chmod +x linux_b/xmrig/xmrig
|
||||||
chmod +x linux_b/xmrig-proxy/xmrig-proxy
|
chmod +x linux_b/xmrig-proxy/xmrig-proxy
|
||||||
|
chmod +x linux_b/node/monderod
|
||||||
mv linux_b "gupaxx-$NEW_VER-linux-x64-bundle"; check "linux -> gupaxx-$NEW_VER-linux-x64-bundle"
|
mv linux_b "gupaxx-$NEW_VER-linux-x64-bundle"; check "linux -> gupaxx-$NEW_VER-linux-x64-bundle"
|
||||||
tar -czpf "gupaxx-${NEW_VER}-linux-x64-bundle.tar.gz" "gupaxx-$NEW_VER-linux-x64-bundle" --owner=lm --group=lm ; check "tar linux-bundle"
|
tar -czpf "gupaxx-${NEW_VER}-linux-x64-bundle.tar.gz" "gupaxx-$NEW_VER-linux-x64-bundle" --owner=lm --group=lm ; check "tar linux-bundle"
|
||||||
# Tar Linux Standalone
|
# Tar Linux Standalone
|
||||||
|
|
Loading…
Reference in a new issue