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 std::sync::{Arc, Mutex};
use egui::{Label, TextEdit, TextStyle, TextWrapMode, Ui}; use egui::{Button, TextEdit, TextStyle, TextWrapMode, Ui};
use crate::{ use crate::{
DARK_GRAY, DARK_GRAY,
helper::{Process, ProcessName}, helper::{Process, ProcessName},
miscs::height_txt_before_button,
regex::num_lines, regex::num_lines,
}; };
@ -86,20 +85,53 @@ pub fn input_args_field(
} }
// Command arguments // 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.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.horizontal(|ui| {
ui.add_sized( if ui
[0.0, height_txt_before_button(ui, &TextStyle::Body)], .add_enabled(
Label::new("Command arguments:"), default_args_simple != arguments,
); Button::new(" Reset to Simple options "),
ui.style_mut().spacing.text_edit_width = ui.available_width(); )
ui.add(TextEdit::hint_text(TextEdit::singleline(arguments), hint)) .on_hover_text("Reset the start options to arguments used for simple mode")
.on_hover_text(hover); .clicked()
arguments.truncate(1024); {
}) *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 => { Tab::P2pool => {
debug!("App | Entering [P2Pool] Tab"); debug!("App | Entering [P2Pool] Tab");
let backup_hosts = self.gather_backup_hosts();
crate::disk::state::P2pool::show( crate::disk::state::P2pool::show(
&mut self.state.p2pool, &mut self.state.p2pool,
&mut self.node_vec, &mut self.node_vec,
@ -111,6 +112,8 @@ impl crate::app::App {
&mut self.p2pool_stdin, &mut self.p2pool_stdin,
ctx, ctx,
ui, ui,
backup_hosts,
&self.state.gupax.absolute_p2pool_path,
); );
} }
Tab::Xmrig => { Tab::Xmrig => {
@ -123,6 +126,7 @@ impl crate::app::App {
&mut self.xmrig_stdin, &mut self.xmrig_stdin,
ctx, ctx,
ui, ui,
&self.state.gupax.absolute_xmrig_path,
); );
} }
Tab::XmrigProxy => { 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::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::app::panels::middle::{rpc_bind_field, rpc_port_field, zmq_bind_field, zmq_port_field};
use crate::{ 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 egui::TextStyle;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -28,7 +29,7 @@ use std::sync::{Arc, Mutex};
use log::debug; use log::debug;
use crate::components::gupax::FileWindow; use crate::components::gupax::FileWindow;
use crate::disk::state::Node; use crate::disk::state::{Node, StartOptionsMode};
use crate::helper::node::PubNodeApi; use crate::helper::node::PubNodeApi;
use crate::helper::{Process, ProcessName}; use crate::helper::{Process, ProcessName};
use crate::{P2POOL_IN, P2POOL_LOG, P2POOL_OUT, SPACE}; use crate::{P2POOL_IN, P2POOL_LOG, P2POOL_OUT, SPACE};
@ -72,13 +73,20 @@ impl Node {
if !self.simple { if !self.simple {
//---------------------------------------------------------------------------------------------------- Arguments //---------------------------------------------------------------------------------------------------- Arguments
debug!("Node Tab | Rendering [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( start_options_field(
ui, ui,
&mut self.arguments, &mut self.arguments,
r#"--zmq-pub tcp://127.0.0.1:18081"#, &default_args_simple,
NODE_ARGUMENTS, &default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
); );
//---------------------------------------------------------------------------------------------------- Prunned checkbox //---------------------------------------------------------------------------------------------------- Prunned checkbox
if !self.arguments.is_empty() {
ui.disable();
}
ui.add_space(SPACE); ui.add_space(SPACE);
debug!("Node Tab | Rendering DNS and Prunning buttons"); debug!("Node Tab | Rendering DNS and Prunning buttons");
ui.horizontal(|ui| { 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::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; use crate::helper::p2pool::PubP2poolApi;
// Gupaxx - Fork of Gupax // Gupaxx - Fork of Gupax
// //
@ -20,6 +20,7 @@ use crate::helper::p2pool::PubP2poolApi;
use crate::{components::node::*, constants::*, helper::*}; use crate::{components::node::*, constants::*, helper::*};
use log::*; use log::*;
use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use super::common::header_tab::header_tab; use super::common::header_tab::header_tab;
@ -41,6 +42,8 @@ impl P2pool {
buffer: &mut String, buffer: &mut String,
_ctx: &egui::Context, _ctx: &egui::Context,
ui: &mut egui::Ui, ui: &mut egui::Ui,
backup_nodes: Option<Vec<PoolNode>>,
path: &Path,
) { ) {
//---------------------------------------------------------------------------------------------------- [Simple] Console //---------------------------------------------------------------------------------------------------- [Simple] Console
// debug!("P2Pool Tab | Rendering [Console]"); // debug!("P2Pool Tab | Rendering [Console]");
@ -69,11 +72,17 @@ impl P2pool {
} }
}); });
if !self.simple { 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( start_options_field(
ui, ui,
&mut self.arguments, &mut self.arguments,
r#"--wallet <...> --host <...>"#, &default_args_simple,
P2POOL_ARGUMENTS, &default_args_advanced,
Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
); );
} }
debug!("P2Pool Tab | Rendering [Address]"); debug!("P2Pool Tab | Rendering [Address]");
@ -86,6 +95,9 @@ impl P2pool {
if self.simple { if self.simple {
self.simple(ui, ping, &mut api_lock); self.simple(ui, ping, &mut api_lock);
} else { } else {
if !self.arguments.is_empty() {
ui.disable();
}
self.advanced(ui, node_vec); 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, monero_address_field, slider_state_field,
}; };
use crate::constants::*; use crate::constants::*;
use crate::disk::state::Xmrig; use crate::disk::state::{StartOptionsMode, Xmrig};
use crate::helper::xrig::xmrig::PubXmrigApi; use crate::helper::xrig::xmrig::PubXmrigApi;
use crate::helper::{Process, ProcessName}; use crate::helper::{Process, ProcessName};
use crate::miscs::height_txt_before_button; use crate::miscs::height_txt_before_button;
@ -30,6 +30,7 @@ use crate::regex::REGEXES;
use egui::{Checkbox, Ui, vec2}; use egui::{Checkbox, Ui, vec2};
use log::*; use log::*;
use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use super::common::list_poolnode::PoolNode; use super::common::list_poolnode::PoolNode;
@ -46,6 +47,7 @@ impl Xmrig {
buffer: &mut String, buffer: &mut String,
_ctx: &egui::Context, _ctx: &egui::Context,
ui: &mut egui::Ui, ui: &mut egui::Ui,
path: &Path,
) { ) {
header_tab( header_tab(
ui, ui,
@ -72,14 +74,16 @@ impl Xmrig {
}); });
if !self.simple { if !self.simple {
debug!("XMRig Tab | Rendering [Arguments]"); debug!("XMRig Tab | Rendering [Arguments]");
ui.horizontal(|ui| { let default_args_simple = self.start_options(path, StartOptionsMode::Simple);
start_options_field( let default_args_advanced = self.start_options(path, StartOptionsMode::Advanced);
ui, start_options_field(
&mut self.arguments, ui,
r#"--url <...> --user <...> --config <...>"#, &mut self.arguments,
XMRIG_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| { ui.add_enabled_ui(self.arguments.is_empty(), |ui| {
debug!("XMRig Tab | Rendering [Address]"); debug!("XMRig Tab | Rendering [Address]");
monero_address_field(&mut self.address, ui, XMRIG_ADDRESS); monero_address_field(&mut self.address, ui, XMRIG_ADDRESS);
@ -108,6 +112,9 @@ impl Xmrig {
); );
}); });
if !self.simple { if !self.simple {
if !self.arguments.is_empty() {
ui.disable();
}
egui::ScrollArea::horizontal() egui::ScrollArea::horizontal()
.id_salt("xmrig_horizontal") .id_salt("xmrig_horizontal")
.show(ui, |ui| { .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::console::{console, input_args_field, start_options_field};
use crate::app::panels::middle::common::header_tab::header_tab; use crate::app::panels::middle::common::header_tab::header_tab;
use crate::app::panels::middle::common::list_poolnode::list_poolnode; 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::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::{Process, ProcessName}; use crate::helper::{Process, ProcessName};
use crate::miscs::height_txt_before_button; use crate::miscs::height_txt_before_button;
use crate::regex::REGEXES; use crate::regex::REGEXES;
use crate::{ use crate::{
SPACE, XMRIG_API_IP, XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE, XMRIG_NAME, XMRIG_PORT, SPACE, START_OPTIONS_HOVER, XMRIG_API_IP, XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE,
XMRIG_PROXY_ARGUMENTS, XMRIG_PROXY_INPUT, XMRIG_PROXY_REDIRECT, XMRIG_PROXY_URL, XMRIG_RIG, XMRIG_NAME, XMRIG_PORT, XMRIG_PROXY_INPUT, XMRIG_PROXY_REDIRECT, XMRIG_PROXY_URL, XMRIG_RIG,
XMRIG_TLS, XMRIG_TLS,
}; };
@ -73,16 +73,21 @@ impl XmrigProxy {
} }
}); });
if !self.simple { if !self.simple {
if !self.arguments.is_empty() {
ui.disable();
}
//---------------------------------------------------------------------------------------------------- Arguments //---------------------------------------------------------------------------------------------------- Arguments
debug!("XMRig-Proxy Tab | Rendering [Arguments]"); debug!("XMRig-Proxy Tab | Rendering [Arguments]");
ui.horizontal(|ui| { let default_args_simple = self.start_options(StartOptionsMode::Simple);
start_options_field( let default_args_advanced = self.start_options(StartOptionsMode::Advanced);
ui, start_options_field(
&mut self.arguments, ui,
r#"--url <...> --user <...> --config <...>"#, &mut self.arguments,
XMRIG_PROXY_ARGUMENTS, &default_args_simple,
); &default_args_advanced,
}); Self::process_name().start_options_hint(),
START_OPTIONS_HOVER,
);
if !self.arguments.is_empty() { if !self.arguments.is_empty() {
ui.disable(); ui.disable();
} }

View file

@ -3,7 +3,12 @@ use rand::{Rng, distributions::Alphanumeric, thread_rng};
use strum::{EnumCount, EnumIter}; use strum::{EnumCount, EnumIter};
use super::*; 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 //---------------------------------------------------------------------------------------------------- [State] Impl
impl Default for State { impl Default for State {
fn default() -> Self { 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, 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 { impl std::fmt::Display for ProcessState {

View file

@ -31,7 +31,7 @@ use std::{
use tokio::spawn; use tokio::spawn;
use crate::{ use crate::{
disk::state::Node, disk::state::{Node, StartOptionsMode},
helper::{ helper::{
ProcessName, ProcessSignal, ProcessState, check_died, check_user_input, signal_end, ProcessName, ProcessSignal, ProcessState, check_died, check_user_input, signal_end,
sleep_end_loop, 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); let mut args = Vec::with_capacity(500);
// [Simple] // [Simple]
if state.simple { match mode {
// Build the node argument to be compatible with p2pool, prune by default StartOptionsMode::Simple => {
args.push("--zmq-pub".to_string()); // Build the node argument to be compatible with p2pool, prune by default
args.push("tcp://127.0.0.1:18083".to_string()); // Local P2Pool (the default) args.push("--zmq-pub".to_string());
args.push("--out-peers".to_string()); args.push("tcp://127.0.0.1:18083".to_string()); // Local P2Pool (the default)
args.push("32".to_string()); args.push("--out-peers".to_string());
args.push("--in-peers".to_string()); args.push("32".to_string());
args.push("64".to_string()); // Rig name args.push("--in-peers".to_string());
args.push("--add-priority-node".to_string()); args.push("64".to_string()); // Rig name
args.push("p2pmd.xmrvsbeast.com:18080".to_string()); args.push("--add-priority-node".to_string());
args.push("--add-priority-node".to_string()); args.push("p2pmd.xmrvsbeast.com:18080".to_string());
args.push("nodes.hashvault.pro:18080".to_string()); args.push("--add-priority-node".to_string());
args.push("--disable-dns-checkpoints".to_string()); args.push("nodes.hashvault.pro:18080".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 {
args.push("--disable-dns-checkpoints".to_string()); args.push("--disable-dns-checkpoints".to_string());
} args.push("--enable-dns-blocklist".to_string());
if state.pruned { args.push("--sync-pruned-blocks".to_string());
args.push("--prune-blockchain".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 args
} }
@ -175,8 +180,14 @@ impl Helper {
// The "frontend" function that parses the arguments, and spawns either the [Simple] or [Advanced] Node watchdog thread. // The "frontend" function that parses the arguments, and spawns either the [Simple] or [Advanced] Node watchdog thread.
pub fn start_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) { pub fn start_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) {
helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle; helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let mode = if state.simple {
let args = Self::build_node_args(state); 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 // Print arguments & user settings to console
crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args)); 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::app::panels::middle::common::list_poolnode::PoolNode;
use crate::components::node::RemoteNode; use crate::components::node::RemoteNode;
use crate::disk::state::P2pool; use crate::disk::state::P2pool;
use crate::disk::state::StartOptionsMode;
use crate::helper::ProcessName; use crate::helper::ProcessName;
use crate::helper::ProcessSignal; use crate::helper::ProcessSignal;
use crate::helper::ProcessState; use crate::helper::ProcessState;
@ -228,14 +229,17 @@ impl Helper {
override_to_local_node: bool, override_to_local_node: bool,
) { ) {
helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle; helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let (args, api_path_local, api_path_network, api_path_pool, api_path_p2p) = let (api_path_local, api_path_network, api_path_pool, api_path_p2p) =
Self::build_p2pool_args_and_mutate_img( Self::mutate_img_p2pool(state, helper, path);
helper, let mode = if state.simple {
state, StartOptionsMode::Simple
path, } else if !state.arguments.is_empty() {
&backup_hosts, StartOptionsMode::Custom
override_to_local_node, } else {
); StartOptionsMode::Advanced
};
let args =
Self::build_p2pool_args(state, path, &backup_hosts, override_to_local_node, mode);
// Print arguments & user settings to console // Print arguments & user settings to console
crate::disk::print_dash(&format!( crate::disk::print_dash(&format!(
@ -288,57 +292,16 @@ impl Helper {
let tail = &address[87..95]; let tail = &address[87..95];
head.to_owned() + "..." + tail head.to_owned() + "..." + tail
} }
pub fn mutate_img_p2pool(
#[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>>,
state: &P2pool, state: &P2pool,
helper: &Arc<Mutex<Self>>,
path: &Path, path: &Path,
backup_hosts: &Option<Vec<PoolNode>>, ) -> (PathBuf, PathBuf, PathBuf, PathBuf) {
override_to_local_node: bool,
) -> (Vec<String>, PathBuf, PathBuf, PathBuf, PathBuf) {
let mut args = Vec::with_capacity(500);
let path = path.to_path_buf(); let path = path.to_path_buf();
let mut api_path = path; let mut api_path = path;
api_path.pop(); api_path.pop();
if state.simple {
// [Simple]
if state.simple && (!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) 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 { *helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(), mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address), address: Self::head_tail_of_monero_address(&state.address),
@ -348,68 +311,136 @@ impl Helper {
out_peers: "10".to_string(), out_peers: "10".to_string(),
in_peers: "10".to_string(), in_peers: "10".to_string(),
}; };
} else if state.simple && (state.local_node || override_to_local_node) { } else if !state.arguments.is_empty() {
// use the local node // This parses the input and attempts to fill out
// Build the p2pool argument // the [ImgP2pool]... This is pretty bad code...
args.push("--wallet".to_string()); let mut last = "";
args.push(state.address.clone()); // Wallet address let lock = helper.lock().unwrap();
args.push("--host".to_string()); let mut p2pool_image = lock.img_p2pool.lock().unwrap();
args.push("127.0.0.1".to_string()); // IP Address let mut mini = false;
args.push("--rpc-port".to_string()); for arg in state.arguments.split_whitespace() {
args.push("18081".to_string()); // RPC Port match last {
args.push("--zmq-port".to_string()); "--mini" => {
args.push("18083".to_string()); // ZMQ Port mini = true;
args.push("--data-api".to_string()); p2pool_image.mini = "P2Pool Mini".to_string();
args.push(api_path.display().to_string()); // API Path }
args.push("--local-api".to_string()); // Enable API "--wallet" => p2pool_image.address = Self::head_tail_of_monero_address(arg),
args.push("--no-color".to_string()); // Remove color escape sequences, Gupax terminal can't parse it :( "--host" => p2pool_image.host = arg.to_string(),
args.push("--mini".to_string()); // P2Pool Mini "--rpc-port" => p2pool_image.rpc = arg.to_string(),
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine. "--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 { *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), address: Self::head_tail_of_monero_address(&state.address),
host: "Local node".to_string(), host: state.selected_node.ip.to_string(),
rpc: "18081".to_string(), rpc: state.selected_node.rpc.to_string(),
zmq: "18083".to_string(), zmq: state.selected_node.zmq_rig.to_string(),
out_peers: "10".to_string(), out_peers: state.out_peers.to_string(),
in_peers: "10".to_string(), in_peers: state.in_peers.to_string(),
}; };
} }
// [Advanced] let mut api_path_local = api_path.clone();
else { let mut api_path_network = api_path.clone();
// Overriding command arguments let mut api_path_pool = api_path.clone();
if !state.arguments.is_empty() { let mut api_path_p2p = api_path.clone();
// This parses the input and attempts to fill out api_path_local.push(P2POOL_API_PATH_LOCAL);
// the [ImgP2pool]... This is pretty bad code... api_path_network.push(P2POOL_API_PATH_NETWORK);
let mut last = ""; api_path_pool.push(P2POOL_API_PATH_POOL);
let lock = helper.lock().unwrap(); api_path_p2p.push(P2POOL_API_PATH_P2P);
let mut p2pool_image = lock.img_p2pool.lock().unwrap(); (
let mut mini = false; api_path_local,
for arg in state.arguments.split_whitespace() { api_path_network,
match last { api_path_pool,
"--mini" => { api_path_p2p,
mini = true; )
p2pool_image.mini = "P2Pool Mini".to_string(); }
#[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" { let ip = if state.ip == "localhost" {
"127.0.0.1" "127.0.0.1"
} else { } 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(); args
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,
)
} }
#[cold] #[cold]

View file

@ -1,4 +1,5 @@
use crate::constants::*; use crate::constants::*;
use crate::disk::state::StartOptionsMode;
use crate::helper::xrig::update_xmrig_config; use crate::helper::xrig::update_xmrig_config;
use crate::helper::{Helper, ProcessName, ProcessSignal, ProcessState}; use crate::helper::{Helper, ProcessName, ProcessSignal, ProcessState};
use crate::helper::{Process, arc_mut, check_died, check_user_input, sleep, sleep_end_loop}; 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>>, sudo: Arc<Mutex<SudoState>>,
) { ) {
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle; helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let api_ip_port = Self::mutate_img_xmrig(helper, state);
let (args, api_ip_port) = Self::build_xmrig_args_and_mutate_img(helper, state, path); 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 // Print arguments & user settings to console
crate::disk::print_dash(&format!("XMRig | Launch arguments: {:#?}", args)); crate::disk::print_dash(&format!("XMRig | Launch arguments: {:#?}", args));
info!("XMRig | Using path: [{}]", path.display()); 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] #[cold]
#[inline(never)] #[inline(never)]
// Takes in some [State/Xmrig] and parses it to build the actual command arguments. // 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 // 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... // 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( pub fn build_xmrig_args(
helper: &Arc<Mutex<Self>>,
state: &crate::disk::state::Xmrig, state: &crate::disk::state::Xmrig,
path: &std::path::Path, 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 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(); let path = path.to_path_buf();
// The actual binary we're executing is [sudo], technically // The actual binary we're executing is [sudo], technically
// the XMRig path is just an argument to sudo, so add it. // the XMRig path is just an argument to sudo, so add it.
@ -237,81 +301,43 @@ impl Helper {
args.push("--".to_string()); args.push("--".to_string());
args.push(path.display().to_string()); args.push(path.display().to_string());
} }
match mode {
// [Simple] StartOptionsMode::Simple => {
if state.simple { // Build the xmrig argument
// Build the xmrig argument let rig = if state.simple_rig.is_empty() {
let rig = if state.simple_rig.is_empty() { GUPAX_VERSION_UNDERSCORE.to_string()
GUPAX_VERSION_UNDERSCORE.to_string() } else {
} else { state.simple_rig.clone()
state.simple_rig.clone() }; // Rig name
}; // Rig name args.push("--url".to_string());
args.push("--url".to_string()); args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default) args.push("--threads".to_string());
args.push("--threads".to_string()); args.push(state.current_threads.to_string()); // Threads
args.push(state.current_threads.to_string()); // Threads args.push("--user".to_string());
args.push("--user".to_string()); args.push(rig); // Rig name
args.push(rig); // Rig name args.push("--no-color".to_string()); // No color
args.push("--no-color".to_string()); // No color args.push("--http-host".to_string());
args.push("--http-host".to_string()); args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("127.0.0.1".to_string()); // HTTP API IP args.push("--http-port".to_string());
args.push("--http-port".to_string()); args.push("18088".to_string()); // HTTP API Port
args.push("18088".to_string()); // HTTP API Port if state.pause != 0 {
if state.pause != 0 { args.push("--pause-on-active".to_string());
args.push("--pause-on-active".to_string()); args.push(state.pause.to_string());
args.push(state.pause.to_string()); } // Pause on active
} // Pause on active }
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig { StartOptionsMode::Advanced => {
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 {
// XMRig doesn't understand [localhost] // XMRig doesn't understand [localhost]
let ip = if state.ip == "localhost" || state.ip.is_empty() { let ip = if state.ip == "localhost" || state.ip.is_empty() {
"127.0.0.1" "127.0.0.1"
} else { } else {
&state.ip &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() "127.0.0.1".to_string()
} else { } else {
state.api_ip.to_string() 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() "18088".to_string()
} else { } else {
state.api_port.to_string() state.api_port.to_string()
@ -340,15 +366,21 @@ impl Helper {
args.push("--pause-on-active".to_string()); args.push("--pause-on-active".to_string());
args.push(state.pause.to_string()); args.push(state.pause.to_string());
} // Pause on active } // Pause on active
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig { }
url: url.clone(), StartOptionsMode::Custom => {
threads: state.current_threads.to_string(), // 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(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string()); 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. // We actually spawn [sudo] on Unix, with XMRig being the argument.

View file

@ -29,6 +29,7 @@ use std::{
}; };
use tokio::spawn; use tokio::spawn;
use crate::disk::state::StartOptionsMode;
use crate::human::{HumanNumber, HumanTime}; use crate::human::{HumanNumber, HumanTime};
use crate::miscs::client; use crate::miscs::client;
use crate::{ 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 mut args = Vec::with_capacity(500);
let api_ip; let api_ip;
let api_port; let api_port;
let ip; let ip;
let port; let port;
// [Simple] match mode {
if state.simple { StartOptionsMode::Simple => {
// Build the xmrig argument // Build the xmrig argument
let rig = if state.simple_rig.is_empty() { let rig = if state.simple_rig.is_empty() {
GUPAX_VERSION_UNDERSCORE.to_string() GUPAX_VERSION_UNDERSCORE.to_string()
} else { } else {
state.simple_rig.clone() state.simple_rig.clone()
}; // Rig name }; // Rig name
args.push("-o".to_string()); args.push("-o".to_string());
args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default) args.push("127.0.0.1:3333".to_string()); // Local P2Pool (the default)
args.push("-b".to_string()); args.push("-b".to_string());
args.push("0.0.0.0:3355".to_string()); args.push("0.0.0.0:3355".to_string());
args.push("--user".to_string()); args.push("--user".to_string());
args.push(rig); // Rig name args.push(rig); // Rig name
args.push("--no-color".to_string()); // No color args.push("--no-color".to_string()); // No color
args.push("--http-host".to_string()); args.push("--http-host".to_string());
args.push("127.0.0.1".to_string()); // HTTP API IP args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string()); args.push("--http-port".to_string());
args.push("18089".to_string()); // HTTP API Port args.push("18089".to_string()); // HTTP API Port
// [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());
} }
} else { StartOptionsMode::Advanced => {
// XMRig doesn't understand [localhost] // XMRig doesn't understand [localhost]
let p2pool_ip = if state.p2pool_ip == "localhost" || state.p2pool_ip.is_empty() { let p2pool_ip = if state.p2pool_ip == "localhost" || state.p2pool_ip.is_empty() {
"127.0.0.1" "127.0.0.1"
} else { } else {
&state.p2pool_ip &state.p2pool_ip
}; };
api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() { api_ip = if state.api_ip == "localhost" || state.api_ip.is_empty() {
"127.0.0.1".to_string() "127.0.0.1".to_string()
} else { } else {
state.api_ip.to_string() state.api_ip.to_string()
}; };
api_port = if state.api_port.is_empty() { api_port = if state.api_port.is_empty() {
"18089".to_string() "18089".to_string()
} else { } else {
state.api_port.to_string() state.api_port.to_string()
}; };
ip = if state.api_ip == "localhost" || state.ip.is_empty() { ip = if state.api_ip == "localhost" || state.ip.is_empty() {
"0.0.0.0".to_string() "0.0.0.0".to_string()
} else { } else {
state.ip.to_string() state.ip.to_string()
}; };
port = if state.port.is_empty() { port = if state.port.is_empty() {
"3355".to_string() "3355".to_string()
} else { } else {
state.port.to_string() state.port.to_string()
}; };
let p2pool_url = format!("{}:{}", p2pool_ip, state.p2pool_port); // Combine IP:Port into one 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 let bind_url = format!("{}:{}", ip, port); // Combine IP:Port into one string
args.push("--user".to_string()); args.push("--user".to_string());
args.push(state.address.clone()); // Wallet args.push(state.address.clone()); // Wallet
args.push("--rig-id".to_string()); args.push("--rig-id".to_string());
args.push(state.rig.to_string()); // Rig ID args.push(state.rig.to_string()); // Rig ID
args.push("-o".to_string()); args.push("-o".to_string());
args.push(p2pool_url.clone()); // IP/Port args.push(p2pool_url.clone()); // IP/Port
args.push("-b".to_string()); args.push("-b".to_string());
args.push(bind_url.clone()); // IP/Port args.push(bind_url.clone()); // IP/Port
args.push("--http-host".to_string()); args.push("--http-host".to_string());
args.push(api_ip.to_string()); // HTTP API IP args.push(api_ip.to_string()); // HTTP API IP
args.push("--http-port".to_string()); args.push("--http-port".to_string());
args.push(api_port.to_string()); // HTTP API Port args.push(api_port.to_string()); // HTTP API Port
args.push("--no-color".to_string()); // No color escape codes args.push("--no-color".to_string()); // No color escape codes
if state.tls { if state.tls {
args.push("--tls".to_string()); args.push("--tls".to_string());
} // TLS } // TLS
if state.keepalive { if state.keepalive {
args.push("--keepalive".to_string()); args.push("--keepalive".to_string());
} // Keepalive } // 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(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string()); args.push("--http-no-restricted".to_string());
@ -267,7 +269,14 @@ impl Helper {
) { ) {
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle; 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 // Print arguments & user settings to console
crate::disk::print_dash(&format!("XMRig-Proxy | Launch arguments: {:#?}", args)); crate::disk::print_dash(&format!("XMRig-Proxy | Launch arguments: {:#?}", args));
info!("XMRig-Proxy | Using path: [{}]", path.display()); 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_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_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_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_INPUT: &str = "Send a command to XMRig-Proxy";
pub const XMRIG_PROXY_SIMPLE: &str = r#"Use simple XMRig-Proxy settings: pub const XMRIG_PROXY_SIMPLE: &str = r#"Use simple XMRig-Proxy settings:
- Mine to local P2Pool (localhost:3333) - 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. 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 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 // This is the typical space added when using
// [ui.separator()] or [ui.group()] // [ui.separator()] or [ui.group()]
// Used for subtracting the width/height so // 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."#; 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_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: pub const P2POOL_SIMPLE: &str = r#"Use simple P2Pool settings:
- Remote remote Monero node - Remote remote Monero node
- Default P2Pool settings + Mini - 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_DELETE: &str = "Delete the currently selected entry";
pub const LIST_CLEAR: &str = "Clear all current values"; pub const LIST_CLEAR: &str = "Clear all current values";
// Node // 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_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_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))] #[cfg(not(windows))]
@ -492,9 +494,7 @@ pub const XMRIG_ADVANCED: &str = r#"Use advanced XMRig settings:
- TLS setting - TLS setting
- Keepalive setting"#; - Keepalive setting"#;
pub const XMRIG_INPUT: &str = "Send a command to XMRig"; 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_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_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"; 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";