mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2025-01-01 19:49:22 +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_state = xvb.state;
|
||||
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.
|
||||
// Used as a reference for other uis.
|
||||
|
@ -101,6 +107,7 @@ impl eframe::App for App {
|
|||
self.top_panel(ctx);
|
||||
self.bottom_panel(
|
||||
ctx,
|
||||
node_state,
|
||||
p2pool_state,
|
||||
xmrig_state,
|
||||
xmrig_proxy_state,
|
||||
|
@ -109,10 +116,12 @@ impl eframe::App for App {
|
|||
wants_input,
|
||||
p2pool_is_waiting,
|
||||
xmrig_is_waiting,
|
||||
node_is_waiting,
|
||||
xmrig_proxy_is_waiting,
|
||||
xvb_is_waiting,
|
||||
p2pool_is_alive,
|
||||
xmrig_is_alive,
|
||||
node_is_alive,
|
||||
xmrig_proxy_is_alive,
|
||||
xvb_is_alive,
|
||||
);
|
||||
|
@ -124,6 +133,7 @@ impl eframe::App for App {
|
|||
ctx,
|
||||
frame,
|
||||
key,
|
||||
node_is_alive,
|
||||
p2pool_is_alive,
|
||||
xmrig_is_alive,
|
||||
xmrig_proxy_is_alive,
|
||||
|
|
|
@ -126,7 +126,8 @@ impl App {
|
|||
Tab::About => self.tab = Tab::Xvb,
|
||||
Tab::Status => self.tab = Tab::About,
|
||||
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::XmrigProxy => self.tab = Tab::Xmrig,
|
||||
Tab::Xvb => self.tab = Tab::XmrigProxy,
|
||||
|
@ -136,7 +137,8 @@ impl App {
|
|||
match self.tab {
|
||||
Tab::About => self.tab = Tab::Status,
|
||||
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::Xmrig => self.tab = Tab::XmrigProxy,
|
||||
Tab::XmrigProxy => self.tab = Tab::Xvb,
|
||||
|
@ -151,6 +153,7 @@ impl App {
|
|||
Submenu::Benchmarks => self.state.status.submenu = Submenu::P2pool,
|
||||
},
|
||||
Tab::Gupax => flip!(self.state.gupax.simple),
|
||||
Tab::Node => flip!(self.state.node.simple),
|
||||
Tab::P2pool => flip!(self.state.p2pool.simple),
|
||||
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
||||
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
||||
|
@ -170,6 +173,7 @@ impl App {
|
|||
Tab::Xmrig => flip!(self.state.xmrig.simple),
|
||||
Tab::XmrigProxy => flip!(self.state.xmrig_proxy.simple),
|
||||
Tab::Xvb => flip!(self.state.xvb.simple),
|
||||
Tab::Node => flip!(self.state.node.simple),
|
||||
Tab::About => (),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use crate::disk::state::State;
|
|||
use crate::errors::ErrorButtons;
|
||||
use crate::errors::ErrorFerris;
|
||||
use crate::errors::ErrorState;
|
||||
use crate::helper::node::PubNodeApi;
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::p2pool::PubP2poolApi;
|
||||
use crate::helper::xrig::xmrig::ImgXmrig;
|
||||
|
@ -103,10 +104,12 @@ pub struct App {
|
|||
// This includes the "helper" threads public P2Pool/XMRig's API.
|
||||
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 node: Arc<Mutex<Process>>, // [Node] process state
|
||||
pub p2pool: Arc<Mutex<Process>>, // [P2Pool] process state
|
||||
pub xmrig: Arc<Mutex<Process>>, // [XMRig] process state
|
||||
pub xmrig_proxy: Arc<Mutex<Process>>, // [XMRig-Proxy] 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 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
|
||||
|
@ -114,8 +117,9 @@ pub struct App {
|
|||
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
|
||||
// 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 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]
|
||||
// Sudo State
|
||||
pub sudo: Arc<Mutex<SudoState>>, // This is just a dummy struct on [Windows].
|
||||
|
@ -200,10 +204,16 @@ impl App {
|
|||
String::new(),
|
||||
PathBuf::new()
|
||||
));
|
||||
let node = arc_mut!(Process::new(
|
||||
ProcessName::Node,
|
||||
String::new(),
|
||||
PathBuf::new()
|
||||
));
|
||||
let p2pool_api = arc_mut!(PubP2poolApi::new());
|
||||
let xmrig_api = arc_mut!(PubXmrigApi::new());
|
||||
let xmrig_proxy_api = arc_mut!(PubXmrigProxyApi::new());
|
||||
let xvb_api = arc_mut!(PubXvbApi::new());
|
||||
let node_api = arc_mut!(PubNodeApi::new());
|
||||
let p2pool_img = arc_mut!(ImgP2pool::new());
|
||||
let xmrig_img = arc_mut!(ImgXmrig::new());
|
||||
|
||||
|
@ -248,6 +258,7 @@ impl App {
|
|||
String::new(),
|
||||
PathBuf::new(),
|
||||
PathBuf::new(),
|
||||
PathBuf::new(),
|
||||
PathBuf::new()
|
||||
)),
|
||||
file_window: FileWindow::new(),
|
||||
|
@ -265,24 +276,29 @@ impl App {
|
|||
xmrig.clone(),
|
||||
xmrig_proxy.clone(),
|
||||
xvb.clone(),
|
||||
node.clone(),
|
||||
p2pool_api.clone(),
|
||||
xmrig_api.clone(),
|
||||
xvb_api.clone(),
|
||||
xmrig_proxy_api.clone(),
|
||||
node_api.clone(),
|
||||
p2pool_img.clone(),
|
||||
xmrig_img.clone(),
|
||||
arc_mut!(GupaxP2poolApi::new())
|
||||
)),
|
||||
node,
|
||||
p2pool,
|
||||
xmrig,
|
||||
xmrig_proxy,
|
||||
xvb,
|
||||
node_api,
|
||||
p2pool_api,
|
||||
xvb_api,
|
||||
xmrig_api,
|
||||
xmrig_proxy_api,
|
||||
p2pool_img,
|
||||
xmrig_img,
|
||||
node_stdin: String::with_capacity(10),
|
||||
p2pool_stdin: String::with_capacity(10),
|
||||
xmrig_stdin: String::with_capacity(10),
|
||||
xmrig_proxy_stdin: String::with_capacity(10),
|
||||
|
@ -555,6 +571,7 @@ impl App {
|
|||
|
||||
// Apply 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 xmrig_path = og.gupax.absolute_xmrig_path.clone();
|
||||
let xmrig_proxy_path = og.gupax.absolute_xp_path.clone();
|
||||
|
@ -562,7 +579,8 @@ impl App {
|
|||
app.exe.clone(),
|
||||
p2pool_path,
|
||||
xmrig_path,
|
||||
xmrig_proxy_path
|
||||
xmrig_proxy_path,
|
||||
node_path
|
||||
));
|
||||
|
||||
// Set state version as compiled in version
|
||||
|
@ -688,6 +706,7 @@ pub enum Tab {
|
|||
About,
|
||||
Status,
|
||||
Gupax,
|
||||
Node,
|
||||
P2pool,
|
||||
Xmrig,
|
||||
XmrigProxy,
|
||||
|
|
|
@ -22,6 +22,7 @@ impl crate::app::App {
|
|||
pub fn bottom_panel(
|
||||
&mut self,
|
||||
ctx: &egui::Context,
|
||||
node_state: ProcessState,
|
||||
p2pool_state: ProcessState,
|
||||
xmrig_state: ProcessState,
|
||||
xmrig_proxy_state: ProcessState,
|
||||
|
@ -30,10 +31,12 @@ impl crate::app::App {
|
|||
wants_input: bool,
|
||||
p2pool_is_waiting: bool,
|
||||
xmrig_is_waiting: bool,
|
||||
node_is_waiting: bool,
|
||||
xmrig_proxy_is_waiting: bool,
|
||||
xvb_is_waiting: bool,
|
||||
p2pool_is_alive: bool,
|
||||
xmrig_is_alive: bool,
|
||||
node_is_alive: bool,
|
||||
xmrig_proxy_is_alive: bool,
|
||||
xvb_is_alive: bool,
|
||||
) {
|
||||
|
@ -74,6 +77,8 @@ impl crate::app::App {
|
|||
ui.label(self.os);
|
||||
// ui.add_sized(size, Label::new(self.os));
|
||||
ui.separator();
|
||||
status_node(node_state, ui, size);
|
||||
ui.separator();
|
||||
status_p2pool(p2pool_state, ui, size);
|
||||
ui.separator();
|
||||
status_xmrig(xmrig_state, ui, size);
|
||||
|
@ -96,6 +101,17 @@ impl crate::app::App {
|
|||
Tab::Gupax => {
|
||||
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 => {
|
||||
self.p2pool_submenu(ui, size);
|
||||
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(
|
||||
&mut self,
|
||||
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) {
|
||||
ui.group(|ui| {
|
||||
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 ⏺");
|
||||
}
|
||||
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) {
|
||||
let color;
|
||||
|
|
|
@ -88,43 +88,48 @@ impl Gupax {
|
|||
debug!("Gupaxx Tab | Rendering bool buttons");
|
||||
ui.horizontal(|ui| {
|
||||
ui.group(|ui| {
|
||||
let width = (size.x - SPACE * 17.0) / 8.0;
|
||||
let height = if self.simple {
|
||||
size.y / 10.0
|
||||
} else {
|
||||
size.y / 15.0
|
||||
};
|
||||
let size = vec2(width, height);
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Small);
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_update, "Auto-Update"))
|
||||
.on_hover_text(GUPAX_AUTO_UPDATE);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.bundled, "Bundle"))
|
||||
.on_hover_text(GUPAX_BUNDLED_UPDATE);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_p2pool, "Auto-P2Pool"))
|
||||
.on_hover_text(GUPAX_AUTO_P2POOL);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xmrig, "Auto-XMRig"))
|
||||
.on_hover_text(GUPAX_AUTO_XMRIG);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xp, "Auto-Proxy"))
|
||||
.on_hover_text(GUPAX_AUTO_XMRIG_PROXY);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xvb, "Auto-XvB"))
|
||||
.on_hover_text(GUPAX_AUTO_XVB);
|
||||
ui.separator();
|
||||
ui.add_sized(
|
||||
size,
|
||||
Checkbox::new(&mut self.ask_before_quit, "Confirm quit"),
|
||||
)
|
||||
.on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
||||
ui.separator();
|
||||
ui.add_sized(
|
||||
size,
|
||||
Checkbox::new(&mut self.save_before_quit, "Save on quit"),
|
||||
)
|
||||
.on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
||||
egui::ScrollArea::horizontal().show(ui, |ui| {
|
||||
let width = (size.x - SPACE * 17.0) / 8.0;
|
||||
let height = if self.simple {
|
||||
size.y / 10.0
|
||||
} else {
|
||||
size.y / 15.0
|
||||
};
|
||||
let size = vec2(width, height);
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Small);
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_update, "Auto-Update"))
|
||||
.on_hover_text(GUPAX_AUTO_UPDATE);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.bundled, "Bundle"))
|
||||
.on_hover_text(GUPAX_BUNDLED_UPDATE);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_node, "Auto-Node"))
|
||||
.on_hover_text(GUPAX_AUTO_NODE);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_p2pool, "Auto-P2Pool"))
|
||||
.on_hover_text(GUPAX_AUTO_P2POOL);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xmrig, "Auto-XMRig"))
|
||||
.on_hover_text(GUPAX_AUTO_XMRIG);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xp, "Auto-Proxy"))
|
||||
.on_hover_text(GUPAX_AUTO_XMRIG_PROXY);
|
||||
ui.separator();
|
||||
ui.add_sized(size, Checkbox::new(&mut self.auto_xvb, "Auto-XvB"))
|
||||
.on_hover_text(GUPAX_AUTO_XVB);
|
||||
ui.separator();
|
||||
ui.add_sized(
|
||||
size,
|
||||
Checkbox::new(&mut self.ask_before_quit, "Confirm quit"),
|
||||
)
|
||||
.on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
||||
ui.separator();
|
||||
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.available_width(), height / 2.0],
|
||||
Label::new(
|
||||
RichText::new("P2Pool/XMRig/XMRig-Proxy PATHs")
|
||||
RichText::new("Node/P2Pool/XMRig/XMRig-Proxy PATHs")
|
||||
.underline()
|
||||
.color(LIGHT_GRAY),
|
||||
),
|
||||
)
|
||||
.on_hover_text("Gupaxx is online");
|
||||
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| {
|
||||
if self.p2pool_path.is_empty() {
|
||||
ui.add_sized(
|
||||
|
@ -189,25 +232,25 @@ impl Gupax {
|
|||
if self.xmrig_path.is_empty() {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
} else if !Self::path_is_file(&self.xmrig_path) {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
} else if !crate::components::update::check_xmrig_path(&self.xmrig_path) {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
} else {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
}
|
||||
|
@ -228,26 +271,26 @@ impl Gupax {
|
|||
ui.add_sized(
|
||||
[text_edit, height],
|
||||
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);
|
||||
} else if !Self::path_is_file(&self.xmrig_proxy_path) {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
} else if !crate::components::update::check_xp_path(&self.xmrig_proxy_path) {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
} else {
|
||||
ui.add_sized(
|
||||
[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);
|
||||
}
|
||||
|
@ -273,6 +316,14 @@ impl Gupax {
|
|||
self.xmrig_path.clone_from(&guard.xmrig_path);
|
||||
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);
|
||||
|
||||
let height = ui.available_height() / 6.0;
|
||||
|
@ -280,7 +331,7 @@ impl Gupax {
|
|||
// Saved [Tab]
|
||||
debug!("Gupaxx Tab | Rendering [Tab] selector");
|
||||
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);
|
||||
ui.add_sized(
|
||||
[ui.available_width(), height / 2.0],
|
||||
|
@ -316,6 +367,14 @@ impl Gupax {
|
|||
self.tab = Tab::Gupax;
|
||||
}
|
||||
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
|
||||
.add_sized(
|
||||
size,
|
||||
|
|
|
@ -8,6 +8,7 @@ use egui::*;
|
|||
use log::debug;
|
||||
|
||||
mod gupax;
|
||||
mod node;
|
||||
mod p2pool;
|
||||
mod status;
|
||||
mod xmrig;
|
||||
|
@ -20,6 +21,7 @@ impl crate::app::App {
|
|||
ctx: &egui::Context,
|
||||
frame: &mut eframe::Frame,
|
||||
key: KeyPressed,
|
||||
node_is_alive: bool,
|
||||
p2pool_is_alive: bool,
|
||||
xmrig_is_alive: bool,
|
||||
xmrig_proxy_is_alive: bool,
|
||||
|
@ -156,12 +158,16 @@ path_xmr: {:#?}\n
|
|||
}
|
||||
Tab::Status => {
|
||||
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 => {
|
||||
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);
|
||||
}
|
||||
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 => {
|
||||
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);
|
||||
|
|
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,
|
||||
disk::{gupax_p2pool_api::GupaxP2poolApi, state::Status, status::*},
|
||||
helper::{
|
||||
node::PubNodeApi,
|
||||
p2pool::{ImgP2pool, PubP2poolApi},
|
||||
xrig::{
|
||||
xmrig::{ImgXmrig, PubXmrigApi},
|
||||
|
@ -42,12 +43,14 @@ impl Status {
|
|||
pub fn show(
|
||||
&mut self,
|
||||
sys: &Arc<Mutex<Sys>>,
|
||||
node_api: &Arc<Mutex<PubNodeApi>>,
|
||||
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
||||
xmrig_api: &Arc<Mutex<PubXmrigApi>>,
|
||||
xmrig_proxy_api: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||
xvb_api: &Arc<Mutex<PubXvbApi>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
node_alive: bool,
|
||||
p2pool_alive: bool,
|
||||
xmrig_alive: bool,
|
||||
xmrig_proxy_alive: bool,
|
||||
|
@ -65,6 +68,8 @@ impl Status {
|
|||
sys,
|
||||
size,
|
||||
ui,
|
||||
node_alive,
|
||||
node_api,
|
||||
p2pool_alive,
|
||||
p2pool_api,
|
||||
p2pool_img,
|
||||
|
|
|
@ -3,6 +3,7 @@ use readable::up::UptimeFull;
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::disk::state::Status;
|
||||
use crate::helper::node::PubNodeApi;
|
||||
use crate::helper::p2pool::{ImgP2pool, PubP2poolApi};
|
||||
use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
|
||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
|
@ -21,6 +22,8 @@ impl Status {
|
|||
sys: &Arc<Mutex<Sys>>,
|
||||
size: Vec2,
|
||||
ui: &mut egui::Ui,
|
||||
node_alive: bool,
|
||||
node_api: &Arc<Mutex<PubNodeApi>>,
|
||||
p2pool_alive: bool,
|
||||
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
|
@ -50,6 +53,8 @@ impl Status {
|
|||
|
||||
// [Gupax]
|
||||
gupax(ui, min_size, size, sys);
|
||||
// [Node]
|
||||
node(ui, min_size, size, node_alive, node_api);
|
||||
// [P2Pool]
|
||||
p2pool(ui, min_size, size, p2pool_alive, p2pool_api, p2pool_img);
|
||||
// [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::{SelectableLabel, TopBottomPanel};
|
||||
use egui::{ScrollArea, SelectableLabel, TopBottomPanel};
|
||||
use log::debug;
|
||||
|
||||
use crate::{app::Tab, utils::constants::SPACE};
|
||||
|
@ -8,82 +8,94 @@ impl crate::app::App {
|
|||
pub fn top_panel(&mut self, ctx: &egui::Context) {
|
||||
debug!("App | Rendering TOP tabs");
|
||||
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;
|
||||
ui.add_space(4.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::About, "About"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::About;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Status, "Status"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Status;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Gupax, "Gupaxx"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Gupax;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::P2pool, "P2Pool"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::P2pool;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Xmrig, "XMRig"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Xmrig;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::XmrigProxy, "Proxy"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::XmrigProxy;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Xvb, "XvB"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Xvb;
|
||||
}
|
||||
ScrollArea::horizontal().show(ui, |ui| {
|
||||
ui.style_mut().override_text_style = Some(Name("Tab".into()));
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::About, "About"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::About;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Status, "Status"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Status;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Gupax, "Gupaxx"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Gupax;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Node, "Node"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Node;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::P2pool, "P2Pool"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::P2pool;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::Xmrig, "XMRig"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
self.tab = Tab::Xmrig;
|
||||
}
|
||||
ui.separator();
|
||||
if ui
|
||||
.add_sized(
|
||||
[width, height],
|
||||
SelectableLabel::new(self.tab == Tab::XmrigProxy, "Proxy"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
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_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_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 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_proxy_path: String, // The picked xmrig-proxy path
|
||||
}
|
||||
|
@ -47,7 +51,11 @@ impl FileWindow {
|
|||
picked_p2pool: false,
|
||||
picked_xmrig: false,
|
||||
picked_xp: false,
|
||||
picked_node: false,
|
||||
picked_nodedb: false,
|
||||
p2pool_path: String::new(),
|
||||
node_path: String::new(),
|
||||
nodedb_path: String::new(),
|
||||
xmrig_path: String::new(),
|
||||
xmrig_proxy_path: String::new(),
|
||||
})
|
||||
|
@ -59,6 +67,8 @@ pub enum FileType {
|
|||
P2pool,
|
||||
Xmrig,
|
||||
XmrigProxy,
|
||||
Node,
|
||||
NodeDB,
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Ratio Lock
|
||||
|
@ -80,6 +90,14 @@ impl Gupax {
|
|||
_ => 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]
|
||||
#[inline(never)]
|
||||
|
@ -89,33 +107,48 @@ impl Gupax {
|
|||
P2pool => "P2Pool",
|
||||
Xmrig => "XMRig",
|
||||
XmrigProxy => "XMRigProxy",
|
||||
Node => "Node",
|
||||
NodeDB => "Node DB",
|
||||
};
|
||||
let file_window = file_window.clone();
|
||||
lock!(file_window).thread = true;
|
||||
thread::spawn(move || {
|
||||
match rfd::FileDialog::new()
|
||||
.set_title(format!("Select {} Binary for Gupaxx", name))
|
||||
.pick_file()
|
||||
{
|
||||
Some(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;
|
||||
}
|
||||
};
|
||||
}
|
||||
None => info!("Gupaxx | No path selected for {}", name),
|
||||
let path = match file_type {
|
||||
NodeDB => rfd::FileDialog::new()
|
||||
.set_title("Select a directory for the DB of your Node")
|
||||
.pick_folder(),
|
||||
_ => rfd::FileDialog::new()
|
||||
.set_title(format!("Select {} Binary for Gupaxx", name))
|
||||
.pick_file(),
|
||||
};
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ cfg_if::cfg_if! {
|
|||
if #[cfg(target_family = "unix")] {
|
||||
pub(super) const GUPAX_BINARY: &str = "gupaxx";
|
||||
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_PROXY_BINARY: &str = "xmrig-proxy";
|
||||
}
|
||||
|
@ -71,6 +72,7 @@ cfg_if::cfg_if! {
|
|||
pub(super) const ARCHIVE_EXT: &str = "zip";
|
||||
pub(super) const GUPAX_BINARY: &str = "Gupaxx.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_PROXY_BINARY: &str = "xmrig-proxy.exe";
|
||||
} else if #[cfg(target_os = "linux")] {
|
||||
|
@ -153,6 +155,22 @@ pub fn check_p2pool_path(path: &str) -> bool {
|
|||
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 {
|
||||
let path = match crate::disk::into_absolute_path(path.to_string()) {
|
||||
Ok(p) => p,
|
||||
|
@ -199,7 +217,8 @@ pub struct Update {
|
|||
pub path_gupax: String, // Full path to current gupax
|
||||
pub path_p2pool: String, // Full path to current p2pool
|
||||
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 prog: Arc<Mutex<f32>>, // Holds the 0-100% progress bar number
|
||||
pub msg: Arc<Mutex<String>>, // Message to display on [Gupax] tab while updating
|
||||
|
@ -212,12 +231,14 @@ impl Update {
|
|||
path_p2pool: PathBuf,
|
||||
path_xmrig: PathBuf,
|
||||
path_xp: PathBuf,
|
||||
path_node: PathBuf,
|
||||
) -> Self {
|
||||
Self {
|
||||
path_gupax,
|
||||
path_p2pool: path_p2pool.display().to_string(),
|
||||
path_xmrig: path_xmrig.display().to_string(),
|
||||
path_xp: path_xp.display().to_string(),
|
||||
path_node: path_node.display().to_string(),
|
||||
updating: arc_mut!(false),
|
||||
prog: arc_mut!(0.0),
|
||||
msg: arc_mut!(MSG_NONE.to_string()),
|
||||
|
@ -299,6 +320,21 @@ impl Update {
|
|||
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
|
||||
let xmrig_proxy_path = match into_absolute_path(gupax.xmrig_proxy_path.clone()) {
|
||||
Ok(p) => p,
|
||||
|
@ -317,6 +353,7 @@ impl Update {
|
|||
lock!(update).path_p2pool = p2pool_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_node = node_path.display().to_string();
|
||||
}
|
||||
|
||||
// Clone before thread spawn
|
||||
|
@ -536,6 +573,7 @@ impl Update {
|
|||
P2POOL_BINARY => lock!(update).path_p2pool.clone(),
|
||||
XMRIG_BINARY => lock!(update).path_xmrig.clone(),
|
||||
XMRIG_PROXY_BINARY => lock!(update).path_xp.clone(),
|
||||
NODE_BINARY => lock!(update).path_node.clone(),
|
||||
_ => continue,
|
||||
};
|
||||
found = true;
|
||||
|
@ -552,6 +590,7 @@ impl Update {
|
|||
P2POOL_BINARY => tmp_dir.clone() + "p2pool_old.exe",
|
||||
XMRIG_BINARY => tmp_dir.clone() + "xmrig_old.exe",
|
||||
XMRIG_PROXY_BINARY => tmp_dir.clone() + "xmrig-proxy_old.exe",
|
||||
NODE_BINARY => tmp_dir.clone() + "monerod_old.exe",
|
||||
_ => continue,
|
||||
};
|
||||
info!(
|
||||
|
@ -568,7 +607,10 @@ impl Update {
|
|||
);
|
||||
// if bundled, create directory for p2pool, xmrig and xmrig-proxy if not present
|
||||
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(
|
||||
path.parent()
|
||||
|
|
|
@ -41,11 +41,15 @@ pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
|
|||
#[cfg(target_os = "windows")]
|
||||
pub const DEFAULT_XMRIG_PATH: &str = r"XMRig\xmrig.exe";
|
||||
#[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";
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
|
||||
#[cfg(target_os = "macos")]
|
||||
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.
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -58,6 +62,9 @@ pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
|
|||
#[cfg(not(feature = "distro"))]
|
||||
pub const DEFAULT_XMRIG_PROXY_PATH: &str = "xmrig-proxy/xmrig-proxy";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(not(feature = "distro"))]
|
||||
pub const DEFAULT_NODE_PATH: &str = "node/monerod";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "distro")]
|
||||
pub const DEFAULT_P2POOL_PATH: &str = "/usr/bin/p2pool";
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -66,3 +73,6 @@ pub const DEFAULT_XMRIG_PATH: &str = "/usr/bin/xmrig";
|
|||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "distro")]
|
||||
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),
|
||||
xvb: Xvb::default(),
|
||||
xmrig_proxy: XmrigProxy::default(),
|
||||
node: Node::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_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_node_path = into_absolute_path(self.gupax.node_path.clone())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -163,6 +165,7 @@ pub struct State {
|
|||
pub xmrig: Xmrig,
|
||||
pub xmrig_proxy: XmrigProxy,
|
||||
pub xvb: Xvb,
|
||||
pub node: Node,
|
||||
pub version: Arc<Mutex<Version>>,
|
||||
}
|
||||
|
||||
|
@ -181,16 +184,18 @@ pub struct Gupax {
|
|||
pub simple: bool,
|
||||
pub auto_update: bool,
|
||||
pub auto_p2pool: bool,
|
||||
pub auto_node: bool,
|
||||
pub auto_xmrig: bool,
|
||||
pub auto_xp: bool,
|
||||
pub auto_xvb: bool,
|
||||
// pub auto_monero: bool,
|
||||
pub ask_before_quit: bool,
|
||||
pub save_before_quit: bool,
|
||||
pub p2pool_path: String,
|
||||
pub node_path: String,
|
||||
pub xmrig_path: String,
|
||||
pub xmrig_proxy_path: String,
|
||||
pub absolute_p2pool_path: PathBuf,
|
||||
pub absolute_node_path: PathBuf,
|
||||
pub absolute_xmrig_path: PathBuf,
|
||||
pub absolute_xp_path: PathBuf,
|
||||
pub selected_width: u16,
|
||||
|
@ -225,6 +230,43 @@ pub struct P2pool {
|
|||
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)]
|
||||
pub struct Xmrig {
|
||||
pub simple: bool,
|
||||
|
@ -414,6 +456,7 @@ impl Default for Gupax {
|
|||
simple: true,
|
||||
auto_update: false,
|
||||
auto_p2pool: false,
|
||||
auto_node: false,
|
||||
auto_xmrig: false,
|
||||
auto_xp: false,
|
||||
auto_xvb: false,
|
||||
|
@ -421,10 +464,12 @@ impl Default for Gupax {
|
|||
save_before_quit: true,
|
||||
p2pool_path: DEFAULT_P2POOL_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(),
|
||||
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_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_height: APP_DEFAULT_HEIGHT as u16,
|
||||
selected_scale: APP_DEFAULT_SCALE,
|
||||
|
|
|
@ -30,6 +30,7 @@ mod test {
|
|||
simple = true
|
||||
auto_update = true
|
||||
auto_p2pool = false
|
||||
auto_node = false
|
||||
auto_xmrig = false
|
||||
auto_xvb = false
|
||||
auto_xp = false
|
||||
|
@ -37,8 +38,10 @@ mod test {
|
|||
save_before_quit = true
|
||||
p2pool_path = "p2pool/p2pool"
|
||||
xmrig_path = "xmrig/xmrig"
|
||||
node_path = "node/monerod"
|
||||
xmrig_proxy_path = "xmrig-proxy/xmrig-proxy"
|
||||
absolute_p2pool_path = "/home/hinto/p2pool/p2pool"
|
||||
absolute_node_path = "/home/hinto/node/monerod"
|
||||
absolute_xmrig_path = "/home/hinto/xmrig/xmrig"
|
||||
absolute_xp_path = "/home/hinto/xmrig/xmrig-proxy/xmrig-proxy"
|
||||
selected_width = 1280
|
||||
|
@ -137,10 +140,26 @@ mod test {
|
|||
node = "Europe"
|
||||
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]
|
||||
gupax = "v1.3.0"
|
||||
p2pool = "v2.5"
|
||||
xmrig = "v6.18.0"
|
||||
node = "v18.3.4"
|
||||
"#;
|
||||
let state = State::from_str(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 log::*;
|
||||
use node::PubNodeApi;
|
||||
use portable_pty::Child;
|
||||
use readable::up::Uptime;
|
||||
use std::fmt::Write;
|
||||
|
@ -53,6 +54,7 @@ use std::{
|
|||
};
|
||||
|
||||
use self::xvb::{nodes::XvbNode, PubXvbApi};
|
||||
pub mod node;
|
||||
pub mod p2pool;
|
||||
pub mod tests;
|
||||
pub mod xrig;
|
||||
|
@ -76,6 +78,7 @@ pub struct Helper {
|
|||
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 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_proxy: Arc<Mutex<Process>>, // XMRig 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_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_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_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_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_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 gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>, //
|
||||
}
|
||||
|
@ -251,6 +256,7 @@ pub enum ProcessName {
|
|||
Xmrig,
|
||||
XmrigProxy,
|
||||
Xvb,
|
||||
Node,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ProcessState {
|
||||
|
@ -270,6 +276,7 @@ impl std::fmt::Display for ProcessName {
|
|||
ProcessName::Xmrig => write!(f, "XMRig"),
|
||||
ProcessName::XmrigProxy => write!(f, "XMRig-Proxy"),
|
||||
ProcessName::Xvb => write!(f, "XvB"),
|
||||
ProcessName::Node => write!(f, "Node"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,10 +292,12 @@ impl Helper {
|
|||
xmrig: Arc<Mutex<Process>>,
|
||||
xmrig_proxy: Arc<Mutex<Process>>,
|
||||
xvb: Arc<Mutex<Process>>,
|
||||
node: Arc<Mutex<Process>>,
|
||||
gui_api_p2pool: Arc<Mutex<PubP2poolApi>>,
|
||||
gui_api_xmrig: Arc<Mutex<PubXmrigApi>>,
|
||||
gui_api_xvb: Arc<Mutex<PubXvbApi>>,
|
||||
gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>,
|
||||
gui_api_node: Arc<Mutex<PubNodeApi>>,
|
||||
img_p2pool: Arc<Mutex<ImgP2pool>>,
|
||||
img_xmrig: Arc<Mutex<ImgXmrig>>,
|
||||
gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>,
|
||||
|
@ -301,15 +310,18 @@ impl Helper {
|
|||
pub_api_xmrig: arc_mut!(PubXmrigApi::new()),
|
||||
pub_api_xp: arc_mut!(PubXmrigProxyApi::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
|
||||
p2pool,
|
||||
xmrig,
|
||||
xmrig_proxy,
|
||||
xvb,
|
||||
node,
|
||||
gui_api_p2pool,
|
||||
gui_api_xmrig,
|
||||
gui_api_xvb,
|
||||
gui_api_xp,
|
||||
gui_api_node,
|
||||
img_p2pool,
|
||||
img_xmrig,
|
||||
gupax_p2pool_api,
|
||||
|
@ -419,15 +431,18 @@ impl Helper {
|
|||
|
||||
let helper = Arc::clone(helper);
|
||||
let lock = lock!(helper);
|
||||
let node = Arc::clone(&lock.node);
|
||||
let p2pool = Arc::clone(&lock.p2pool);
|
||||
let xmrig = Arc::clone(&lock.xmrig);
|
||||
let xmrig_proxy = Arc::clone(&lock.xmrig_proxy);
|
||||
let xvb = Arc::clone(&lock.xvb);
|
||||
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_xmrig = Arc::clone(&lock.gui_api_xmrig);
|
||||
let gui_api_xp = Arc::clone(&lock.gui_api_xp);
|
||||
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_xmrig = Arc::clone(&lock.pub_api_xmrig);
|
||||
let pub_api_xp = Arc::clone(&lock.pub_api_xp);
|
||||
|
@ -451,35 +466,48 @@ impl Helper {
|
|||
|
||||
// 2. Lock... EVERYTHING!
|
||||
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);
|
||||
debug!("Helper | Locking (2/12) ... [p2pool]");
|
||||
debug!("Helper | Locking (3/15) ... [p2pool]");
|
||||
let xmrig = lock!(xmrig);
|
||||
debug!("Helper | Locking (3/12) ... [xmrig]");
|
||||
debug!("Helper | Locking (4/15) ... [xmrig]");
|
||||
let xmrig_proxy = lock!(xmrig_proxy);
|
||||
debug!("Helper | Locking (3/12) ... [xmrig_proxy]");
|
||||
debug!("Helper | Locking (5/15) ... [xmrig_proxy]");
|
||||
let xvb = lock!(xvb);
|
||||
debug!("Helper | Locking (4/12) ... [xvb]");
|
||||
debug!("Helper | Locking (6/15) ... [xvb]");
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
debug!("Helper | Locking (12/12) ... [pub_api_xvb]");
|
||||
debug!("Helper | Locking (15/15) ... [pub_api_xvb]");
|
||||
// Calculate Gupax's uptime always.
|
||||
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() {
|
||||
debug!("Helper | P2Pool is alive! Running [combine_gui_pub_api()]");
|
||||
|
@ -539,6 +567,8 @@ impl Helper {
|
|||
debug!("Helper | Unlocking (3/12) ... [xmrig]");
|
||||
drop(p2pool);
|
||||
debug!("Helper | Unlocking (4/12) ... [p2pool]");
|
||||
drop(node);
|
||||
debug!("Helper | Unlocking (4/12) ... [node]");
|
||||
drop(pub_api_xvb);
|
||||
debug!("Helper | Unlocking (5/12) ... [pub_api_xvb]");
|
||||
drop(pub_api_xp);
|
||||
|
@ -547,6 +577,8 @@ impl Helper {
|
|||
debug!("Helper | Unlocking (6/12) ... [pub_api_xmrig]");
|
||||
drop(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);
|
||||
debug!("Helper | Unlocking (8/12) ... [gui_api_xvb]");
|
||||
drop(gui_api_xp);
|
||||
|
@ -555,6 +587,8 @@ impl Helper {
|
|||
debug!("Helper | Unlocking (10/12) ... [gui_api_xmrig]");
|
||||
drop(gui_api_p2pool);
|
||||
debug!("Helper | Unlocking (11/12) ... [gui_api_p2pool]");
|
||||
drop(gui_api_node);
|
||||
debug!("Helper | Unlocking (11/12) ... [node]");
|
||||
drop(lock);
|
||||
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::errors::process_running;
|
||||
use crate::helper::{Helper, ProcessSignal};
|
||||
use crate::utils::constants::{
|
||||
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()),
|
||||
FontId::new(scale * 1.2, egui::FontFamily::Monospace),
|
||||
FontId::new(scale * 1.05, egui::FontFamily::Monospace),
|
||||
),
|
||||
(
|
||||
Name("Bottom".into()),
|
||||
|
@ -180,6 +181,26 @@ pub fn init_auto(app: &mut App) {
|
|||
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]
|
||||
if app.state.gupax.auto_p2pool {
|
||||
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...");
|
||||
} else if !crate::components::update::check_p2pool_path(&app.state.gupax.p2pool_path) {
|
||||
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 {
|
||||
let backup_hosts = app.gather_backup_hosts();
|
||||
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...");
|
||||
} else if !crate::components::update::check_xmrig_path(&app.state.gupax.xmrig_path) {
|
||||
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) {
|
||||
Helper::start_xmrig(
|
||||
&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...");
|
||||
} 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...");
|
||||
} else if process_running(crate::helper::ProcessName::XmrigProxy) {
|
||||
warn!("Gupaxx | Xmrig-Proxy instance is already running outside of Gupaxx ! Skipping auto-node...");
|
||||
} else {
|
||||
Helper::start_xp(
|
||||
&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 XMRIG_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
|
||||
// e.g: Gupax_v1_0_0
|
||||
// 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 =
|
||||
"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_DEAD: &str = "XMRig is offline";
|
||||
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_BLOCK_REWARD: &str = "Block reward";
|
||||
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
|
||||
pub const STATUS_SUBMENU_PROCESSES: &str =
|
||||
"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_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_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_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!";
|
||||
|
@ -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_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_NODE: &str = "Set the default tab Gupaxx starts on to: Node";
|
||||
|
||||
pub const GUPAX_SIMPLE: &str = r#"Use simple Gupaxx settings:
|
||||
- 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_DELETE: &str = "Delete the currently selected entry";
|
||||
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
|
||||
pub const XMRIG_SIMPLE: &str = r#"Use simple XMRig settings:
|
||||
- Mine to local P2Pool (localhost:3333)
|
||||
|
|
|
@ -98,6 +98,7 @@ impl ErrorState {
|
|||
|
||||
pub fn process_running(process_name: ProcessName) -> bool {
|
||||
let name = match process_name {
|
||||
ProcessName::Node => "monerod",
|
||||
ProcessName::P2pool => "p2pool",
|
||||
ProcessName::Xmrig => "xmrig",
|
||||
ProcessName::XmrigProxy => "xmrig-proxy",
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//---------------------------------------------------------------------------------------------------- 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]
|
||||
|
@ -17,13 +19,15 @@ pub(crate) fn set_panic_hook(now: std::time::Instant) {
|
|||
"{panic_info:#?}
|
||||
|
||||
info:
|
||||
OS | {OS_NAME}
|
||||
args | {args:?}
|
||||
commit | {COMMIT}
|
||||
gupaxx | {GUPAX_VERSION}
|
||||
p2pool | {P2POOL_VERSION} (bundled)
|
||||
xmrig | {XMRIG_VERSION} (bundled)
|
||||
uptime | {uptime} seconds
|
||||
OS | {OS_NAME}
|
||||
args | {args:?}
|
||||
commit | {COMMIT}
|
||||
gupaxx | {GUPAX_VERSION}
|
||||
monerod | {NODE_VERSION} (bundled)
|
||||
p2pool | {P2POOL_VERSION} (bundled)
|
||||
xmrig | {XMRIG_VERSION} (bundled)
|
||||
xmrig-proxy | {XMRIG_VERSION} (bundled)
|
||||
uptime | {uptime} seconds
|
||||
|
||||
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 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
|
||||
|
||||
echo
|
||||
|
|
|
@ -34,12 +34,14 @@ title "Linux folder check"
|
|||
[[ -f linux_b/p2pool/p2pool ]]; check "linux_b/p2pool/p2pool"
|
||||
[[ -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/node/monerod ]]; check "linux_b/node/monerod"
|
||||
title "macOS-x64 folder check"
|
||||
[[ -d macos-x64/Gupaxx.app ]]; check "macos-x64/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/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/node/monerod ]]; check "macos-x64_b/node/monerod"
|
||||
title "macOS-arm64 folder check"
|
||||
[[ -d macos-arm64/Gupaxx.app ]]; check "macos-arm64/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"
|
||||
## 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/node/monerod ]]; check "macos-arm64_b/node/monerod"
|
||||
title "Windows folder check"
|
||||
[[ -f windows/Gupaxx.exe ]]; check "windows/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/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/node/monerod.exe ]]; check "windows_b/node/monerod.exe"
|
||||
|
||||
# Get random date for tar/zip
|
||||
title "RNG Date"
|
||||
|
@ -67,6 +71,7 @@ chmod +x linux_b/gupaxx
|
|||
chmod +x linux_b/p2pool/p2pool
|
||||
chmod +x linux_b/xmrig/xmrig
|
||||
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"
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue