feat: friendly custom args (#66)

This commit is contained in:
Cyrix126 2025-01-02 22:31:17 +01:00 committed by GitHub
parent 109c9a28b7
commit 5ed1414c39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 590 additions and 399 deletions

View file

@ -17,12 +17,11 @@
use std::sync::{Arc, Mutex};
use egui::{Label, TextEdit, TextStyle, TextWrapMode, Ui};
use egui::{Button, TextEdit, TextStyle, TextWrapMode, Ui};
use crate::{
DARK_GRAY,
helper::{Process, ProcessName},
miscs::height_txt_before_button,
regex::num_lines,
};
@ -86,20 +85,53 @@ pub fn input_args_field(
}
// Command arguments
pub fn start_options_field(ui: &mut Ui, arguments: &mut String, hint: &str, hover: &str) {
pub fn start_options_field(
ui: &mut Ui,
arguments: &mut String,
default_args_simple: &str,
default_args_advanced: &str,
hint: &str,
hover: &str,
) {
ui.group(|ui| {
ui.label("Start options:");
ui.style_mut().wrap_mode = Some(TextWrapMode::Wrap);
ui.style_mut().spacing.text_edit_width = ui.available_width();
ui.add(
TextEdit::multiline(arguments)
.hint_text(hint)
.desired_rows(1),
)
.on_hover_text(hover);
ui.horizontal(|ui| {
ui.add_sized(
[0.0, height_txt_before_button(ui, &TextStyle::Body)],
Label::new("Command arguments:"),
);
ui.style_mut().spacing.text_edit_width = ui.available_width();
ui.add(TextEdit::hint_text(TextEdit::singleline(arguments), hint))
.on_hover_text(hover);
arguments.truncate(1024);
})
if ui
.add_enabled(
default_args_simple != arguments,
Button::new(" Reset to Simple options "),
)
.on_hover_text("Reset the start options to arguments used for simple mode")
.clicked()
{
*arguments = default_args_simple.to_string();
}
if ui
.add_enabled(
default_args_advanced != arguments,
Button::new("Reset to Advanced options"),
)
.on_hover_text("Reset the start options to arguments used for advanced mode")
.clicked()
{
*arguments = default_args_advanced.to_string();
}
if ui
.add_enabled(!arguments.is_empty(), Button::new("Clear"))
.on_hover_text("Clear custom start options to use the advanced settings")
.clicked()
{
*arguments = String::new();
}
});
});
if !arguments.is_empty() {
ui.disable();
}
}

View file

@ -101,6 +101,7 @@ impl crate::app::App {
}
Tab::P2pool => {
debug!("App | Entering [P2Pool] Tab");
let backup_hosts = self.gather_backup_hosts();
crate::disk::state::P2pool::show(
&mut self.state.p2pool,
&mut self.node_vec,
@ -111,6 +112,8 @@ impl crate::app::App {
&mut self.p2pool_stdin,
ctx,
ui,
backup_hosts,
&self.state.gupax.absolute_p2pool_path,
);
}
Tab::Xmrig => {
@ -123,6 +126,7 @@ impl crate::app::App {
&mut self.xmrig_stdin,
ctx,
ui,
&self.state.gupax.absolute_xmrig_path,
);
}
Tab::XmrigProxy => {

View file

@ -20,7 +20,8 @@ use crate::app::panels::middle::common::header_tab::header_tab;
use crate::app::panels::middle::common::state_edit_field::{path_db_field, slider_state_field};
use crate::app::panels::middle::{rpc_bind_field, rpc_port_field, zmq_bind_field, zmq_port_field};
use crate::{
NODE_ARGUMENTS, NODE_DNS_BLOCKLIST, NODE_DNS_CHECKPOINT, NODE_INPUT, NODE_PRUNNING, NODE_URL,
NODE_DNS_BLOCKLIST, NODE_DNS_CHECKPOINT, NODE_INPUT, NODE_PRUNNING, NODE_URL,
START_OPTIONS_HOVER,
};
use egui::TextStyle;
use std::sync::{Arc, Mutex};
@ -28,7 +29,7 @@ use std::sync::{Arc, Mutex};
use log::debug;
use crate::components::gupax::FileWindow;
use crate::disk::state::Node;
use crate::disk::state::{Node, StartOptionsMode};
use crate::helper::node::PubNodeApi;
use crate::helper::{Process, ProcessName};
use crate::{P2POOL_IN, P2POOL_LOG, P2POOL_OUT, SPACE};
@ -72,13 +73,20 @@ impl Node {
if !self.simple {
//---------------------------------------------------------------------------------------------------- Arguments
debug!("Node Tab | Rendering [Arguments]");
let default_args_simple = self.start_options(StartOptionsMode::Simple);
let default_args_advanced = self.start_options(StartOptionsMode::Advanced);
start_options_field(
ui,
&mut self.arguments,
r#"--zmq-pub tcp://127.0.0.1:18081"#,
NODE_ARGUMENTS,
&default_args_simple,
&default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
);
//---------------------------------------------------------------------------------------------------- Prunned checkbox
if !self.arguments.is_empty() {
ui.disable();
}
ui.add_space(SPACE);
debug!("Node Tab | Rendering DNS and Prunning buttons");
ui.horizontal(|ui| {

View file

@ -1,5 +1,5 @@
use crate::app::panels::middle::common::console::{console, input_args_field, start_options_field};
use crate::disk::state::{P2pool, State};
use crate::disk::state::{P2pool, StartOptionsMode, State};
use crate::helper::p2pool::PubP2poolApi;
// Gupaxx - Fork of Gupax
//
@ -20,6 +20,7 @@ use crate::helper::p2pool::PubP2poolApi;
use crate::{components::node::*, constants::*, helper::*};
use log::*;
use std::path::Path;
use std::sync::{Arc, Mutex};
use super::common::header_tab::header_tab;
@ -41,6 +42,8 @@ impl P2pool {
buffer: &mut String,
_ctx: &egui::Context,
ui: &mut egui::Ui,
backup_nodes: Option<Vec<PoolNode>>,
path: &Path,
) {
//---------------------------------------------------------------------------------------------------- [Simple] Console
// debug!("P2Pool Tab | Rendering [Console]");
@ -69,11 +72,17 @@ impl P2pool {
}
});
if !self.simple {
let default_args_simple =
self.start_options(path, &backup_nodes, StartOptionsMode::Simple);
let default_args_advanced =
self.start_options(path, &backup_nodes, StartOptionsMode::Advanced);
start_options_field(
ui,
&mut self.arguments,
r#"--wallet <...> --host <...>"#,
P2POOL_ARGUMENTS,
&default_args_simple,
&default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
);
}
debug!("P2Pool Tab | Rendering [Address]");
@ -86,6 +95,9 @@ impl P2pool {
if self.simple {
self.simple(ui, ping, &mut api_lock);
} else {
if !self.arguments.is_empty() {
ui.disable();
}
self.advanced(ui, node_vec);
}
});

View file

@ -22,7 +22,7 @@ use crate::app::panels::middle::common::state_edit_field::{
monero_address_field, slider_state_field,
};
use crate::constants::*;
use crate::disk::state::Xmrig;
use crate::disk::state::{StartOptionsMode, Xmrig};
use crate::helper::xrig::xmrig::PubXmrigApi;
use crate::helper::{Process, ProcessName};
use crate::miscs::height_txt_before_button;
@ -30,6 +30,7 @@ use crate::regex::REGEXES;
use egui::{Checkbox, Ui, vec2};
use log::*;
use std::path::Path;
use std::sync::{Arc, Mutex};
use super::common::list_poolnode::PoolNode;
@ -46,6 +47,7 @@ impl Xmrig {
buffer: &mut String,
_ctx: &egui::Context,
ui: &mut egui::Ui,
path: &Path,
) {
header_tab(
ui,
@ -72,14 +74,16 @@ impl Xmrig {
});
if !self.simple {
debug!("XMRig Tab | Rendering [Arguments]");
ui.horizontal(|ui| {
start_options_field(
ui,
&mut self.arguments,
r#"--url <...> --user <...> --config <...>"#,
XMRIG_ARGUMENTS,
);
});
let default_args_simple = self.start_options(path, StartOptionsMode::Simple);
let default_args_advanced = self.start_options(path, StartOptionsMode::Advanced);
start_options_field(
ui,
&mut self.arguments,
&default_args_simple,
&default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
);
ui.add_enabled_ui(self.arguments.is_empty(), |ui| {
debug!("XMRig Tab | Rendering [Address]");
monero_address_field(&mut self.address, ui, XMRIG_ADDRESS);
@ -108,6 +112,9 @@ impl Xmrig {
);
});
if !self.simple {
if !self.arguments.is_empty() {
ui.disable();
}
egui::ScrollArea::horizontal()
.id_salt("xmrig_horizontal")
.show(ui, |ui| {

View file

@ -23,14 +23,14 @@ use log::debug;
use crate::app::panels::middle::common::console::{console, input_args_field, start_options_field};
use crate::app::panels::middle::common::header_tab::header_tab;
use crate::app::panels::middle::common::list_poolnode::list_poolnode;
use crate::disk::state::XmrigProxy;
use crate::disk::state::{StartOptionsMode, XmrigProxy};
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::{Process, ProcessName};
use crate::miscs::height_txt_before_button;
use crate::regex::REGEXES;
use crate::{
SPACE, XMRIG_API_IP, XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE, XMRIG_NAME, XMRIG_PORT,
XMRIG_PROXY_ARGUMENTS, XMRIG_PROXY_INPUT, XMRIG_PROXY_REDIRECT, XMRIG_PROXY_URL, XMRIG_RIG,
SPACE, START_OPTIONS_HOVER, XMRIG_API_IP, XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE,
XMRIG_NAME, XMRIG_PORT, XMRIG_PROXY_INPUT, XMRIG_PROXY_REDIRECT, XMRIG_PROXY_URL, XMRIG_RIG,
XMRIG_TLS,
};
@ -73,16 +73,21 @@ impl XmrigProxy {
}
});
if !self.simple {
if !self.arguments.is_empty() {
ui.disable();
}
//---------------------------------------------------------------------------------------------------- Arguments
debug!("XMRig-Proxy Tab | Rendering [Arguments]");
ui.horizontal(|ui| {
start_options_field(
ui,
&mut self.arguments,
r#"--url <...> --user <...> --config <...>"#,
XMRIG_PROXY_ARGUMENTS,
);
});
let default_args_simple = self.start_options(StartOptionsMode::Simple);
let default_args_advanced = self.start_options(StartOptionsMode::Advanced);
start_options_field(
ui,
&mut self.arguments,
&default_args_simple,
&default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
);
if !self.arguments.is_empty() {
ui.disable();
}

View file

@ -3,7 +3,12 @@ use rand::{Rng, distributions::Alphanumeric, thread_rng};
use strum::{EnumCount, EnumIter};
use super::*;
use crate::{components::node::RemoteNode, disk::status::*, helper::ProcessName};
use crate::{
app::panels::middle::common::list_poolnode::PoolNode,
components::node::RemoteNode,
disk::status::*,
helper::{Helper, ProcessName},
};
//---------------------------------------------------------------------------------------------------- [State] Impl
impl Default for State {
fn default() -> Self {
@ -705,3 +710,53 @@ impl Default for Version {
}
}
}
// Get the process for the state
impl Node {
pub const fn process_name() -> ProcessName {
ProcessName::Node
}
pub fn start_options(&self, mode: StartOptionsMode) -> String {
Helper::build_node_args(self, mode).join(" ")
}
}
impl P2pool {
pub const fn process_name() -> ProcessName {
ProcessName::P2pool
}
pub fn start_options(
&self,
path: &Path,
backup_nodes: &Option<Vec<PoolNode>>,
mode: StartOptionsMode,
) -> String {
Helper::build_p2pool_args(self, path, backup_nodes, false, mode).join(" ")
}
}
impl Xmrig {
pub const fn process_name() -> ProcessName {
ProcessName::Xmrig
}
pub fn start_options(&self, path: &Path, mode: StartOptionsMode) -> String {
Helper::build_xmrig_args(self, path, mode).join(" ")
}
}
impl XmrigProxy {
pub const fn process_name() -> ProcessName {
ProcessName::XmrigProxy
}
pub fn start_options(&self, mode: StartOptionsMode) -> String {
Helper::build_xp_args(self, mode).join(" ")
}
}
// impl Xvb {
// pub const fn process_name() -> ProcessName {
// ProcessName::Xvb
// }
// }
pub enum StartOptionsMode {
Simple,
Advanced,
Custom,
}

View file

@ -338,6 +338,14 @@ impl ProcessName {
ProcessName::Xvb => None,
}
}
pub const fn start_options_hint(&self) -> &str {
match self {
ProcessName::Node => NODE_START_OPTIONS_HINT,
ProcessName::P2pool => P2POOL_START_OPTIONS_HINT,
ProcessName::Xmrig | ProcessName::XmrigProxy => XMRIG_START_OPTIONS_HINT,
ProcessName::Xvb => "",
}
}
}
impl std::fmt::Display for ProcessState {

View file

@ -31,7 +31,7 @@ use std::{
use tokio::spawn;
use crate::{
disk::state::Node,
disk::state::{Node, StartOptionsMode},
helper::{
ProcessName, ProcessSignal, ProcessState, check_died, check_user_input, signal_end,
sleep_end_loop,
@ -72,65 +72,70 @@ impl Helper {
}
}
}
pub fn build_node_args(state: &crate::disk::state::Node) -> Vec<String> {
pub fn build_node_args(
state: &crate::disk::state::Node,
mode: StartOptionsMode,
) -> Vec<String> {
let mut args = Vec::with_capacity(500);
// [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 if !state.arguments.is_empty() {
// This parses the input
// todo: set the state if user change port and token
for arg in state.arguments.split_whitespace() {
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
}
} 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("--log-level".to_string());
args.push(state.log_level.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 {
match mode {
StartOptionsMode::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());
}
if state.pruned {
args.push("--enable-dns-blocklist".to_string());
args.push("--sync-pruned-blocks".to_string());
args.push("--prune-blockchain".to_string());
}
StartOptionsMode::Advanced => {
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("--log-level".to_string());
args.push(state.log_level.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());
}
}
StartOptionsMode::Custom => {
// This parses the input
// todo: set the state if user change port and token
for arg in state.arguments.split_whitespace() {
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
}
}
}
args
}
@ -175,8 +180,14 @@ impl Helper {
// 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) {
helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_node_args(state);
let mode = if state.simple {
StartOptionsMode::Simple
} else if !state.arguments.is_empty() {
StartOptionsMode::Custom
} else {
StartOptionsMode::Advanced
};
let args = Self::build_node_args(state, mode);
// Print arguments & user settings to console
crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args));

View file

@ -20,6 +20,7 @@ use super::Process;
use crate::app::panels::middle::common::list_poolnode::PoolNode;
use crate::components::node::RemoteNode;
use crate::disk::state::P2pool;
use crate::disk::state::StartOptionsMode;
use crate::helper::ProcessName;
use crate::helper::ProcessSignal;
use crate::helper::ProcessState;
@ -228,14 +229,17 @@ impl Helper {
override_to_local_node: bool,
) {
helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let (args, api_path_local, api_path_network, api_path_pool, api_path_p2p) =
Self::build_p2pool_args_and_mutate_img(
helper,
state,
path,
&backup_hosts,
override_to_local_node,
);
let (api_path_local, api_path_network, api_path_pool, api_path_p2p) =
Self::mutate_img_p2pool(state, helper, path);
let mode = if state.simple {
StartOptionsMode::Simple
} else if !state.arguments.is_empty() {
StartOptionsMode::Custom
} else {
StartOptionsMode::Advanced
};
let args =
Self::build_p2pool_args(state, path, &backup_hosts, override_to_local_node, mode);
// Print arguments & user settings to console
crate::disk::print_dash(&format!(
@ -288,57 +292,16 @@ impl Helper {
let tail = &address[87..95];
head.to_owned() + "..." + tail
}
#[cold]
#[inline(never)]
// Takes in some [State/P2pool] and parses it to build the actual command arguments.
// Returns the [Vec] of actual arguments, and mutates the [ImgP2pool] for the main GUI thread
// It returns a value... and mutates a deeply nested passed argument... this is some pretty bad code...
pub fn build_p2pool_args_and_mutate_img(
helper: &Arc<Mutex<Self>>,
pub fn mutate_img_p2pool(
state: &P2pool,
helper: &Arc<Mutex<Self>>,
path: &Path,
backup_hosts: &Option<Vec<PoolNode>>,
override_to_local_node: bool,
) -> (Vec<String>, PathBuf, PathBuf, PathBuf, PathBuf) {
let mut args = Vec::with_capacity(500);
) -> (PathBuf, PathBuf, PathBuf, PathBuf) {
let path = path.to_path_buf();
let mut api_path = path;
api_path.pop();
// [Simple]
if state.simple && (!state.local_node && !override_to_local_node) {
// Build the p2pool argument
if state.simple {
let (ip, rpc, zmq) = RemoteNode::get_ip_rpc_zmq(&state.node); // Get: (IP, RPC, ZMQ)
args.push("--wallet".to_string());
args.push(state.address.clone()); // Wallet address
args.push("--host".to_string());
args.push(ip.to_string()); // IP Address
args.push("--rpc-port".to_string());
args.push(rpc.to_string()); // RPC Port
args.push("--zmq-port".to_string());
args.push(zmq.to_string()); // ZMQ Port
args.push("--data-api".to_string());
args.push(api_path.display().to_string()); // API Path
args.push("--local-api".to_string()); // Enable API
args.push("--no-color".to_string()); // Remove color escape sequences, Gupax terminal can't parse it :(
args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
// Push other nodes if `backup_host`.
if let Some(nodes) = backup_hosts {
for node in nodes {
if (node.ip(), node.port(), node.custom()) != (ip, rpc, zmq) {
args.push("--host".to_string());
args.push(node.ip().to_string());
args.push("--rpc-port".to_string());
args.push(node.port().to_string());
args.push("--zmq-port".to_string());
args.push(node.custom().to_string());
}
}
}
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address),
@ -348,68 +311,136 @@ impl Helper {
out_peers: "10".to_string(),
in_peers: "10".to_string(),
};
} else if state.simple && (state.local_node || override_to_local_node) {
// use the local node
// Build the p2pool argument
args.push("--wallet".to_string());
args.push(state.address.clone()); // Wallet address
args.push("--host".to_string());
args.push("127.0.0.1".to_string()); // IP Address
args.push("--rpc-port".to_string());
args.push("18081".to_string()); // RPC Port
args.push("--zmq-port".to_string());
args.push("18083".to_string()); // ZMQ Port
args.push("--data-api".to_string());
args.push(api_path.display().to_string()); // API Path
args.push("--local-api".to_string()); // Enable API
args.push("--no-color".to_string()); // Remove color escape sequences, Gupax terminal can't parse it :(
args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
} else if !state.arguments.is_empty() {
// This parses the input and attempts to fill out
// the [ImgP2pool]... This is pretty bad code...
let mut last = "";
let lock = helper.lock().unwrap();
let mut p2pool_image = lock.img_p2pool.lock().unwrap();
let mut mini = false;
for arg in state.arguments.split_whitespace() {
match last {
"--mini" => {
mini = true;
p2pool_image.mini = "P2Pool Mini".to_string();
}
"--wallet" => p2pool_image.address = Self::head_tail_of_monero_address(arg),
"--host" => p2pool_image.host = arg.to_string(),
"--rpc-port" => p2pool_image.rpc = arg.to_string(),
"--zmq-port" => p2pool_image.zmq = arg.to_string(),
"--out-peers" => p2pool_image.out_peers = arg.to_string(),
"--in-peers" => p2pool_image.in_peers = arg.to_string(),
"--data-api" => api_path = PathBuf::from(arg),
_ => (),
}
if !mini {
p2pool_image.mini = "P2Pool Main".to_string();
}
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
last = arg;
}
} else {
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(),
mini: if state.mini {
"P2Pool Mini".to_string()
} else {
"P2Pool Main".to_string()
},
address: Self::head_tail_of_monero_address(&state.address),
host: "Local node".to_string(),
rpc: "18081".to_string(),
zmq: "18083".to_string(),
out_peers: "10".to_string(),
in_peers: "10".to_string(),
host: state.selected_node.ip.to_string(),
rpc: state.selected_node.rpc.to_string(),
zmq: state.selected_node.zmq_rig.to_string(),
out_peers: state.out_peers.to_string(),
in_peers: state.in_peers.to_string(),
};
}
// [Advanced]
else {
// Overriding command arguments
if !state.arguments.is_empty() {
// This parses the input and attempts to fill out
// the [ImgP2pool]... This is pretty bad code...
let mut last = "";
let lock = helper.lock().unwrap();
let mut p2pool_image = lock.img_p2pool.lock().unwrap();
let mut mini = false;
for arg in state.arguments.split_whitespace() {
match last {
"--mini" => {
mini = true;
p2pool_image.mini = "P2Pool Mini".to_string();
let mut api_path_local = api_path.clone();
let mut api_path_network = api_path.clone();
let mut api_path_pool = api_path.clone();
let mut api_path_p2p = api_path.clone();
api_path_local.push(P2POOL_API_PATH_LOCAL);
api_path_network.push(P2POOL_API_PATH_NETWORK);
api_path_pool.push(P2POOL_API_PATH_POOL);
api_path_p2p.push(P2POOL_API_PATH_P2P);
(
api_path_local,
api_path_network,
api_path_pool,
api_path_p2p,
)
}
#[cold]
#[inline(never)]
// Takes in some [State/P2pool] and parses it to build the actual command arguments.
// Returns the [Vec] of actual arguments, and mutates the [ImgP2pool] for the main GUI thread
// It returns a value... and mutates a deeply nested passed argument... this is some pretty bad code...
pub fn build_p2pool_args(
state: &P2pool,
path: &Path,
backup_hosts: &Option<Vec<PoolNode>>,
override_to_local_node: bool,
// Allows to provide a different mode without mutating the state
mode: StartOptionsMode,
) -> Vec<String> {
let mut args = Vec::with_capacity(500);
let path = path.to_path_buf();
let mut api_path = path;
api_path.pop();
// [Simple]
match mode {
StartOptionsMode::Simple if !state.local_node && !override_to_local_node => {
// Build the p2pool argument
let (ip, rpc, zmq) = RemoteNode::get_ip_rpc_zmq(&state.node); // Get: (IP, RPC, ZMQ)
args.push("--wallet".to_string());
args.push(state.address.clone()); // Wallet address
args.push("--host".to_string());
args.push(ip.to_string()); // IP Address
args.push("--rpc-port".to_string());
args.push(rpc.to_string()); // RPC Port
args.push("--zmq-port".to_string());
args.push(zmq.to_string()); // ZMQ Port
args.push("--data-api".to_string());
args.push(api_path.display().to_string()); // API Path
args.push("--local-api".to_string()); // Enable API
args.push("--no-color".to_string()); // Remove color escape sequences, Gupax terminal can't parse it :(
args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
// Push other nodes if `backup_host`.
if let Some(nodes) = backup_hosts {
for node in nodes {
if (node.ip(), node.port(), node.custom()) != (ip, rpc, zmq) {
args.push("--host".to_string());
args.push(node.ip().to_string());
args.push("--rpc-port".to_string());
args.push(node.port().to_string());
args.push("--zmq-port".to_string());
args.push(node.custom().to_string());
}
"--wallet" => p2pool_image.address = Self::head_tail_of_monero_address(arg),
"--host" => p2pool_image.host = arg.to_string(),
"--rpc-port" => p2pool_image.rpc = arg.to_string(),
"--zmq-port" => p2pool_image.zmq = arg.to_string(),
"--out-peers" => p2pool_image.out_peers = arg.to_string(),
"--in-peers" => p2pool_image.in_peers = arg.to_string(),
"--data-api" => api_path = PathBuf::from(arg),
_ => (),
}
if !mini {
p2pool_image.mini = "P2Pool Main".to_string();
}
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
last = arg;
}
// Else, build the argument
} else {
}
StartOptionsMode::Simple if state.local_node || override_to_local_node => {
// use the local node
// Build the p2pool argument
args.push("--wallet".to_string());
args.push(state.address.clone()); // Wallet address
args.push("--host".to_string());
args.push("127.0.0.1".to_string()); // IP Address
args.push("--rpc-port".to_string());
args.push("18081".to_string()); // RPC Port
args.push("--zmq-port".to_string());
args.push("18083".to_string()); // ZMQ Port
args.push("--data-api".to_string());
args.push(api_path.display().to_string()); // API Path
args.push("--local-api".to_string()); // Enable API
args.push("--no-color".to_string()); // Remove color escape sequences, Gupax terminal can't parse it :(
args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
}
StartOptionsMode::Advanced => {
// build the argument
let ip = if state.ip == "localhost" {
"127.0.0.1"
} else {
@ -456,37 +487,14 @@ impl Helper {
}
}
}
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: if state.mini {
"P2Pool Mini".to_string()
} else {
"P2Pool Main".to_string()
},
address: Self::head_tail_of_monero_address(&state.address),
host: state.selected_node.ip.to_string(),
rpc: state.selected_node.rpc.to_string(),
zmq: state.selected_node.zmq_rig.to_string(),
out_peers: state.out_peers.to_string(),
in_peers: state.in_peers.to_string(),
};
}
StartOptionsMode::Custom => {
// Overriding command arguments
args.push(state.arguments.split_whitespace().collect());
}
_ => (),
}
let mut api_path_local = api_path.clone();
let mut api_path_network = api_path.clone();
let mut api_path_pool = api_path.clone();
let mut api_path_p2p = api_path.clone();
api_path_local.push(P2POOL_API_PATH_LOCAL);
api_path_network.push(P2POOL_API_PATH_NETWORK);
api_path_pool.push(P2POOL_API_PATH_POOL);
api_path_p2p.push(P2POOL_API_PATH_P2P);
(
args,
api_path_local,
api_path_network,
api_path_pool,
api_path_p2p,
)
args
}
#[cold]

View file

@ -1,4 +1,5 @@
use crate::constants::*;
use crate::disk::state::StartOptionsMode;
use crate::helper::xrig::update_xmrig_config;
use crate::helper::{Helper, ProcessName, ProcessSignal, ProcessState};
use crate::helper::{Process, arc_mut, check_died, check_user_input, sleep, sleep_end_loop};
@ -180,8 +181,15 @@ impl Helper {
sudo: Arc<Mutex<SudoState>>,
) {
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let (args, api_ip_port) = Self::build_xmrig_args_and_mutate_img(helper, state, path);
let api_ip_port = Self::mutate_img_xmrig(helper, state);
let mode = if state.simple {
StartOptionsMode::Simple
} else if !state.arguments.is_empty() {
StartOptionsMode::Custom
} else {
StartOptionsMode::Advanced
};
let args = Self::build_xmrig_args(state, path, mode);
// Print arguments & user settings to console
crate::disk::print_dash(&format!("XMRig | Launch arguments: {:#?}", args));
info!("XMRig | Using path: [{}]", path.display());
@ -213,20 +221,76 @@ impl Helper {
);
});
}
pub fn mutate_img_xmrig(
helper: &Arc<Mutex<Self>>,
state: &crate::disk::state::Xmrig,
) -> String {
let mut api_ip = String::with_capacity(15);
let mut api_port = String::with_capacity(5);
if state.simple {
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
threads: state.current_threads.to_string(),
url: "127.0.0.1:3333 (Local P2Pool)".to_string(),
};
} else if !state.arguments.is_empty() {
// This parses the input and attempts to fill out
// the [ImgXmrig]... This is pretty bad code...
let mut last = "";
let lock = helper.lock().unwrap();
let mut xmrig_image = lock.img_xmrig.lock().unwrap();
for arg in state.arguments.split_whitespace() {
match last {
"--threads" => xmrig_image.threads = arg.to_string(),
"--url" => xmrig_image.url = arg.to_string(),
"--http-host" => {
api_ip = if arg == "localhost" {
"127.0.0.1".to_string()
} else {
arg.to_string()
}
}
"--http-port" => api_port = arg.to_string(),
_ => (),
}
last = arg;
}
} else {
let ip = if state.ip == "localhost" || state.ip.is_empty() {
"127.0.0.1"
} else {
&state.ip
};
api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
"127.0.0.1".to_string()
} else {
state.api_ip.to_string()
};
api_port = if state.api_port.is_empty() {
"18088".to_string()
} else {
state.api_port.to_string()
};
let url = format!("{}:{}", ip, state.port); // Combine IP:Port into one string
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
url: url.clone(),
threads: state.current_threads.to_string(),
};
}
format!("{}:{}", api_ip, api_port)
}
#[cold]
#[inline(never)]
// Takes in some [State/Xmrig] and parses it to build the actual command arguments.
// Returns the [Vec] of actual arguments, and mutates the [ImgXmrig] for the main GUI thread
// It returns a value... and mutates a deeply nested passed argument... this is some pretty bad code...
pub fn build_xmrig_args_and_mutate_img(
helper: &Arc<Mutex<Self>>,
pub fn build_xmrig_args(
state: &crate::disk::state::Xmrig,
path: &std::path::Path,
) -> (Vec<String>, String) {
// Allows to provide a different mode without mutating the state
mode: StartOptionsMode,
) -> Vec<String> {
let mut args = Vec::with_capacity(500);
let mut api_ip = String::with_capacity(15);
let mut api_port = String::with_capacity(5);
let path = path.to_path_buf();
// The actual binary we're executing is [sudo], technically
// the XMRig path is just an argument to sudo, so add it.
@ -237,81 +301,43 @@ impl Helper {
args.push("--".to_string());
args.push(path.display().to_string());
}
// [Simple]
if state.simple {
// Build the xmrig argument
let rig = if state.simple_rig.is_empty() {
GUPAX_VERSION_UNDERSCORE.to_string()
} else {
state.simple_rig.clone()
}; // Rig name
args.push("--url".to_string());
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("--threads".to_string());
args.push(state.current_threads.to_string()); // Threads
args.push("--user".to_string());
args.push(rig); // Rig name
args.push("--no-color".to_string()); // No color
args.push("--http-host".to_string());
args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push("18088".to_string()); // HTTP API Port
if state.pause != 0 {
args.push("--pause-on-active".to_string());
args.push(state.pause.to_string());
} // Pause on active
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
threads: state.current_threads.to_string(),
url: "127.0.0.1:3333 (Local P2Pool)".to_string(),
};
api_ip = "127.0.0.1".to_string();
api_port = "18088".to_string();
// [Advanced]
} else {
// Overriding command arguments
if !state.arguments.is_empty() {
// This parses the input and attempts to fill out
// the [ImgXmrig]... This is pretty bad code...
let mut last = "";
let lock = helper.lock().unwrap();
let mut xmrig_image = lock.img_xmrig.lock().unwrap();
for arg in state.arguments.split_whitespace() {
match last {
"--threads" => xmrig_image.threads = arg.to_string(),
"--url" => xmrig_image.url = arg.to_string(),
"--http-host" => {
api_ip = if arg == "localhost" {
"127.0.0.1".to_string()
} else {
arg.to_string()
}
}
"--http-port" => api_port = arg.to_string(),
_ => (),
}
args.push(if arg == "localhost" {
"127.0.0.1".to_string()
} else {
arg.to_string()
});
last = arg;
}
// Else, build the argument
} else {
match mode {
StartOptionsMode::Simple => {
// Build the xmrig argument
let rig = if state.simple_rig.is_empty() {
GUPAX_VERSION_UNDERSCORE.to_string()
} else {
state.simple_rig.clone()
}; // Rig name
args.push("--url".to_string());
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("--threads".to_string());
args.push(state.current_threads.to_string()); // Threads
args.push("--user".to_string());
args.push(rig); // Rig name
args.push("--no-color".to_string()); // No color
args.push("--http-host".to_string());
args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push("18088".to_string()); // HTTP API Port
if state.pause != 0 {
args.push("--pause-on-active".to_string());
args.push(state.pause.to_string());
} // Pause on active
}
StartOptionsMode::Advanced => {
// XMRig doesn't understand [localhost]
let ip = if state.ip == "localhost" || state.ip.is_empty() {
"127.0.0.1"
} else {
&state.ip
};
api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
let api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
"127.0.0.1".to_string()
} else {
state.api_ip.to_string()
};
api_port = if state.api_port.is_empty() {
let api_port = if state.api_port.is_empty() {
"18088".to_string()
} else {
state.api_port.to_string()
@ -340,15 +366,21 @@ impl Helper {
args.push("--pause-on-active".to_string());
args.push(state.pause.to_string());
} // Pause on active
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
url: url.clone(),
threads: state.current_threads.to_string(),
};
}
StartOptionsMode::Custom => {
// This parses the input and attempts to fill out
// the [ImgXmrig]... This is pretty bad code...
// custom args from user input
// This parses the input
for arg in state.arguments.split_whitespace() {
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
}
}
}
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string());
(args, format!("{}:{}", api_ip, api_port))
args
}
// We actually spawn [sudo] on Unix, with XMRig being the argument.

View file

@ -29,6 +29,7 @@ use std::{
};
use tokio::spawn;
use crate::disk::state::StartOptionsMode;
use crate::human::{HumanNumber, HumanTime};
use crate::miscs::client;
use crate::{
@ -125,90 +126,91 @@ impl Helper {
}
}
}
pub fn build_xp_args(state: &crate::disk::state::XmrigProxy) -> Vec<String> {
pub fn build_xp_args(
state: &crate::disk::state::XmrigProxy,
mode: StartOptionsMode,
) -> Vec<String> {
let mut args = Vec::with_capacity(500);
let api_ip;
let api_port;
let ip;
let port;
// [Simple]
if state.simple {
// Build the xmrig argument
let rig = if state.simple_rig.is_empty() {
GUPAX_VERSION_UNDERSCORE.to_string()
} else {
state.simple_rig.clone()
}; // Rig name
args.push("-o".to_string());
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("-b".to_string());
args.push("0.0.0.0:3355".to_string());
args.push("--user".to_string());
args.push(rig); // Rig name
args.push("--no-color".to_string()); // No color
args.push("--http-host".to_string());
args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push("18089".to_string()); // HTTP API Port
// [Advanced]
} else if !state.arguments.is_empty() {
// custom args from user input
// This parses the input
// todo: set the state if user change port and token
for arg in state.arguments.split_whitespace() {
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
match mode {
StartOptionsMode::Simple => {
// Build the xmrig argument
let rig = if state.simple_rig.is_empty() {
GUPAX_VERSION_UNDERSCORE.to_string()
} else {
state.simple_rig.clone()
}; // Rig name
args.push("-o".to_string());
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("-b".to_string());
args.push("0.0.0.0:3355".to_string());
args.push("--user".to_string());
args.push(rig); // Rig name
args.push("--no-color".to_string()); // No color
args.push("--http-host".to_string());
args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push("18089".to_string()); // HTTP API Port
}
} else {
// XMRig doesn't understand [localhost]
let p2pool_ip = if state.p2pool_ip == "localhost" || state.p2pool_ip.is_empty() {
"127.0.0.1"
} else {
&state.p2pool_ip
};
api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
"127.0.0.1".to_string()
} else {
state.api_ip.to_string()
};
api_port = if state.api_port.is_empty() {
"18089".to_string()
} else {
state.api_port.to_string()
};
ip = if state.api_ip == "localhost" || state.ip.is_empty() {
"0.0.0.0".to_string()
} else {
state.ip.to_string()
};
StartOptionsMode::Advanced => {
// XMRig doesn't understand [localhost]
let p2pool_ip = if state.p2pool_ip == "localhost" || state.p2pool_ip.is_empty() {
"127.0.0.1"
} else {
&state.p2pool_ip
};
api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
"127.0.0.1".to_string()
} else {
state.api_ip.to_string()
};
api_port = if state.api_port.is_empty() {
"18089".to_string()
} else {
state.api_port.to_string()
};
ip = if state.api_ip == "localhost" || state.ip.is_empty() {
"0.0.0.0".to_string()
} else {
state.ip.to_string()
};
port = if state.port.is_empty() {
"3355".to_string()
} else {
state.port.to_string()
};
let p2pool_url = format!("{}:{}", p2pool_ip, state.p2pool_port); // Combine IP:Port into one string
let bind_url = format!("{}:{}", ip, port); // Combine IP:Port into one string
args.push("--user".to_string());
args.push(state.address.clone()); // Wallet
args.push("--rig-id".to_string());
args.push(state.rig.to_string()); // Rig ID
args.push("-o".to_string());
args.push(p2pool_url.clone()); // IP/Port
args.push("-b".to_string());
args.push(bind_url.clone()); // IP/Port
args.push("--http-host".to_string());
args.push(api_ip.to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push(api_port.to_string()); // HTTP API Port
args.push("--no-color".to_string()); // No color escape codes
if state.tls {
args.push("--tls".to_string());
} // TLS
if state.keepalive {
args.push("--keepalive".to_string());
} // Keepalive
port = if state.port.is_empty() {
"3355".to_string()
} else {
state.port.to_string()
};
let p2pool_url = format!("{}:{}", p2pool_ip, state.p2pool_port); // Combine IP:Port into one string
let bind_url = format!("{}:{}", ip, port); // Combine IP:Port into one string
args.push("--user".to_string());
args.push(state.address.clone()); // Wallet
args.push("--rig-id".to_string());
args.push(state.rig.to_string()); // Rig ID
args.push("-o".to_string());
args.push(p2pool_url.clone()); // IP/Port
args.push("-b".to_string());
args.push(bind_url.clone()); // IP/Port
args.push("--http-host".to_string());
args.push(api_ip.to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push(api_port.to_string()); // HTTP API Port
args.push("--no-color".to_string()); // No color escape codes
if state.tls {
args.push("--tls".to_string());
} // TLS
if state.keepalive {
args.push("--keepalive".to_string());
} // Keepalive
}
StartOptionsMode::Custom => {
for arg in state.arguments.split_whitespace() {
let arg = if arg == "localhost" { "127.0.0.1" } else { arg };
args.push(arg.to_string());
}
}
}
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string());
@ -267,7 +269,14 @@ impl Helper {
) {
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_xp_args(state_proxy);
let mode = if state_proxy.simple {
StartOptionsMode::Simple
} else if !state_proxy.arguments.is_empty() {
StartOptionsMode::Custom
} else {
StartOptionsMode::Advanced
};
let args = Self::build_xp_args(state_proxy, mode);
// Print arguments & user settings to console
crate::disk::print_dash(&format!("XMRig-Proxy | Launch arguments: {:#?}", args));
info!("XMRig-Proxy | Using path: [{}]", path.display());

View file

@ -127,9 +127,6 @@ pub const XMRIG_PROXY_FAILED: &str = "XMRig-Proxy is offline and failed when exi
pub const XMRIG_PROXY_MIDDLE: &str = "XMRig-Proxy is in the middle of (re)starting/stopping";
pub const XMRIG_PROXY_NOT_MINING: &str = "XMRig-Proxy is online, but not mining to any pool";
pub const XMRIG_PROXY_REDIRECT: &str = "point local xmrig instance on this proxy instead of the p2pool instance (recommended if using XvB)";
pub const XMRIG_PROXY_ARGUMENTS: &str = r#"WARNING: Use [--no-color] and make sure to set [--http-host <IP>] & [--http-port <PORT>] so that the [Status] tab can work!
Start XMRig-Proxy with these arguments"#;
pub const XMRIG_PROXY_INPUT: &str = "Send a command to XMRig-Proxy";
pub const XMRIG_PROXY_SIMPLE: &str = r#"Use simple XMRig-Proxy settings:
- Mine to local P2Pool (localhost:3333)
@ -164,6 +161,14 @@ If unchecked (default):\n
The algorithm will watch the HR estimated by the stratum data of the p2pool node, which is more accurate but will only take into account the miners that are using your P2Pool node.
";
pub const XVB_P2POOL_BUFFER: &str = "Set the % amount of additional HR to send to p2pool. Will reduce (if positive) or augment (if negative) the chances to miss the p2pool window";
pub const START_OPTIONS_HOVER: &str = "Start the process with theses options.\nThe \"Reset to simple/advanced options\" are arguments constructed from the settings.\nYou can replace them with your own";
pub const NODE_START_OPTIONS_HINT: &str = "--zmq-pub tcp://<ip>:port --out-peers 32 --in-peers 64 --add-priority-node <ip>:<port> --disable-dns-checkpoints --enable-dns-blocklist --sync-pruned-blocks --prune-blockchain";
pub const P2POOL_START_OPTIONS_HINT: &str = "--wallet <primary address> --host <IP> --rpc-port <PORT> --zmq-port <PORT> --data-api <PATH> --local-api --no-color --mini --light-mode";
// also valid for xmrig-proxy
pub const XMRIG_START_OPTIONS_HINT: &str =
"-o <IP:PORT> -t <THREADS> --user <RIG> --no-color --http-host <BIND> --http-port <PORT>";
// This is the typical space added when using
// [ui.separator()] or [ui.group()]
// Used for subtracting the width/height so
@ -410,9 +415,7 @@ Running and using your own local Monero node improves privacy and ensures your c
For a simple guide, see the [Running a Local Monero Node] section on Gupaxx s GitHub by clicking this message."#;
pub const P2POOL_INPUT: &str = "Send a command to P2Pool";
pub const P2POOL_ARGUMENTS: &str = r#"WARNING: Use [--no-color] and make sure to set [--data-api <PATH>] & [--local-api] so that the [Status] tab can work!
Start P2Pool with these arguments and override all below settings"#;
pub const P2POOL_SIMPLE: &str = r#"Use simple P2Pool settings:
- Remote remote Monero node
- Default P2Pool settings + Mini
@ -441,7 +444,6 @@ pub const LIST_SAVE: &str = "Save the current values to the already existing ent
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.";
#[cfg(not(windows))]
@ -492,9 +494,7 @@ pub const XMRIG_ADVANCED: &str = r#"Use advanced XMRig settings:
- TLS setting
- Keepalive setting"#;
pub const XMRIG_INPUT: &str = "Send a command to XMRig";
pub const XMRIG_ARGUMENTS: &str = r#"WARNING: Use [--no-color] and make sure to set [--http-host <IP>] & [--http-port <PORT>] so that the [Status] tab can work!
Start XMRig with these arguments and override all below settings"#;
pub const XMRIG_ADDRESS: &str = "Specify which Monero address to payout to. This does nothing if mining to P2Pool since the address being paid out to will be the one P2Pool started with. This doubles as a rig identifier for P2Pool and some pools.";
pub const XMRIG_NAME: &str = "Add a unique name to identify this pool; Only [A-Za-z0-9-_.] and spaces allowed; Max length = 30 characters";
pub const XMRIG_IP: &str = "Specify the pool IP to connect to with XMRig; It must be a valid IPv4 address or a valid domain name; Max length = 255 characters";