mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2025-03-26 17:18:47 +00:00
feat: handling custom values from processes that depends on them + fixes
feat: add fields for p2pool port, token for xmrig, token/ip/port for proxy feat: no need for restarting service that depends on other when the orher service is restarted with new settings feat: custom args reflects edited fields of other processes feat: rename "node" appearance to "pool" when it means the latter feat: detect and print in status custom pool fix: proxy was setting bind to 0.0.0.0 if localhost name was used fix: generate backup hosts only once at start
This commit is contained in:
parent
1cb943aab0
commit
0f961c13f8
27 changed files with 1169 additions and 405 deletions
|
@ -32,11 +32,13 @@ use crate::helper::Helper;
|
|||
use crate::helper::Process;
|
||||
use crate::helper::ProcessName;
|
||||
use crate::helper::Sys;
|
||||
use crate::helper::node::ImgNode;
|
||||
use crate::helper::node::PubNodeApi;
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::p2pool::PubP2poolApi;
|
||||
use crate::helper::xrig::xmrig::ImgXmrig;
|
||||
use crate::helper::xrig::xmrig::PubXmrigApi;
|
||||
use crate::helper::xrig::xmrig_proxy::ImgProxy;
|
||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
use crate::helper::xvb::PubXvbApi;
|
||||
use crate::helper::xvb::priv_stats::RuntimeMode;
|
||||
|
@ -143,20 +145,21 @@ pub struct App {
|
|||
// actual stats, and all the functions needed to mutate them.
|
||||
pub gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>,
|
||||
// Static stuff
|
||||
pub benchmarks: Vec<Benchmark>, // XMRig CPU benchmarks
|
||||
pub pid: sysinfo::Pid, // Gupax's PID
|
||||
pub max_threads: u16, // Max amount of detected system threads
|
||||
pub now: Instant, // Internal timer
|
||||
pub exe: String, // Path for [Gupax] binary
|
||||
pub dir: String, // Directory [Gupax] binary is in
|
||||
pub resolution: Vec2, // Frame resolution
|
||||
pub os: &'static str, // OS
|
||||
pub admin: bool, // Are we admin? (for Windows)
|
||||
pub os_data_path: PathBuf, // OS data path (e.g: ~/.local/share/gupax/)
|
||||
pub benchmarks: Vec<Benchmark>, // XMRig CPU benchmarks
|
||||
pub pid: sysinfo::Pid, // Gupax's PID
|
||||
pub max_threads: u16, // Max amount of detected system threads
|
||||
pub now: Instant, // Internal timer
|
||||
pub exe: String, // Path for [Gupax] binary
|
||||
pub dir: String, // Directory [Gupax] binary is in
|
||||
pub resolution: Vec2, // Frame resolution
|
||||
pub os: &'static str, // OS
|
||||
pub admin: bool, // Are we admin? (for Windows)
|
||||
pub os_data_path: PathBuf, // OS data path (e.g: ~/.local/share/gupax/)
|
||||
pub gupax_p2pool_api_path: PathBuf, // Gupax-P2Pool API path (e.g: ~/.local/share/gupax/p2pool/)
|
||||
pub state_path: PathBuf, // State file path
|
||||
pub node_path: PathBuf, // Node file path
|
||||
pub pool_path: PathBuf, // Pool file path
|
||||
pub backup_hosts: Option<Vec<PoolNode>>, // P2Pool backup nodes
|
||||
pub version: &'static str, // Gupax version
|
||||
pub name_version: String, // [Gupax vX.X.X]
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -224,8 +227,10 @@ impl App {
|
|||
let xmrig_proxy_api = arc_mut!(PubXmrigProxyApi::new());
|
||||
let xvb_api = arc_mut!(PubXvbApi::new());
|
||||
let node_api = arc_mut!(PubNodeApi::new());
|
||||
let node_img = arc_mut!(ImgNode::default());
|
||||
let p2pool_img = arc_mut!(ImgP2pool::new());
|
||||
let xmrig_img = arc_mut!(ImgXmrig::new());
|
||||
let proxy_img = arc_mut!(ImgProxy::new());
|
||||
|
||||
info!("App Init | Sysinfo...");
|
||||
// We give this to the [Helper] thread.
|
||||
|
@ -292,8 +297,10 @@ impl App {
|
|||
xvb_api.clone(),
|
||||
xmrig_proxy_api.clone(),
|
||||
node_api.clone(),
|
||||
node_img.clone(),
|
||||
p2pool_img.clone(),
|
||||
xmrig_img.clone(),
|
||||
proxy_img.clone(),
|
||||
arc_mut!(GupaxP2poolApi::new())
|
||||
)),
|
||||
node,
|
||||
|
@ -332,6 +339,7 @@ impl App {
|
|||
state_path: PathBuf::new(),
|
||||
node_path: PathBuf::new(),
|
||||
pool_path: PathBuf::new(),
|
||||
backup_hosts: None,
|
||||
version: GUPAX_VERSION,
|
||||
name_version: format!("Gupaxx {}", GUPAX_VERSION),
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -679,6 +687,9 @@ impl App {
|
|||
}
|
||||
|
||||
info!("App ... OK");
|
||||
|
||||
// Backup hosts needs to be available to print the custom args correctly for p2pool
|
||||
app.backup_hosts = app.gather_backup_hosts();
|
||||
app
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ impl crate::app::App {
|
|||
ProcessName::Xvb => XVB_FAILED,
|
||||
}
|
||||
}
|
||||
Syncing | NotMining | OfflineNodesAll => {
|
||||
Syncing | NotMining | OfflinePoolsAll => {
|
||||
color = ORANGE;
|
||||
match process.name {
|
||||
ProcessName::Node => NODE_SYNCING,
|
||||
|
@ -262,8 +262,9 @@ impl crate::app::App {
|
|||
Helper::restart_p2pool(
|
||||
&self.helper,
|
||||
&self.state.p2pool,
|
||||
&self.state.node,
|
||||
&self.state.gupax.absolute_p2pool_path,
|
||||
self.gather_backup_hosts(),
|
||||
self.backup_hosts.clone(),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
@ -272,6 +273,8 @@ impl crate::app::App {
|
|||
Helper::restart_xmrig(
|
||||
&self.helper,
|
||||
&self.state.xmrig,
|
||||
&self.state.p2pool,
|
||||
&self.state.xmrig_proxy,
|
||||
&self.state.gupax.absolute_xmrig_path,
|
||||
Arc::clone(&self.sudo),
|
||||
);
|
||||
|
@ -284,7 +287,7 @@ impl crate::app::App {
|
|||
Helper::restart_xp(
|
||||
&self.helper,
|
||||
&self.state.xmrig_proxy,
|
||||
&self.state.xmrig,
|
||||
&self.state.p2pool,
|
||||
&self.state.gupax.absolute_xp_path,
|
||||
);
|
||||
}
|
||||
|
@ -333,8 +336,9 @@ impl crate::app::App {
|
|||
ProcessName::P2pool => Helper::start_p2pool(
|
||||
&self.helper,
|
||||
&self.state.p2pool,
|
||||
&self.state.node,
|
||||
&self.state.gupax.absolute_p2pool_path,
|
||||
self.gather_backup_hosts(),
|
||||
self.backup_hosts.clone(),
|
||||
false,
|
||||
),
|
||||
|
||||
|
@ -343,6 +347,8 @@ impl crate::app::App {
|
|||
Helper::start_xmrig(
|
||||
&self.helper,
|
||||
&self.state.xmrig,
|
||||
&self.state.p2pool,
|
||||
&self.state.xmrig_proxy,
|
||||
&self.state.gupax.absolute_xmrig_path,
|
||||
Arc::clone(&self.sudo),
|
||||
);
|
||||
|
@ -355,7 +361,7 @@ impl crate::app::App {
|
|||
ProcessName::XmrigProxy => Helper::start_xp(
|
||||
&self.helper,
|
||||
&self.state.xmrig_proxy,
|
||||
&self.state.xmrig,
|
||||
&self.state.p2pool,
|
||||
&self.state.gupax.absolute_xp_path,
|
||||
),
|
||||
ProcessName::Xvb => Helper::start_xvb(
|
||||
|
|
|
@ -101,8 +101,8 @@ impl crate::app::App {
|
|||
);
|
||||
}
|
||||
Tab::P2pool => {
|
||||
let (rpc_port, zmq_port) = self.state.node.ports();
|
||||
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,
|
||||
|
@ -113,8 +113,10 @@ impl crate::app::App {
|
|||
&mut self.p2pool_stdin,
|
||||
ctx,
|
||||
ui,
|
||||
backup_hosts,
|
||||
self.backup_hosts.clone(),
|
||||
&self.state.gupax.absolute_p2pool_path,
|
||||
zmq_port,
|
||||
rpc_port,
|
||||
);
|
||||
}
|
||||
Tab::Xmrig => {
|
||||
|
@ -127,6 +129,7 @@ impl crate::app::App {
|
|||
&mut self.xmrig_stdin,
|
||||
ctx,
|
||||
ui,
|
||||
self.state.p2pool.stratum_port(),
|
||||
);
|
||||
}
|
||||
Tab::XmrigProxy => {
|
||||
|
@ -138,6 +141,7 @@ impl crate::app::App {
|
|||
&self.xmrig_proxy_api,
|
||||
&mut self.xmrig_proxy_stdin,
|
||||
ui,
|
||||
self.state.p2pool.stratum_port(),
|
||||
);
|
||||
}
|
||||
Tab::Xvb => {
|
||||
|
|
|
@ -49,6 +49,9 @@ impl P2pool {
|
|||
if !self.zmq_port_field(ui) {
|
||||
incorrect_input = false;
|
||||
}
|
||||
if !self.stratum_port_field(ui) {
|
||||
incorrect_input = false;
|
||||
}
|
||||
});
|
||||
list_poolnode(
|
||||
ui,
|
||||
|
@ -166,4 +169,19 @@ impl P2pool {
|
|||
.validations(&[|x| REGEXES.ipv4.is_match(x), |x| REGEXES.domain.is_match(x)])
|
||||
.build(ui, &mut self.ip)
|
||||
}
|
||||
|
||||
/// TODO: find a better solution to handle settings that are not String ?
|
||||
fn stratum_port_field(&mut self, ui: &mut Ui) -> bool {
|
||||
let mut port = self.stratum_port.to_string();
|
||||
let valid = StateTextEdit::new(ui)
|
||||
.description("STRATUM PORT")
|
||||
.max_ch(5)
|
||||
.help_msg(HELP_STRATUM_PORT)
|
||||
.validations(&[|x| REGEXES.port.is_match(x)])
|
||||
.build(ui, &mut port);
|
||||
if let Ok(port) = port.parse() {
|
||||
self.stratum_port = port;
|
||||
}
|
||||
valid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ impl P2pool {
|
|||
ui: &mut egui::Ui,
|
||||
backup_nodes: Option<Vec<PoolNode>>,
|
||||
path: &Path,
|
||||
local_node_zmq_port: u16,
|
||||
local_node_rpc_port: u16,
|
||||
) {
|
||||
//---------------------------------------------------------------------------------------------------- [Simple] Console
|
||||
// debug!("P2Pool Tab | Rendering [Console]");
|
||||
|
@ -72,10 +74,20 @@ 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);
|
||||
let default_args_simple = self.start_options(
|
||||
path,
|
||||
&backup_nodes,
|
||||
StartOptionsMode::Simple,
|
||||
local_node_zmq_port,
|
||||
local_node_rpc_port,
|
||||
);
|
||||
let default_args_advanced = self.start_options(
|
||||
path,
|
||||
&backup_nodes,
|
||||
StartOptionsMode::Advanced,
|
||||
local_node_zmq_port,
|
||||
local_node_rpc_port,
|
||||
);
|
||||
start_options_field(
|
||||
ui,
|
||||
&mut self.arguments,
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::helper::node::PubNodeApi;
|
|||
use crate::helper::p2pool::{ImgP2pool, PubP2poolApi};
|
||||
use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
|
||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
use crate::helper::xvb::nodes::Pool;
|
||||
use crate::helper::xvb::{PubXvbApi, rounds::XvbRound};
|
||||
use crate::helper::{ProcessName, Sys};
|
||||
|
||||
|
@ -285,7 +286,7 @@ fn xmrig_proxy(
|
|||
|
||||
ui.label(RichText::new("Pool").underline().color(BONE))
|
||||
.on_hover_text(STATUS_XMRIG_PROXY_POOL);
|
||||
ui.label(api.node.to_string());
|
||||
ui.label(api.pool.as_ref().unwrap_or(&Pool::Unknown).to_string());
|
||||
drop(api);
|
||||
});
|
||||
}
|
||||
|
@ -337,7 +338,7 @@ fn xmrig(
|
|||
));
|
||||
ui.label(RichText::new("Pool").underline().color(BONE))
|
||||
.on_hover_text(STATUS_XMRIG_POOL);
|
||||
ui.label(api.node.to_string());
|
||||
ui.label(api.pool.as_ref().unwrap_or(&Pool::Unknown).to_string());
|
||||
ui.label(RichText::new("Threads").underline().color(BONE))
|
||||
.on_hover_text(STATUS_XMRIG_THREADS);
|
||||
ui.label(format!(
|
||||
|
|
|
@ -46,6 +46,7 @@ impl Xmrig {
|
|||
buffer: &mut String,
|
||||
_ctx: &egui::Context,
|
||||
ui: &mut egui::Ui,
|
||||
p2pool_stratum_port: u16,
|
||||
) {
|
||||
header_tab(
|
||||
ui,
|
||||
|
@ -72,8 +73,10 @@ impl Xmrig {
|
|||
});
|
||||
if !self.simple {
|
||||
debug!("XMRig Tab | Rendering [Arguments]");
|
||||
let default_args_simple = self.start_options(StartOptionsMode::Simple);
|
||||
let default_args_advanced = self.start_options(StartOptionsMode::Advanced);
|
||||
let default_args_simple =
|
||||
self.start_options(StartOptionsMode::Simple, p2pool_stratum_port);
|
||||
let default_args_advanced =
|
||||
self.start_options(StartOptionsMode::Advanced, p2pool_stratum_port);
|
||||
start_options_field(
|
||||
ui,
|
||||
&mut self.arguments,
|
||||
|
|
|
@ -34,9 +34,9 @@ use crate::{
|
|||
XMRIG_TLS,
|
||||
};
|
||||
|
||||
use super::XMRIG_API_TOKEN;
|
||||
use super::common::list_poolnode::PoolNode;
|
||||
use super::common::state_edit_field::StateTextEdit;
|
||||
use super::{HELP_STRATUM_IP, HELP_STRATUM_PORT, XMRIG_API_TOKEN};
|
||||
|
||||
impl XmrigProxy {
|
||||
#[inline(always)] // called once
|
||||
|
@ -47,6 +47,7 @@ impl XmrigProxy {
|
|||
api: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||
buffer: &mut String,
|
||||
ui: &mut egui::Ui,
|
||||
stratum_port: u16,
|
||||
) {
|
||||
header_tab(
|
||||
ui,
|
||||
|
@ -76,8 +77,10 @@ impl XmrigProxy {
|
|||
if !self.simple {
|
||||
//---------------------------------------------------------------------------------------------------- Arguments
|
||||
debug!("XMRig-Proxy Tab | Rendering [Arguments]");
|
||||
let default_args_simple = self.start_options(StartOptionsMode::Simple);
|
||||
let default_args_advanced = self.start_options(StartOptionsMode::Advanced);
|
||||
let default_args_simple =
|
||||
self.start_options(StartOptionsMode::Simple, stratum_port);
|
||||
let default_args_advanced =
|
||||
self.start_options(StartOptionsMode::Advanced, stratum_port);
|
||||
start_options_field(
|
||||
ui,
|
||||
&mut self.arguments,
|
||||
|
@ -135,8 +138,8 @@ impl XmrigProxy {
|
|||
ui,
|
||||
&mut (
|
||||
&mut self.name,
|
||||
&mut self.ip,
|
||||
&mut self.port,
|
||||
&mut self.p2pool_ip,
|
||||
&mut self.p2pool_port,
|
||||
&mut self.rig,
|
||||
),
|
||||
&mut self.selected_pool,
|
||||
|
@ -148,7 +151,7 @@ impl XmrigProxy {
|
|||
});
|
||||
ui.add_space(5.0);
|
||||
|
||||
debug!("XMRig-Proxy Tab | Rendering [API] TextEdits");
|
||||
debug!("XMRig-Proxy Tab | Rendering [API/BIND] TextEdits");
|
||||
// [HTTP API IP/Port]
|
||||
ui.group(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
|
@ -157,6 +160,8 @@ impl XmrigProxy {
|
|||
self.api_ip_field(ui);
|
||||
self.api_port_field(ui);
|
||||
self.api_token_field(ui);
|
||||
self.stratum_ip_field(ui);
|
||||
self.stratum_port_field(ui);
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
@ -198,11 +203,11 @@ impl XmrigProxy {
|
|||
}
|
||||
fn rpc_port_field(&mut self, ui: &mut Ui) -> bool {
|
||||
StateTextEdit::new(ui)
|
||||
.description(" RPC PORT ")
|
||||
.description(" PORT ")
|
||||
.max_ch(5)
|
||||
.help_msg(XMRIG_PORT)
|
||||
.validations(&[|x| REGEXES.port.is_match(x)])
|
||||
.build(ui, &mut self.port)
|
||||
.build(ui, &mut self.p2pool_port)
|
||||
}
|
||||
fn ip_field(&mut self, ui: &mut Ui) -> bool {
|
||||
StateTextEdit::new(ui)
|
||||
|
@ -210,7 +215,7 @@ impl XmrigProxy {
|
|||
.max_ch(255)
|
||||
.help_msg(XMRIG_IP)
|
||||
.validations(&[|x| REGEXES.ipv4.is_match(x) || REGEXES.domain.is_match(x)])
|
||||
.build(ui, &mut self.ip)
|
||||
.build(ui, &mut self.p2pool_ip)
|
||||
}
|
||||
fn rig_field(&mut self, ui: &mut Ui) -> bool {
|
||||
StateTextEdit::new(ui)
|
||||
|
@ -242,4 +247,21 @@ impl XmrigProxy {
|
|||
.help_msg(XMRIG_API_TOKEN)
|
||||
.build(ui, &mut self.token)
|
||||
}
|
||||
fn stratum_ip_field(&mut self, ui: &mut Ui) -> bool {
|
||||
StateTextEdit::new(ui)
|
||||
.description(" BIND IP ")
|
||||
.max_ch(255)
|
||||
.help_msg(HELP_STRATUM_IP)
|
||||
.validations(&[|x| REGEXES.ipv4.is_match(x) || REGEXES.domain.is_match(x)])
|
||||
.build(ui, &mut self.ip)
|
||||
}
|
||||
fn stratum_port_field(&mut self, ui: &mut Ui) -> bool {
|
||||
let valid = StateTextEdit::new(ui)
|
||||
.description(" BIND PORT ")
|
||||
.max_ch(5)
|
||||
.help_msg(HELP_STRATUM_PORT)
|
||||
.validations(&[|x| REGEXES.port.is_match(x)])
|
||||
.build(ui, &mut self.port);
|
||||
valid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ impl crate::disk::state::Xvb {
|
|||
ui.add_enabled_ui(is_alive, |ui| {
|
||||
let api = &api.lock().unwrap();
|
||||
let priv_stats = &api.stats_priv;
|
||||
let current_node = &api.current_node;
|
||||
let current_node = &api.current_pool;
|
||||
let style_height = ui.text_style_height(&TextStyle::Body);
|
||||
|
||||
let width_column = ui.text_style_height(&TextStyle::Body) * 12.0;
|
||||
|
@ -327,7 +327,7 @@ if priv_stats.win_current {
|
|||
.map_or("No where".to_string(), |n| n.to_string()),
|
||||
)
|
||||
.on_hover_text_at_pointer(&priv_stats.msg_indicator);
|
||||
ui.label(Uptime::from(priv_stats.time_switch_node).to_string())
|
||||
ui.label(Uptime::from(priv_stats.time_switch_pool).to_string())
|
||||
.on_hover_text_at_pointer(&priv_stats.msg_indicator)
|
||||
})
|
||||
});
|
||||
|
|
|
@ -324,6 +324,8 @@ impl crate::app::App {
|
|||
self.sudo.clone(),
|
||||
&self.helper.clone(),
|
||||
&self.state.xmrig,
|
||||
&self.state.p2pool,
|
||||
&self.state.xmrig_proxy,
|
||||
&self.state.gupax.absolute_xmrig_path,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ use crate::{
|
|||
app::panels::middle::common::list_poolnode::PoolNode,
|
||||
components::node::RemoteNode,
|
||||
disk::status::*,
|
||||
helper::{Helper, ProcessName},
|
||||
helper::{
|
||||
Helper, Process, ProcessName, node::ImgNode, p2pool::ImgP2pool, xrig::xmrig_proxy::ImgProxy,
|
||||
},
|
||||
};
|
||||
//---------------------------------------------------------------------------------------------------- [State] Impl
|
||||
impl Default for State {
|
||||
|
@ -305,6 +307,7 @@ pub struct P2pool {
|
|||
pub ip: String,
|
||||
pub rpc: String,
|
||||
pub zmq: String,
|
||||
pub stratum_port: u16,
|
||||
pub selected_node: SelectedPoolNode,
|
||||
pub prefer_local_node: bool,
|
||||
pub console_height: u32,
|
||||
|
@ -627,6 +630,7 @@ impl Default for P2pool {
|
|||
ip: "localhost".to_string(),
|
||||
rpc: "18081".to_string(),
|
||||
zmq: "18083".to_string(),
|
||||
stratum_port: P2POOL_PORT_DEFAULT,
|
||||
selected_node: SelectedPoolNode {
|
||||
index: 0,
|
||||
name: "Local Monero Node".to_string(),
|
||||
|
@ -663,7 +667,7 @@ impl Default for Xmrig {
|
|||
ip: "localhost".to_string(),
|
||||
port: "3333".to_string(),
|
||||
api_ip: "localhost".to_string(),
|
||||
api_port: "18088".to_string(),
|
||||
api_port: XMRIG_API_PORT_DEFAULT.to_string(),
|
||||
tls: false,
|
||||
keepalive: false,
|
||||
current_threads: 1,
|
||||
|
@ -721,6 +725,55 @@ impl Node {
|
|||
pub fn start_options(&self, mode: StartOptionsMode) -> String {
|
||||
Helper::build_node_args(self, mode).join(" ")
|
||||
}
|
||||
/// Return rpc port, zmq port from state
|
||||
pub fn ports(&self) -> (u16, u16) {
|
||||
let mut zmq_port = NODE_ZMQ_PORT_DEFAULT;
|
||||
let mut rpc_port = NODE_RPC_PORT_DEFAULT;
|
||||
if self.simple {
|
||||
zmq_port = NODE_ZMQ_PORT_DEFAULT;
|
||||
rpc_port = NODE_RPC_PORT_DEFAULT;
|
||||
} else if !self.arguments.is_empty() {
|
||||
// This parses the input and attempts to fill out
|
||||
// the [ImgXmrig]... This is pretty bad code...
|
||||
let mut last = "";
|
||||
for arg in self.arguments.split_whitespace() {
|
||||
match last {
|
||||
"--zmq-pub" => {
|
||||
zmq_port = last
|
||||
.split(":")
|
||||
.last()
|
||||
.unwrap_or(&NODE_ZMQ_PORT_DEFAULT.to_string())
|
||||
.parse()
|
||||
.unwrap_or(NODE_ZMQ_PORT_DEFAULT);
|
||||
}
|
||||
"--rpc-bind-port" => zmq_port = last.parse().unwrap_or(NODE_RPC_PORT_DEFAULT),
|
||||
_ => (),
|
||||
}
|
||||
last = arg;
|
||||
}
|
||||
} else {
|
||||
zmq_port = if self.api_port.is_empty() {
|
||||
NODE_ZMQ_PORT_DEFAULT
|
||||
} else {
|
||||
self.zmq_port.parse().unwrap_or(NODE_ZMQ_PORT_DEFAULT)
|
||||
};
|
||||
rpc_port = if self.api_port.is_empty() {
|
||||
NODE_RPC_PORT_DEFAULT
|
||||
} else {
|
||||
self.api_port.parse().unwrap_or(NODE_RPC_PORT_DEFAULT)
|
||||
};
|
||||
}
|
||||
(rpc_port, zmq_port)
|
||||
}
|
||||
/// get the ports that the node process is currently using or that it will use if started with current settings
|
||||
pub fn current_ports(&self, node_process: &Process, img_node: &ImgNode) -> (u16, u16) {
|
||||
let node_is_alive = node_process.is_alive();
|
||||
if node_is_alive {
|
||||
(img_node.zmq_port, img_node.rpc_port)
|
||||
} else {
|
||||
self.ports()
|
||||
}
|
||||
}
|
||||
}
|
||||
impl P2pool {
|
||||
pub const fn process_name() -> ProcessName {
|
||||
|
@ -731,24 +784,116 @@ impl P2pool {
|
|||
path: &Path,
|
||||
backup_nodes: &Option<Vec<PoolNode>>,
|
||||
mode: StartOptionsMode,
|
||||
local_node_zmq_port: u16,
|
||||
local_node_rpc_port: u16,
|
||||
) -> String {
|
||||
Helper::build_p2pool_args(self, path, backup_nodes, false, mode).join(" ")
|
||||
Helper::build_p2pool_args(
|
||||
self,
|
||||
path,
|
||||
backup_nodes,
|
||||
false,
|
||||
local_node_rpc_port,
|
||||
local_node_zmq_port,
|
||||
mode,
|
||||
)
|
||||
.join(" ")
|
||||
}
|
||||
/// get the port that the p2pool process would use for stratum if it were using the current settings
|
||||
pub fn stratum_port(&self) -> u16 {
|
||||
if self.simple {
|
||||
P2POOL_PORT_DEFAULT
|
||||
} else if !self.arguments.is_empty() {
|
||||
let mut last = "";
|
||||
for arg in self.arguments.split_whitespace() {
|
||||
if last == "--stratum" {
|
||||
return last
|
||||
.split(":")
|
||||
.last()
|
||||
.unwrap_or(&P2POOL_PORT_DEFAULT.to_string())
|
||||
.parse()
|
||||
.unwrap_or(P2POOL_PORT_DEFAULT);
|
||||
}
|
||||
last = arg;
|
||||
}
|
||||
return P2POOL_PORT_DEFAULT;
|
||||
} else {
|
||||
return self.stratum_port;
|
||||
}
|
||||
}
|
||||
|
||||
/// get the ports that the node process is currently using or that it will use if started with current settings
|
||||
pub fn current_port(&self, p2pool_process: &Process, img_p2pool: &ImgP2pool) -> u16 {
|
||||
let p2pool_is_alive = p2pool_process.is_alive();
|
||||
if p2pool_is_alive {
|
||||
img_p2pool.stratum_port
|
||||
} else {
|
||||
self.stratum_port()
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Xmrig {
|
||||
pub const fn process_name() -> ProcessName {
|
||||
ProcessName::Xmrig
|
||||
}
|
||||
pub fn start_options(&self, mode: StartOptionsMode) -> String {
|
||||
Helper::build_xmrig_args(self, mode).join(" ")
|
||||
pub fn start_options(&self, mode: StartOptionsMode, p2pool_stratum_port: u16) -> String {
|
||||
Helper::build_xmrig_args(self, mode, p2pool_stratum_port).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(" ")
|
||||
pub fn start_options(&self, mode: StartOptionsMode, p2pool_stratum_port: u16) -> String {
|
||||
Helper::build_xp_args(self, mode, p2pool_stratum_port).join(" ")
|
||||
}
|
||||
/// get the API port that would be used if xmrig was started with the current settings
|
||||
pub fn api_port(&self) -> u16 {
|
||||
if self.simple {
|
||||
PROXY_API_PORT_DEFAULT
|
||||
} else if !self.arguments.is_empty() {
|
||||
let mut last = "";
|
||||
for arg in self.arguments.split_whitespace() {
|
||||
if last == "--http-host" {
|
||||
return last.parse().unwrap_or(PROXY_API_PORT_DEFAULT);
|
||||
}
|
||||
last = arg;
|
||||
}
|
||||
return PROXY_API_PORT_DEFAULT;
|
||||
} else {
|
||||
return self.api_port.parse().unwrap_or(PROXY_API_PORT_DEFAULT);
|
||||
}
|
||||
}
|
||||
/// get the port that would be used if xmrig was started with the current settings
|
||||
pub fn bind_port(&self) -> u16 {
|
||||
if self.simple {
|
||||
PROXY_PORT_DEFAULT
|
||||
} else if !self.arguments.is_empty() {
|
||||
let mut last = "";
|
||||
for arg in self.arguments.split_whitespace() {
|
||||
if last == "--bind" || last == "-b" {
|
||||
return last
|
||||
.split(":")
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.parse()
|
||||
.unwrap_or(PROXY_PORT_DEFAULT);
|
||||
}
|
||||
last = arg;
|
||||
}
|
||||
return PROXY_PORT_DEFAULT;
|
||||
} else {
|
||||
return self.port.parse().unwrap_or(PROXY_PORT_DEFAULT);
|
||||
}
|
||||
}
|
||||
/// get the port that proxy process is currently using or that it will use if started with current settings
|
||||
/// return (bind port, api port)
|
||||
pub fn current_ports(&self, proxy_process: &Process, img_proxy: &ImgProxy) -> (u16, u16) {
|
||||
let proxy_is_alive = proxy_process.is_alive();
|
||||
if proxy_is_alive {
|
||||
(img_proxy.port, img_proxy.api_port)
|
||||
} else {
|
||||
(self.bind_port(), self.api_port())
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl Xvb {
|
||||
|
|
|
@ -87,6 +87,7 @@ mod test {
|
|||
zmq = "18083"
|
||||
prefer_local_node = true
|
||||
console_height = 360
|
||||
stratum_port = 3333
|
||||
|
||||
[p2pool.selected_node]
|
||||
index = 0
|
||||
|
|
|
@ -44,7 +44,7 @@ use crate::helper::{
|
|||
use crate::{constants::*, disk::gupax_p2pool_api::GupaxP2poolApi, human::*, macros::*};
|
||||
use derive_more::derive::Display;
|
||||
use log::*;
|
||||
use node::PubNodeApi;
|
||||
use node::{ImgNode, PubNodeApi};
|
||||
use portable_pty::Child;
|
||||
use readable::up::Uptime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -57,8 +57,9 @@ use std::{
|
|||
time::*,
|
||||
};
|
||||
use strum::{EnumCount, EnumIter};
|
||||
use xrig::xmrig_proxy::ImgProxy;
|
||||
|
||||
use self::xvb::{PubXvbApi, nodes::XvbNode};
|
||||
use self::xvb::{PubXvbApi, nodes::Pool};
|
||||
pub mod node;
|
||||
pub mod p2pool;
|
||||
pub mod tests;
|
||||
|
@ -92,8 +93,10 @@ pub struct Helper {
|
|||
pub gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for GUI thread)
|
||||
pub gui_api_xvb: Arc<Mutex<PubXvbApi>>, // XMRig API state (for GUI thread)
|
||||
pub gui_api_node: Arc<Mutex<PubNodeApi>>, // Node API state (for GUI thread)
|
||||
pub img_node: Arc<Mutex<ImgNode>>, // A static "image" of the data XMRig started with
|
||||
pub img_p2pool: Arc<Mutex<ImgP2pool>>, // A static "image" of the data P2Pool started with
|
||||
pub img_xmrig: Arc<Mutex<ImgXmrig>>, // A static "image" of the data XMRig started with
|
||||
pub img_proxy: Arc<Mutex<ImgProxy>>, // A static "image" of the data XMRig started with
|
||||
pub_api_p2pool: Arc<Mutex<PubP2poolApi>>, // P2Pool API state (for Helper/P2Pool thread)
|
||||
pub_api_xmrig: Arc<Mutex<PubXmrigApi>>, // XMRig API state (for Helper/XMRig thread)
|
||||
pub_api_xp: Arc<Mutex<PubXmrigProxyApi>>, // XMRig-Proxy API state (for Helper/XMRig-Proxy thread)
|
||||
|
@ -202,7 +205,7 @@ impl Process {
|
|||
|| self.state == ProcessState::Middle
|
||||
|| self.state == ProcessState::Syncing
|
||||
|| self.state == ProcessState::NotMining
|
||||
|| self.state == ProcessState::OfflineNodesAll
|
||||
|| self.state == ProcessState::OfflinePoolsAll
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -227,8 +230,8 @@ pub enum ProcessState {
|
|||
// Only for XMRig and XvB, ORANGE.
|
||||
// XvB: token or address are invalid even if syntax correct
|
||||
NotMining,
|
||||
// XvB: if node of XvB become unusable (ex: offline).
|
||||
OfflineNodesAll,
|
||||
// XvB: if pool of XvB become unusable (ex: offline).
|
||||
OfflinePoolsAll,
|
||||
}
|
||||
|
||||
impl Default for ProcessState {
|
||||
|
@ -237,13 +240,13 @@ impl Default for ProcessState {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum ProcessSignal {
|
||||
None,
|
||||
Start,
|
||||
Stop,
|
||||
Restart,
|
||||
UpdateNodes(XvbNode),
|
||||
UpdatePools(Pool),
|
||||
}
|
||||
|
||||
impl Default for ProcessSignal {
|
||||
|
@ -388,8 +391,10 @@ impl Helper {
|
|||
gui_api_xvb: Arc<Mutex<PubXvbApi>>,
|
||||
gui_api_xp: Arc<Mutex<PubXmrigProxyApi>>,
|
||||
gui_api_node: Arc<Mutex<PubNodeApi>>,
|
||||
img_node: Arc<Mutex<ImgNode>>,
|
||||
img_p2pool: Arc<Mutex<ImgP2pool>>,
|
||||
img_xmrig: Arc<Mutex<ImgXmrig>>,
|
||||
img_proxy: Arc<Mutex<ImgProxy>>,
|
||||
gupax_p2pool_api: Arc<Mutex<GupaxP2poolApi>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -412,8 +417,10 @@ impl Helper {
|
|||
gui_api_xvb,
|
||||
gui_api_xp,
|
||||
gui_api_node,
|
||||
img_node,
|
||||
img_p2pool,
|
||||
img_xmrig,
|
||||
img_proxy,
|
||||
gupax_p2pool_api,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,8 @@ impl Helper {
|
|||
} else {
|
||||
StartOptionsMode::Advanced
|
||||
};
|
||||
let (rpc_port, zmq_port) = state.ports();
|
||||
*helper.lock().unwrap().img_node.lock().unwrap() = ImgNode { rpc_port, zmq_port };
|
||||
let args = Self::build_node_args(state, mode);
|
||||
|
||||
// Print arguments & user settings to console
|
||||
|
@ -459,3 +461,17 @@ impl PrivNodeApi {
|
|||
Ok(private)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImgNode {
|
||||
pub rpc_port: u16,
|
||||
pub zmq_port: u16,
|
||||
}
|
||||
|
||||
impl Default for ImgNode {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
rpc_port: 18081,
|
||||
zmq_port: 18083,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use super::Helper;
|
|||
use super::Process;
|
||||
use crate::app::panels::middle::common::list_poolnode::PoolNode;
|
||||
use crate::components::node::RemoteNode;
|
||||
use crate::disk::state::Node;
|
||||
use crate::disk::state::P2pool;
|
||||
use crate::disk::state::StartOptionsMode;
|
||||
use crate::helper::ProcessName;
|
||||
|
@ -193,6 +194,7 @@ impl Helper {
|
|||
pub fn restart_p2pool(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &P2pool,
|
||||
state_node: &Node,
|
||||
path: &Path,
|
||||
backup_hosts: Option<Vec<PoolNode>>,
|
||||
override_to_local_node: bool,
|
||||
|
@ -203,6 +205,7 @@ impl Helper {
|
|||
|
||||
let helper = Arc::clone(helper);
|
||||
let state = state.clone();
|
||||
let state_node = state_node.clone();
|
||||
let path = path.to_path_buf();
|
||||
// This thread lives to wait, start p2pool then die.
|
||||
thread::spawn(move || {
|
||||
|
@ -212,7 +215,14 @@ impl Helper {
|
|||
}
|
||||
// Ok, process is not alive, start the new one!
|
||||
info!("P2Pool | Old process seems dead, starting new one!");
|
||||
Self::start_p2pool(&helper, &state, &path, backup_hosts, override_to_local_node);
|
||||
Self::start_p2pool(
|
||||
&helper,
|
||||
&state,
|
||||
&state_node,
|
||||
&path,
|
||||
backup_hosts,
|
||||
override_to_local_node,
|
||||
);
|
||||
});
|
||||
info!("P2Pool | Restart ... OK");
|
||||
}
|
||||
|
@ -223,6 +233,7 @@ impl Helper {
|
|||
pub fn start_p2pool(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &P2pool,
|
||||
state_node: &Node,
|
||||
path: &Path,
|
||||
backup_hosts: Option<Vec<PoolNode>>,
|
||||
override_to_local_node: bool,
|
||||
|
@ -237,8 +248,22 @@ impl Helper {
|
|||
} else {
|
||||
StartOptionsMode::Advanced
|
||||
};
|
||||
let args =
|
||||
Self::build_p2pool_args(state, path, &backup_hosts, override_to_local_node, mode);
|
||||
// get the rpc and zmq port used when starting the node if it is alive, else use current settings of the Node.
|
||||
// If the Node is started with different ports that the one used in settings when P2Pool was started,
|
||||
// the user will need to restart p2pool
|
||||
let node_process = Arc::clone(&helper.lock().unwrap().node);
|
||||
let img_node = Arc::clone(&helper.lock().unwrap().img_node);
|
||||
let (local_node_zmq, local_node_rpc) =
|
||||
state_node.current_ports(&node_process.lock().unwrap(), &img_node.lock().unwrap());
|
||||
let args = Self::build_p2pool_args(
|
||||
state,
|
||||
path,
|
||||
&backup_hosts,
|
||||
override_to_local_node,
|
||||
local_node_zmq,
|
||||
local_node_rpc,
|
||||
mode,
|
||||
);
|
||||
|
||||
// Print arguments & user settings to console
|
||||
crate::disk::print_dash(&format!(
|
||||
|
@ -256,14 +281,17 @@ impl Helper {
|
|||
// starting the thread even if the option is disabled allows to apply the change immediately in case it is enabled again without asking the user to restart p2pool.
|
||||
// Start this thread only if we don't already override to local node
|
||||
if !override_to_local_node {
|
||||
thread::spawn(enc!((helper, state, path, backup_hosts) move || {
|
||||
Self::watch_switch_p2pool_to_local_node(
|
||||
&helper,
|
||||
&state,
|
||||
&path,
|
||||
backup_hosts,
|
||||
);
|
||||
}));
|
||||
thread::spawn(
|
||||
enc!((helper, state, state_node, path, backup_hosts) move || {
|
||||
Self::watch_switch_p2pool_to_local_node(
|
||||
&helper,
|
||||
&state,
|
||||
&state_node,
|
||||
&path,
|
||||
backup_hosts,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
thread::spawn(move || {
|
||||
|
@ -309,6 +337,7 @@ impl Helper {
|
|||
zmq: zmq.to_string(),
|
||||
out_peers: "10".to_string(),
|
||||
in_peers: "10".to_string(),
|
||||
stratum_port: P2POOL_PORT_DEFAULT,
|
||||
};
|
||||
} else if !state.arguments.is_empty() {
|
||||
// This parses the input and attempts to fill out
|
||||
|
@ -330,6 +359,14 @@ impl Helper {
|
|||
"--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),
|
||||
"--stratum" => {
|
||||
p2pool_image.stratum_port = last
|
||||
.split(":")
|
||||
.last()
|
||||
.unwrap_or(&P2POOL_PORT_DEFAULT.to_string())
|
||||
.parse()
|
||||
.unwrap_or(P2POOL_PORT_DEFAULT)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if !mini {
|
||||
|
@ -349,6 +386,7 @@ impl Helper {
|
|||
host: state.selected_node.ip.to_string(),
|
||||
rpc: state.selected_node.rpc.to_string(),
|
||||
zmq: state.selected_node.zmq_rig.to_string(),
|
||||
stratum_port: state.stratum_port,
|
||||
out_peers: state.out_peers.to_string(),
|
||||
in_peers: state.in_peers.to_string(),
|
||||
};
|
||||
|
@ -378,6 +416,8 @@ impl Helper {
|
|||
path: &Path,
|
||||
backup_hosts: &Option<Vec<PoolNode>>,
|
||||
override_to_local_node: bool,
|
||||
local_node_zmq_port: u16,
|
||||
local_node_rpc_port: u16,
|
||||
// Allows to provide a different mode without mutating the state
|
||||
mode: StartOptionsMode,
|
||||
) -> Vec<String> {
|
||||
|
@ -423,14 +463,17 @@ impl Helper {
|
|||
StartOptionsMode::Simple if state.local_node || override_to_local_node => {
|
||||
// use the local node
|
||||
// Build the p2pool argument
|
||||
// dbg!("Simple mode/local node");
|
||||
// dbg!(local_node_rpc);
|
||||
// dbg!(local_node_zmq);
|
||||
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(local_node_rpc_port.to_string()); // RPC Port
|
||||
args.push("--zmq-port".to_string());
|
||||
args.push("18083".to_string()); // ZMQ Port
|
||||
args.push(local_node_zmq_port.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
|
||||
|
@ -754,6 +797,7 @@ impl Helper {
|
|||
async fn watch_switch_p2pool_to_local_node(
|
||||
helper: &Arc<Mutex<Helper>>,
|
||||
state: &P2pool,
|
||||
state_node: &Node,
|
||||
path_p2pool: &Path,
|
||||
backup_hosts: Option<Vec<PoolNode>>,
|
||||
) {
|
||||
|
@ -776,7 +820,7 @@ impl Helper {
|
|||
drop(process);
|
||||
drop(node_process);
|
||||
drop(helper_lock);
|
||||
Helper::restart_p2pool(helper, state, path_p2pool, backup_hosts, true);
|
||||
Helper::restart_p2pool(helper, state, state_node, path_p2pool, backup_hosts, true);
|
||||
break;
|
||||
}
|
||||
drop(gui_api);
|
||||
|
@ -801,6 +845,7 @@ pub struct ImgP2pool {
|
|||
pub zmq: String, // What is the ZMQ port?
|
||||
pub out_peers: String, // How many out-peers?
|
||||
pub in_peers: String, // How many in-peers?
|
||||
pub stratum_port: u16, // on which port p2pool is listening for stratum connections
|
||||
}
|
||||
|
||||
impl Default for ImgP2pool {
|
||||
|
@ -819,6 +864,7 @@ impl ImgP2pool {
|
|||
zmq: String::from("???"),
|
||||
out_peers: String::from("???"),
|
||||
in_peers: String::from("???"),
|
||||
stratum_port: P2POOL_PORT_DEFAULT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::disk::state::StartOptionsMode;
|
||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
use crate::disk::state::{StartOptionsMode, XmrigProxy};
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::xrig::xmrig::ImgXmrig;
|
||||
use crate::helper::xrig::xmrig_proxy::{ImgProxy, PubXmrigProxyApi};
|
||||
use crate::helper::xvb::algorithm::Algorithm;
|
||||
use crate::helper::{
|
||||
Helper, Process, ProcessName, ProcessState,
|
||||
|
@ -266,6 +268,20 @@ Uptime = 0h 2m 4s
|
|||
"".to_string(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
let process_p2pool = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
"".to_string(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
let process_xp = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::XmrigProxy,
|
||||
"".to_string(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
let img_p2pool = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let img_proxy = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let proxy_state = XmrigProxy::default();
|
||||
let p2pool_state = P2pool::default();
|
||||
|
||||
process.lock().unwrap().state = ProcessState::Alive;
|
||||
PubXmrigApi::update_from_output(
|
||||
|
@ -274,6 +290,12 @@ Uptime = 0h 2m 4s
|
|||
&output_pub,
|
||||
elapsed,
|
||||
&mut process.lock().unwrap(),
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&process_xp.lock().unwrap(),
|
||||
&img_proxy,
|
||||
&img_p2pool,
|
||||
&proxy_state,
|
||||
&p2pool_state,
|
||||
);
|
||||
println!("{:#?}", process);
|
||||
assert!(process.lock().unwrap().state == ProcessState::NotMining);
|
||||
|
@ -287,6 +309,12 @@ Uptime = 0h 2m 4s
|
|||
&output_pub,
|
||||
elapsed,
|
||||
&mut process.lock().unwrap(),
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&process_xp.lock().unwrap(),
|
||||
&img_proxy,
|
||||
&img_p2pool,
|
||||
&proxy_state,
|
||||
&p2pool_state,
|
||||
);
|
||||
assert!(process.lock().unwrap().state == ProcessState::Alive);
|
||||
}
|
||||
|
@ -516,6 +544,14 @@ Uptime = 0h 2m 4s
|
|||
let gui_api_p2pool = Arc::new(Mutex::new(PubP2poolApi::new()));
|
||||
let token_xmrig = "12345678";
|
||||
let state_p2pool = P2pool::default();
|
||||
let proxy_img = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||
let p2pool_process = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
String::new(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
let time_donated = Arc::new(Mutex::new(u32::default()));
|
||||
let rig = "test_rig";
|
||||
let xp_alive = false;
|
||||
|
@ -540,6 +576,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 1000.0);
|
||||
|
@ -560,6 +600,14 @@ Uptime = 0h 2m 4s
|
|||
let xp_alive = false;
|
||||
let share = 1;
|
||||
let p2pool_buffer = 5;
|
||||
let proxy_img = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||
let p2pool_process = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
String::new(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
|
||||
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
|
||||
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualP2pool;
|
||||
|
@ -579,6 +627,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 9000.0);
|
||||
|
@ -599,6 +651,14 @@ Uptime = 0h 2m 4s
|
|||
let xp_alive = false;
|
||||
let share = 1;
|
||||
let p2pool_buffer = 5;
|
||||
let proxy_img = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||
let p2pool_process = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
String::new(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
|
||||
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
|
||||
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualDonationLevel;
|
||||
|
@ -623,6 +683,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 1000.0);
|
||||
|
@ -643,6 +707,14 @@ Uptime = 0h 2m 4s
|
|||
let xp_alive = false;
|
||||
let share = 1;
|
||||
let p2pool_buffer = 5;
|
||||
let proxy_img = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||
let p2pool_process = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
String::new(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
|
||||
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 9_000_000;
|
||||
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
|
||||
|
@ -662,6 +734,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 10000.0);
|
||||
|
@ -684,6 +760,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 1000.0);
|
||||
|
@ -704,6 +784,14 @@ Uptime = 0h 2m 4s
|
|||
let xp_alive = false;
|
||||
let share = 1;
|
||||
let p2pool_buffer = 5;
|
||||
let proxy_img = Arc::new(Mutex::new(ImgProxy::new()));
|
||||
let p2pool_img = Arc::new(Mutex::new(ImgP2pool::new()));
|
||||
let xmrig_img = Arc::new(Mutex::new(ImgXmrig::new()));
|
||||
let p2pool_process = Arc::new(Mutex::new(Process::new(
|
||||
ProcessName::P2pool,
|
||||
String::new(),
|
||||
PathBuf::new(),
|
||||
)));
|
||||
|
||||
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 95_000_000;
|
||||
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
|
||||
|
@ -724,6 +812,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 15382.1);
|
||||
|
@ -744,6 +836,10 @@ Uptime = 0h 2m 4s
|
|||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&p2pool_process,
|
||||
);
|
||||
|
||||
assert_eq!(algo.stats.target_donation_hashrate, 20000.0);
|
||||
|
@ -763,6 +859,8 @@ Uptime = 0h 2m 4s
|
|||
Path::new(""),
|
||||
&None,
|
||||
false,
|
||||
18083,
|
||||
18081,
|
||||
StartOptionsMode::Custom,
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::helper::XvbNode;
|
||||
use crate::XMRIG_API_CONFIG_ENDPOINT;
|
||||
use crate::XMRIG_API_SUMMARY_ENDPOINT;
|
||||
use crate::helper::Pool;
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use log::info;
|
||||
|
@ -24,6 +26,8 @@ use reqwest_middleware::ClientWithMiddleware as Client;
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use xmrig::ImgXmrig;
|
||||
use xmrig_proxy::ImgProxy;
|
||||
|
||||
pub mod xmrig;
|
||||
pub mod xmrig_proxy;
|
||||
|
@ -33,7 +37,7 @@ pub async fn update_xmrig_config(
|
|||
client: &Client,
|
||||
api_uri: &str,
|
||||
token: &str,
|
||||
node: &XvbNode,
|
||||
node: &Pool,
|
||||
address: &str,
|
||||
rig: &str,
|
||||
) -> Result<()> {
|
||||
|
@ -81,3 +85,29 @@ pub async fn update_xmrig_config(
|
|||
struct Hashrate {
|
||||
total: [Option<f32>; 3],
|
||||
}
|
||||
|
||||
/// Take the runtime port. Even if settings were changed, the port will be the current one.
|
||||
/// to get config url, true. False for summary
|
||||
/// provide either xmrig_img or proxy_img
|
||||
pub fn current_api_url_xrig(
|
||||
config: bool,
|
||||
xmrig_img: Option<&ImgXmrig>,
|
||||
proxy_img: Option<&ImgProxy>,
|
||||
) -> String {
|
||||
let (port, endpoint) = if let Some(xmrig) = xmrig_img {
|
||||
if config {
|
||||
(xmrig.api_port, XMRIG_API_CONFIG_ENDPOINT)
|
||||
} else {
|
||||
(xmrig.api_port, XMRIG_API_SUMMARY_ENDPOINT)
|
||||
}
|
||||
} else if let Some(proxy) = proxy_img {
|
||||
if config {
|
||||
(proxy.api_port, XMRIG_API_CONFIG_ENDPOINT)
|
||||
} else {
|
||||
(proxy.api_port, XMRIG_API_SUMMARY_ENDPOINT)
|
||||
}
|
||||
} else {
|
||||
panic!("neither xmrig_img or proxy_img is some");
|
||||
};
|
||||
format!("http://127.0.0.1:{port}/{endpoint}")
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
use crate::constants::*;
|
||||
use crate::disk::state::StartOptionsMode;
|
||||
use crate::disk::state::{P2pool, StartOptionsMode, XmrigProxy};
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::xrig::update_xmrig_config;
|
||||
use crate::helper::{Helper, ProcessName, ProcessSignal, ProcessState};
|
||||
use crate::helper::{Pool, PubXvbApi};
|
||||
use crate::helper::{Process, arc_mut, check_died, check_user_input, sleep, sleep_end_loop};
|
||||
use crate::helper::{PubXvbApi, XvbNode};
|
||||
use crate::human::HumanTime;
|
||||
use crate::miscs::{client, output_console};
|
||||
use crate::regex::{XMRIG_REGEX, contains_error, contains_usepool, detect_new_node_xmrig};
|
||||
use crate::regex::{XMRIG_REGEX, contains_error, contains_usepool, detect_pool_xmrig};
|
||||
use crate::utils::human::HumanNumber;
|
||||
use crate::utils::sudo::SudoState;
|
||||
use enclose::enclose;
|
||||
use enclose::{enc, enclose};
|
||||
use log::*;
|
||||
use portable_pty::Child;
|
||||
use readable::num::Unsigned;
|
||||
|
@ -29,17 +30,24 @@ use std::{
|
|||
use tokio::spawn;
|
||||
|
||||
use super::Hashrate;
|
||||
use super::xmrig_proxy::ImgProxy;
|
||||
|
||||
impl Helper {
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn read_pty_xmrig(
|
||||
output_parse: Arc<Mutex<String>>,
|
||||
output_pub: Arc<Mutex<String>>,
|
||||
reader: Box<dyn std::io::Read + Send>,
|
||||
process_xvb: Arc<Mutex<Process>>,
|
||||
process_xp: Arc<Mutex<Process>>,
|
||||
process_p2pool: Arc<Mutex<Process>>,
|
||||
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
p2pool_state: &P2pool,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
proxy_state: &XmrigProxy,
|
||||
) {
|
||||
use std::io::BufRead;
|
||||
let mut stdout = std::io::BufReader::new(reader).lines();
|
||||
|
@ -54,7 +62,7 @@ impl Helper {
|
|||
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
|
||||
error!("XMRig PTY Pub | Output error: {}", e);
|
||||
}
|
||||
if i > 13 {
|
||||
if i > 7 {
|
||||
break;
|
||||
} else {
|
||||
i += 1;
|
||||
|
@ -62,37 +70,51 @@ impl Helper {
|
|||
}
|
||||
|
||||
while let Some(Ok(line)) = stdout.next() {
|
||||
// need to verify if node still working
|
||||
// need to verify if pool still working
|
||||
// for that need to catch "connect error"
|
||||
// only check if xvb process is used and xmrig-proxy is not.
|
||||
if process_xvb.lock().unwrap().is_alive() && !process_xp.lock().unwrap().is_alive() {
|
||||
if contains_error(&line) {
|
||||
let current_node = pub_api_xvb.lock().unwrap().current_node;
|
||||
if let Some(current_node) = current_node {
|
||||
// updating current node to None, will stop sending signal of FailedNode until new node is set
|
||||
// send signal to update node.
|
||||
warn!("XMRig PTY Parse | node is offline, sending signal to update nodes.");
|
||||
// update nodes only if we were not mining on p2pool.
|
||||
let current_pool = pub_api_xvb.lock().unwrap().current_pool.clone();
|
||||
if let Some(current_pool) = current_pool {
|
||||
// updating current pool to None, will stop sending signal of FailedPool until new pool is set
|
||||
// send signal to update pool.
|
||||
warn!("XMRig PTY Parse | pool is offline, sending signal to update pools.");
|
||||
// update pools only if we were not mining on p2pool.
|
||||
// if xmrig stop, xvb will react in any case.
|
||||
if current_node != XvbNode::P2pool {
|
||||
if current_pool
|
||||
!= Pool::P2pool(p2pool_state.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
))
|
||||
{
|
||||
process_xvb.lock().unwrap().signal =
|
||||
ProcessSignal::UpdateNodes(current_node);
|
||||
ProcessSignal::UpdatePools(current_pool);
|
||||
}
|
||||
pub_api_xvb.lock().unwrap().current_node = None;
|
||||
pub_api_xvb.lock().unwrap().current_pool = None;
|
||||
}
|
||||
}
|
||||
if contains_usepool(&line) {
|
||||
info!("XMRig PTY Parse | new pool detected");
|
||||
// need to update current node because it was updated.
|
||||
// if custom node made by user, it is not supported because algo is deciding which node to use.
|
||||
let node = detect_new_node_xmrig(&line);
|
||||
if node.is_none() {
|
||||
error!("XMRig PTY Parse | node is not understood, switching to backup.");
|
||||
// need to update current pool because it was updated.
|
||||
// if custom pool made by user, it is not supported because algo is deciding which pool to use.
|
||||
let pool = detect_pool_xmrig(
|
||||
&line,
|
||||
proxy_state
|
||||
.current_ports(&process_xp.lock().unwrap(), &proxy_img.lock().unwrap())
|
||||
.0,
|
||||
p2pool_state.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
),
|
||||
);
|
||||
if pool.is_none() {
|
||||
error!("XMRig PTY Parse | pool is not understood, switching to backup.");
|
||||
// update with default will choose which XvB to prefer. Will update XvB to use p2pool.
|
||||
process_xvb.lock().unwrap().signal =
|
||||
ProcessSignal::UpdateNodes(XvbNode::default());
|
||||
ProcessSignal::UpdatePools(Pool::default());
|
||||
}
|
||||
pub_api_xvb.lock().unwrap().current_node = node;
|
||||
pub_api_xvb.lock().unwrap().current_pool = pool;
|
||||
}
|
||||
}
|
||||
// println!("{}", line); // For debugging.
|
||||
|
@ -158,6 +180,8 @@ impl Helper {
|
|||
pub fn restart_xmrig(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &crate::disk::state::Xmrig,
|
||||
state_p2pool: &P2pool,
|
||||
state_proxy: &XmrigProxy,
|
||||
path: &Path,
|
||||
sudo: Arc<Mutex<SudoState>>,
|
||||
) {
|
||||
|
@ -165,19 +189,17 @@ impl Helper {
|
|||
helper.lock().unwrap().xmrig.lock().unwrap().signal = ProcessSignal::Restart;
|
||||
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
|
||||
|
||||
let helper = Arc::clone(helper);
|
||||
let state = state.clone();
|
||||
let path = path.to_path_buf();
|
||||
// This thread lives to wait, start xmrig then die.
|
||||
thread::spawn(move || {
|
||||
thread::spawn(enc!((helper, state, state_p2pool, state_proxy)move || {
|
||||
while helper.lock().unwrap().xmrig.lock().unwrap().state != ProcessState::Waiting {
|
||||
warn!("XMRig | Want to restart but process is still alive, waiting...");
|
||||
sleep!(1000);
|
||||
}
|
||||
// Ok, process is not alive, start the new one!
|
||||
info!("XMRig | Old process seems dead, starting new one!");
|
||||
Self::start_xmrig(&helper, &state, &path, sudo);
|
||||
});
|
||||
Self::start_xmrig(&helper, &state, &state_p2pool, &state_proxy, &path, sudo);
|
||||
}));
|
||||
info!("XMRig | Restart ... OK");
|
||||
}
|
||||
|
||||
|
@ -186,11 +208,20 @@ impl Helper {
|
|||
pub fn start_xmrig(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &crate::disk::state::Xmrig,
|
||||
p2pool_state: &P2pool,
|
||||
proxy_state: &XmrigProxy,
|
||||
path: &Path,
|
||||
sudo: Arc<Mutex<SudoState>>,
|
||||
) {
|
||||
// get the stratum port of p2pool
|
||||
//
|
||||
let process_p2pool = Arc::clone(&helper.lock().unwrap().p2pool);
|
||||
let p2pool_img = Arc::clone(&helper.lock().unwrap().img_p2pool);
|
||||
|
||||
let p2pool_stratum_port =
|
||||
p2pool_state.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap());
|
||||
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
|
||||
let api_ip_port = Self::mutate_img_xmrig(helper, state);
|
||||
let api_ip_port = Self::mutate_img_xmrig(helper, state, p2pool_stratum_port);
|
||||
let mode = if state.simple {
|
||||
StartOptionsMode::Simple
|
||||
} else if !state.arguments.is_empty() {
|
||||
|
@ -198,7 +229,7 @@ impl Helper {
|
|||
} else {
|
||||
StartOptionsMode::Advanced
|
||||
};
|
||||
let args = Self::build_xmrig_args(state, mode);
|
||||
let args = Self::build_xmrig_args(state, mode, p2pool_stratum_port);
|
||||
// Print arguments & user settings to console
|
||||
crate::disk::print_dash(&format!("XMRig | Launch arguments: {:#?}", args));
|
||||
info!("XMRig | Using path: [{}]", path.display());
|
||||
|
@ -212,6 +243,10 @@ impl Helper {
|
|||
let process_p2pool = Arc::clone(&helper.lock().unwrap().p2pool);
|
||||
let path = path.to_path_buf();
|
||||
let token = state.token.clone();
|
||||
let p2pool_state = p2pool_state.clone();
|
||||
let p2pool_img = Arc::clone(&helper.lock().unwrap().img_p2pool);
|
||||
let proxy_state = proxy_state.clone();
|
||||
let proxy_img = Arc::clone(&helper.lock().unwrap().img_proxy);
|
||||
let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
|
||||
thread::spawn(move || {
|
||||
Self::spawn_xmrig_watchdog(
|
||||
|
@ -227,12 +262,17 @@ impl Helper {
|
|||
process_xp,
|
||||
process_p2pool,
|
||||
&pub_api_xvb,
|
||||
&p2pool_state,
|
||||
&p2pool_img,
|
||||
&proxy_state,
|
||||
&proxy_img,
|
||||
);
|
||||
});
|
||||
}
|
||||
pub fn mutate_img_xmrig(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &crate::disk::state::Xmrig,
|
||||
stratum_port: u16,
|
||||
) -> String {
|
||||
let mut api_ip = String::with_capacity(15);
|
||||
let mut api_port = String::with_capacity(5);
|
||||
|
@ -242,7 +282,9 @@ impl Helper {
|
|||
|
||||
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
|
||||
threads: state.current_threads.to_string(),
|
||||
url: "127.0.0.1:3333 (Local P2Pool)".to_string(),
|
||||
url: format!("127.0.0.1:{stratum_port} (Local P2Pool)"),
|
||||
api_port: XMRIG_API_PORT_DEFAULT,
|
||||
token: state.token.clone(),
|
||||
};
|
||||
} else if !state.arguments.is_empty() {
|
||||
// This parses the input and attempts to fill out
|
||||
|
@ -261,7 +303,13 @@ impl Helper {
|
|||
arg.to_string()
|
||||
}
|
||||
}
|
||||
"--http-port" => api_port = arg.to_string(),
|
||||
"--http-port" => {
|
||||
api_port = arg.to_string();
|
||||
xmrig_image.api_port = arg.parse().unwrap_or(XMRIG_API_PORT_DEFAULT)
|
||||
}
|
||||
l if l.contains("--http-access-token=") => {
|
||||
xmrig_image.token = l.split_once("=").unwrap().1.to_string();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
last = arg;
|
||||
|
@ -278,7 +326,7 @@ impl Helper {
|
|||
state.api_ip.to_string()
|
||||
};
|
||||
api_port = if state.api_port.is_empty() {
|
||||
"18088".to_string()
|
||||
XMRIG_API_PORT_DEFAULT.to_string()
|
||||
} else {
|
||||
state.api_port.to_string()
|
||||
};
|
||||
|
@ -286,6 +334,8 @@ impl Helper {
|
|||
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
|
||||
url: url.clone(),
|
||||
threads: state.current_threads.to_string(),
|
||||
api_port: state.api_port.parse().unwrap_or(XMRIG_API_PORT_DEFAULT),
|
||||
token: state.token.clone(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -300,6 +350,7 @@ impl Helper {
|
|||
state: &crate::disk::state::Xmrig,
|
||||
// Allows to provide a different mode without mutating the state
|
||||
mode: StartOptionsMode,
|
||||
p2pool_stratum_port: u16,
|
||||
) -> Vec<String> {
|
||||
let mut args = Vec::with_capacity(500);
|
||||
// some args needs to be added to both simple/advanced
|
||||
|
@ -326,7 +377,7 @@ impl Helper {
|
|||
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(format!("127.0.0.1:{p2pool_stratum_port}")); // Local P2Pool (the default)
|
||||
args.push("--user".to_string());
|
||||
args.push(rig); // Rig name
|
||||
args.push("--http-host".to_string());
|
||||
|
@ -421,6 +472,10 @@ impl Helper {
|
|||
process_xp: Arc<Mutex<Process>>,
|
||||
process_p2pool: Arc<Mutex<Process>>,
|
||||
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
p2pool_state: &P2pool,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
proxy_state: &XmrigProxy,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
) {
|
||||
// The actual binary we're executing is [sudo], technically
|
||||
// the XMRig path is just an argument to sudo, so add it.
|
||||
|
@ -447,9 +502,11 @@ impl Helper {
|
|||
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
|
||||
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
|
||||
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
|
||||
spawn(enclose!((pub_api_xvb, process_xp) async move {
|
||||
Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, process_xp, &pub_api_xvb).await;
|
||||
}));
|
||||
spawn(
|
||||
enclose!((pub_api_xvb, process_xp, p2pool_state, p2pool_img, process_p2pool, proxy_img, proxy_state) async move {
|
||||
Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, process_xp, process_p2pool, &pub_api_xvb, &p2pool_state, &p2pool_img, &proxy_img, &proxy_state).await;
|
||||
}),
|
||||
);
|
||||
// 1b. Create command
|
||||
debug!("XMRig | Creating command...");
|
||||
#[cfg(target_os = "windows")]
|
||||
|
@ -496,19 +553,25 @@ impl Helper {
|
|||
|
||||
let client = client();
|
||||
let start = process.lock().unwrap().start;
|
||||
let api_uri = {
|
||||
let api_uri_config = {
|
||||
if !api_ip_port.ends_with('/') {
|
||||
api_ip_port.push('/');
|
||||
}
|
||||
"http://".to_owned() + &api_ip_port + XMRIG_API_SUMMARY_URI
|
||||
"http://".to_owned() + &api_ip_port + XMRIG_API_CONFIG_ENDPOINT
|
||||
};
|
||||
info!("XMRig | Final API URI: {}", api_uri);
|
||||
let api_uri_summary = {
|
||||
if !api_ip_port.ends_with('/') {
|
||||
api_ip_port.push('/');
|
||||
}
|
||||
"http://".to_owned() + &api_ip_port + XMRIG_API_SUMMARY_ENDPOINT
|
||||
};
|
||||
info!("XMRig | Final API URI: {}", api_uri_config);
|
||||
|
||||
// Reset stats before loop
|
||||
*pub_api.lock().unwrap() = PubXmrigApi::new();
|
||||
*gui_api.lock().unwrap() = PubXmrigApi::new();
|
||||
// node used for process Status tab
|
||||
pub_api.lock().unwrap().node = NO_POOL.to_string();
|
||||
// pool used for process Status tab
|
||||
pub_api.lock().unwrap().pool = None;
|
||||
// 5. Loop as watchdog
|
||||
info!("XMRig | Entering watchdog mode... woof!");
|
||||
// needs xmrig to be in belownormal priority or else Gupaxx will be in trouble if it does not have enough cpu time.
|
||||
|
@ -571,12 +634,18 @@ impl Helper {
|
|||
&output_parse,
|
||||
start.elapsed(),
|
||||
&mut process_lock,
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&process_xp.lock().unwrap(),
|
||||
proxy_img,
|
||||
p2pool_img,
|
||||
proxy_state,
|
||||
p2pool_state,
|
||||
);
|
||||
drop(pub_api_lock);
|
||||
drop(process_lock);
|
||||
// Send an HTTP API request
|
||||
debug!("XMRig Watchdog | Attempting HTTP API request...");
|
||||
match PrivXmrigApi::request_xmrig_api(&client, &api_uri, token).await {
|
||||
match PrivXmrigApi::request_xmrig_api(&client, &api_uri_summary, token).await {
|
||||
Ok(priv_api) => {
|
||||
debug!("XMRig Watchdog | HTTP API request OK, attempting [update_from_priv()]");
|
||||
PubXmrigApi::update_from_priv(&pub_api, priv_api);
|
||||
|
@ -584,25 +653,33 @@ impl Helper {
|
|||
Err(err) => {
|
||||
warn!(
|
||||
"XMRig Watchdog | Could not send HTTP API request to: {}\n{}",
|
||||
api_uri, err
|
||||
api_uri_summary, err
|
||||
);
|
||||
}
|
||||
}
|
||||
// if mining on proxy and proxy is not alive, switch back to p2pool node
|
||||
if (pub_api.lock().unwrap().node == XvbNode::XmrigProxy.to_string()
|
||||
|| pub_api.lock().unwrap().node == NO_POOL)
|
||||
if (pub_api.lock().unwrap().pool
|
||||
== Some(Pool::XmrigProxy(
|
||||
proxy_state
|
||||
.current_ports(&process_xp.lock().unwrap(), &proxy_img.lock().unwrap())
|
||||
.0,
|
||||
))
|
||||
|| pub_api.lock().unwrap().pool.is_none())
|
||||
&& !process_xp.lock().unwrap().is_alive()
|
||||
&& process_p2pool.lock().unwrap().is_alive()
|
||||
{
|
||||
info!(
|
||||
"XMRig Process | redirect xmrig to p2pool since XMRig-Proxy is not alive anymore"
|
||||
"XMRig Process | redirect xmrig to p2pool since XMRig-Proxy is not alive and p2pool is alive"
|
||||
);
|
||||
let pool = Pool::P2pool(
|
||||
p2pool_state
|
||||
.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap()),
|
||||
);
|
||||
let node = XvbNode::P2pool;
|
||||
if let Err(err) = update_xmrig_config(
|
||||
&client,
|
||||
XMRIG_CONFIG_URL,
|
||||
&api_uri_config,
|
||||
token,
|
||||
&node,
|
||||
&pool,
|
||||
"",
|
||||
GUPAX_VERSION_UNDERSCORE,
|
||||
)
|
||||
|
@ -636,8 +713,8 @@ impl Helper {
|
|||
gui_api_output_raw: &mut String,
|
||||
sudo: &Arc<Mutex<SudoState>>,
|
||||
) -> bool {
|
||||
let signal = process.signal;
|
||||
if signal == ProcessSignal::Stop || signal == ProcessSignal::Restart {
|
||||
let signal = &process.signal;
|
||||
if *signal == ProcessSignal::Stop || *signal == ProcessSignal::Restart {
|
||||
debug!("XMRig Watchdog | Stop/Restart SIGNAL caught");
|
||||
// macOS requires [sudo] again to kill [XMRig]
|
||||
if cfg!(target_os = "macos") {
|
||||
|
@ -647,7 +724,7 @@ impl Helper {
|
|||
Self::sudo_kill(child_pty.lock().unwrap().process_id().unwrap(), sudo);
|
||||
// And... wipe it again (only if we're stopping full).
|
||||
// If we're restarting, the next start will wipe it for us.
|
||||
if signal != ProcessSignal::Restart {
|
||||
if *signal != ProcessSignal::Restart {
|
||||
SudoState::wipe(sudo);
|
||||
}
|
||||
} else if let Err(e) = child_pty.lock().unwrap().kill() {
|
||||
|
@ -700,11 +777,14 @@ impl Helper {
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [ImgXmrig]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImgXmrig {
|
||||
pub threads: String,
|
||||
pub url: String,
|
||||
pub api_port: u16,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
impl Default for ImgXmrig {
|
||||
|
@ -718,6 +798,8 @@ impl ImgXmrig {
|
|||
Self {
|
||||
threads: "???".to_string(),
|
||||
url: "???".to_string(),
|
||||
api_port: XMRIG_API_PORT_DEFAULT,
|
||||
token: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,7 +819,7 @@ pub struct PubXmrigApi {
|
|||
pub hashrate_raw: f32,
|
||||
pub hashrate_raw_1m: f32,
|
||||
pub hashrate_raw_15m: f32,
|
||||
pub node: String,
|
||||
pub pool: Option<Pool>,
|
||||
}
|
||||
|
||||
impl Default for PubXmrigApi {
|
||||
|
@ -760,7 +842,7 @@ impl PubXmrigApi {
|
|||
hashrate_raw: 0.0,
|
||||
hashrate_raw_1m: 0.0,
|
||||
hashrate_raw_15m: 0.0,
|
||||
node: UNKNOWN_DATA.to_string(),
|
||||
pool: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,12 +861,19 @@ impl PubXmrigApi {
|
|||
|
||||
// This combines the buffer from the PTY thread [output_pub]
|
||||
// with the actual [PubApiXmrig] output field.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn update_from_output(
|
||||
public: &mut Self,
|
||||
output_parse: &Arc<Mutex<String>>,
|
||||
output_pub: &Arc<Mutex<String>>,
|
||||
elapsed: std::time::Duration,
|
||||
process: &mut Process,
|
||||
process_p2pool: &Process,
|
||||
process_proxy: &Process,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
proxy_state: &XmrigProxy,
|
||||
p2pool_state: &P2pool,
|
||||
) {
|
||||
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
|
||||
let mut output_pub = output_pub.lock().unwrap();
|
||||
|
@ -803,12 +892,18 @@ impl PubXmrigApi {
|
|||
if XMRIG_REGEX.new_job.is_match(&output_parse) {
|
||||
process.state = ProcessState::Alive;
|
||||
// get the pool we mine on to put it on stats
|
||||
if let Some(name_pool) = crate::regex::detect_node_xmrig(&output_parse) {
|
||||
public.node = name_pool;
|
||||
if let Some(name_pool) = crate::regex::detect_pool_xmrig(
|
||||
&output_parse,
|
||||
proxy_state
|
||||
.current_ports(process_proxy, &proxy_img.lock().unwrap())
|
||||
.0,
|
||||
p2pool_state.current_port(process_p2pool, &p2pool_img.lock().unwrap()),
|
||||
) {
|
||||
public.pool = Some(name_pool);
|
||||
}
|
||||
} else if XMRIG_REGEX.not_mining.is_match(&output_parse) {
|
||||
process.state = ProcessState::NotMining;
|
||||
public.node = NO_POOL.to_string();
|
||||
public.pool = None;
|
||||
}
|
||||
|
||||
// 3. Throw away [output_parse]
|
||||
|
@ -896,3 +991,24 @@ struct Connection {
|
|||
accepted: u128,
|
||||
rejected: u128,
|
||||
}
|
||||
|
||||
// get the API port that would be used if xmrig was started with the current settings
|
||||
// pub fn get_xmrig_api_port(xmrig_state: &Xmrig) -> u16 {
|
||||
// if xmrig_state.simple {
|
||||
// XMRIG_API_PORT_DEFAULT
|
||||
// } else if !xmrig_state.arguments.is_empty() {
|
||||
// let mut last = "";
|
||||
// for arg in xmrig_state.arguments.split_whitespace() {
|
||||
// if last == "--http-host" {
|
||||
// return last.parse().unwrap_or(XMRIG_API_PORT_DEFAULT);
|
||||
// }
|
||||
// last = arg;
|
||||
// }
|
||||
// return XMRIG_API_PORT_DEFAULT;
|
||||
// } else {
|
||||
// return xmrig_state
|
||||
// .api_port
|
||||
// .parse()
|
||||
// .unwrap_or(XMRIG_API_PORT_DEFAULT);
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -21,6 +21,7 @@ use reqwest::header::AUTHORIZATION;
|
|||
use reqwest_middleware::ClientWithMiddleware as Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Write;
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
path::Path,
|
||||
sync::{Arc, Mutex},
|
||||
|
@ -29,36 +30,42 @@ use std::{
|
|||
};
|
||||
use tokio::spawn;
|
||||
|
||||
use crate::disk::state::StartOptionsMode;
|
||||
use crate::disk::state::{P2pool, StartOptionsMode, XmrigProxy};
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::xrig::current_api_url_xrig;
|
||||
use crate::human::{HumanNumber, HumanTime};
|
||||
use crate::miscs::client;
|
||||
use crate::{
|
||||
GUPAX_VERSION_UNDERSCORE, UNKNOWN_DATA,
|
||||
disk::state::Xmrig,
|
||||
GUPAX_VERSION_UNDERSCORE,
|
||||
helper::{
|
||||
Helper, Process, ProcessName, ProcessSignal, ProcessState, check_died, check_user_input,
|
||||
signal_end, sleep_end_loop,
|
||||
xrig::update_xmrig_config,
|
||||
xvb::{PubXvbApi, nodes::XvbNode},
|
||||
xvb::{PubXvbApi, nodes::Pool},
|
||||
},
|
||||
macros::{arc_mut, sleep},
|
||||
miscs::output_console,
|
||||
regex::{XMRIG_REGEX, contains_timeout, contains_usepool, detect_new_node_xmrig},
|
||||
regex::{XMRIG_REGEX, contains_timeout, contains_usepool, detect_pool_xmrig},
|
||||
};
|
||||
use crate::{NO_POOL, XMRIG_CONFIG_URL, XMRIG_PROXY_SUMMARY_URL};
|
||||
use crate::{PROXY_API_PORT_DEFAULT, PROXY_PORT_DEFAULT, XMRIG_API_SUMMARY_ENDPOINT};
|
||||
|
||||
use super::xmrig::PubXmrigApi;
|
||||
use super::xmrig::{ImgXmrig, PubXmrigApi};
|
||||
impl Helper {
|
||||
// Takes in some [State/XmrigProxy] and parses it to build the actual command arguments.
|
||||
// Returns the [Vec] of actual arguments,
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn read_pty_xp(
|
||||
output_parse: Arc<Mutex<String>>,
|
||||
output_pub: Arc<Mutex<String>>,
|
||||
reader: Box<dyn std::io::Read + Send>,
|
||||
process_xvb: Arc<Mutex<Process>>,
|
||||
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
process_p2pool: Arc<Mutex<Process>>,
|
||||
p2pool_state: &P2pool,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
proxy_state: &XmrigProxy,
|
||||
) {
|
||||
use std::io::BufRead;
|
||||
let mut stdout = std::io::BufReader::new(reader).lines();
|
||||
|
@ -86,35 +93,47 @@ impl Helper {
|
|||
// only switch nodes of XvB if XvB process is used
|
||||
if process_xvb.lock().unwrap().is_alive() {
|
||||
if contains_timeout(&line) {
|
||||
let current_node = pub_api_xvb.lock().unwrap().current_node;
|
||||
let current_node = pub_api_xvb.lock().unwrap().current_pool.clone();
|
||||
if let Some(current_node) = current_node {
|
||||
// updating current node to None, will stop sending signal of FailedNode until new node is set
|
||||
// send signal to update node.
|
||||
warn!(
|
||||
"XMRig-Proxy PTY Parse | node is offline, sending signal to update nodes."
|
||||
);
|
||||
if current_node != XvbNode::P2pool {
|
||||
if current_node
|
||||
!= Pool::P2pool(p2pool_state.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
))
|
||||
{
|
||||
process_xvb.lock().unwrap().signal =
|
||||
ProcessSignal::UpdateNodes(current_node);
|
||||
ProcessSignal::UpdatePools(current_node);
|
||||
}
|
||||
pub_api_xvb.lock().unwrap().current_node = None;
|
||||
pub_api_xvb.lock().unwrap().current_pool = None;
|
||||
}
|
||||
}
|
||||
if contains_usepool(&line) {
|
||||
info!("XMRig-Proxy PTY Parse | new pool detected");
|
||||
// need to update current node because it was updated.
|
||||
// if custom node made by user, it is not supported because algo is deciding which node to use.
|
||||
|
||||
let node = detect_new_node_xmrig(&line);
|
||||
// the state of the process we are in will always be in sync with the image of settings with started with because it is cloned with the start of the process.
|
||||
let node = detect_pool_xmrig(
|
||||
&line,
|
||||
proxy_state.bind_port(),
|
||||
p2pool_state.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
),
|
||||
);
|
||||
if node.is_none() {
|
||||
warn!(
|
||||
"XMRig-Proxy PTY Parse | node is not understood, switching to backup."
|
||||
);
|
||||
// update with default will choose which XvB to prefer. Will update XvB to use p2pool.
|
||||
process_xvb.lock().unwrap().signal =
|
||||
ProcessSignal::UpdateNodes(XvbNode::default());
|
||||
ProcessSignal::UpdatePools(Pool::default());
|
||||
}
|
||||
pub_api_xvb.lock().unwrap().current_node = node;
|
||||
pub_api_xvb.lock().unwrap().current_pool = node;
|
||||
}
|
||||
}
|
||||
// println!("{}", line); // For debugging.
|
||||
|
@ -129,6 +148,7 @@ impl Helper {
|
|||
pub fn build_xp_args(
|
||||
state: &crate::disk::state::XmrigProxy,
|
||||
mode: StartOptionsMode,
|
||||
p2pool_stratum_port: u16,
|
||||
) -> Vec<String> {
|
||||
let mut args = Vec::with_capacity(500);
|
||||
let api_ip;
|
||||
|
@ -152,15 +172,15 @@ impl Helper {
|
|||
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(format!("127.0.0.1:{p2pool_stratum_port}")); // Local P2Pool (the default)
|
||||
args.push("-b".to_string());
|
||||
args.push("0.0.0.0:3355".to_string());
|
||||
args.push(format!("0.0.0.0:{}", PROXY_PORT_DEFAULT));
|
||||
args.push("--user".to_string());
|
||||
args.push(rig); // Rig name
|
||||
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
|
||||
args.push(PROXY_API_PORT_DEFAULT.to_string()); // HTTP API Port
|
||||
}
|
||||
StartOptionsMode::Advanced => {
|
||||
// XMRig doesn't understand [localhost]
|
||||
|
@ -175,18 +195,20 @@ impl Helper {
|
|||
state.api_ip.to_string()
|
||||
};
|
||||
api_port = if state.api_port.is_empty() {
|
||||
"18089".to_string()
|
||||
PROXY_API_PORT_DEFAULT.to_string()
|
||||
} else {
|
||||
state.api_port.to_string()
|
||||
};
|
||||
ip = if state.api_ip == "localhost" || state.ip.is_empty() {
|
||||
ip = if state.ip == "localhost" {
|
||||
"127.0.0.1".to_string()
|
||||
} else if state.ip.is_empty() {
|
||||
"0.0.0.0".to_string()
|
||||
} else {
|
||||
state.ip.to_string()
|
||||
};
|
||||
|
||||
port = if state.port.is_empty() {
|
||||
"3355".to_string()
|
||||
PROXY_PORT_DEFAULT.to_string()
|
||||
} else {
|
||||
state.port.to_string()
|
||||
};
|
||||
|
@ -221,6 +243,43 @@ impl Helper {
|
|||
args
|
||||
}
|
||||
|
||||
pub fn mutate_img_proxy(helper: &Arc<Mutex<Self>>, state: &crate::disk::state::XmrigProxy) {
|
||||
if state.simple {
|
||||
*helper.lock().unwrap().img_proxy.lock().unwrap() = ImgProxy::new();
|
||||
} 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 proxy_image = lock.img_proxy.lock().unwrap();
|
||||
for arg in state.arguments.split_whitespace() {
|
||||
match last {
|
||||
"--bind" | "-b" => {
|
||||
proxy_image.port = last
|
||||
.split(":")
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.parse()
|
||||
.unwrap_or(PROXY_PORT_DEFAULT);
|
||||
}
|
||||
"--http-host" => {
|
||||
proxy_image.api_port = last.parse().unwrap_or(PROXY_API_PORT_DEFAULT)
|
||||
}
|
||||
l if l.contains("--http-access-token=") => {
|
||||
proxy_image.token = l.split_once("=").unwrap().1.to_string();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
last = arg;
|
||||
}
|
||||
} else {
|
||||
*helper.lock().unwrap().img_proxy.lock().unwrap() = ImgProxy {
|
||||
api_port: state.api_port.parse().unwrap_or(PROXY_API_PORT_DEFAULT),
|
||||
port: state.port.parse().unwrap_or(PROXY_PORT_DEFAULT),
|
||||
token: state.token.clone(),
|
||||
};
|
||||
}
|
||||
}
|
||||
pub fn stop_xp(helper: &Arc<Mutex<Self>>) {
|
||||
info!("XMRig-Proxy | Attempting to stop...");
|
||||
helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Stop;
|
||||
|
@ -241,19 +300,16 @@ impl Helper {
|
|||
pub fn restart_xp(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state: &crate::disk::state::XmrigProxy,
|
||||
state_xmrig: &Xmrig,
|
||||
state_p2pool: &P2pool,
|
||||
path: &Path,
|
||||
) {
|
||||
info!("XMRig-Proxy | Attempting to restart...");
|
||||
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
|
||||
helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Restart;
|
||||
|
||||
let helper = Arc::clone(helper);
|
||||
let state = state.clone();
|
||||
let state_xmrig = state_xmrig.clone();
|
||||
let path = path.to_path_buf();
|
||||
// This thread lives to wait, start xmrig_proxy then die.
|
||||
thread::spawn(move || {
|
||||
thread::spawn(enc!((helper, state, state_p2pool, path)move || {
|
||||
while helper.lock().unwrap().xmrig_proxy.lock().unwrap().state != ProcessState::Waiting
|
||||
{
|
||||
warn!("XMRig-proxy | Want to restart but process is still alive, waiting...");
|
||||
|
@ -261,14 +317,14 @@ impl Helper {
|
|||
}
|
||||
// Ok, process is not alive, start the new one!
|
||||
info!("XMRig-Proxy | Old process seems dead, starting new one!");
|
||||
Self::start_xp(&helper, &state, &state_xmrig, &path);
|
||||
});
|
||||
Self::start_xp(&helper, &state, &state_p2pool, &path);
|
||||
}));
|
||||
info!("XMRig-Proxy | Restart ... OK");
|
||||
}
|
||||
pub fn start_xp(
|
||||
helper: &Arc<Mutex<Self>>,
|
||||
state_proxy: &crate::disk::state::XmrigProxy,
|
||||
state_xmrig: &Xmrig,
|
||||
state_p2pool: &P2pool,
|
||||
path: &Path,
|
||||
) {
|
||||
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
|
||||
|
@ -280,7 +336,15 @@ impl Helper {
|
|||
} else {
|
||||
StartOptionsMode::Advanced
|
||||
};
|
||||
let args = Self::build_xp_args(state_proxy, mode);
|
||||
|
||||
// get the stratum port of p2pool
|
||||
let process_p2pool = Arc::clone(&helper.lock().unwrap().p2pool);
|
||||
let p2pool_img = Arc::clone(&helper.lock().unwrap().img_p2pool);
|
||||
let p2pool_stratum_port =
|
||||
state_p2pool.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap());
|
||||
// store the data used for startup to make it available to the other processes.
|
||||
Helper::mutate_img_proxy(helper, state_proxy);
|
||||
let args = Self::build_xp_args(state_proxy, mode, p2pool_stratum_port);
|
||||
// Print arguments & user settings to console
|
||||
crate::disk::print_dash(&format!("XMRig-Proxy | Launch arguments: {:#?}", args));
|
||||
info!("XMRig-Proxy | Using path: [{}]", path.display());
|
||||
|
@ -292,11 +356,11 @@ impl Helper {
|
|||
let process_xvb = Arc::clone(&helper.lock().unwrap().xvb);
|
||||
let process_xmrig = Arc::clone(&helper.lock().unwrap().xmrig);
|
||||
let path = path.to_path_buf();
|
||||
let token = state_proxy.token.clone();
|
||||
let state_xmrig = state_xmrig.clone();
|
||||
let redirect_xmrig = state_proxy.redirect_local_xmrig;
|
||||
let state = state_proxy.clone();
|
||||
let state_p2pool = state_p2pool.clone();
|
||||
let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
|
||||
let pub_api_xmrig = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
|
||||
let xmrig_img = Arc::clone(&helper.lock().unwrap().img_xmrig);
|
||||
thread::spawn(move || {
|
||||
Self::spawn_xp_watchdog(
|
||||
&process,
|
||||
|
@ -304,13 +368,15 @@ impl Helper {
|
|||
&pub_api,
|
||||
args,
|
||||
path,
|
||||
&token,
|
||||
&state_xmrig,
|
||||
redirect_xmrig,
|
||||
&state,
|
||||
process_xvb,
|
||||
process_xmrig,
|
||||
&pub_api_xvb,
|
||||
&pub_api_xmrig,
|
||||
&xmrig_img,
|
||||
process_p2pool,
|
||||
&state_p2pool,
|
||||
&p2pool_img,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -323,13 +389,15 @@ impl Helper {
|
|||
pub_api: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||
args: Vec<String>,
|
||||
path: std::path::PathBuf,
|
||||
token_proxy: &str,
|
||||
state_xmrig: &Xmrig,
|
||||
xmrig_redirect: bool,
|
||||
state: &XmrigProxy,
|
||||
process_xvb: Arc<Mutex<Process>>,
|
||||
process_xmrig: Arc<Mutex<Process>>,
|
||||
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
pub_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
process_p2pool: Arc<Mutex<Process>>,
|
||||
p2pool_state: &P2pool,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
) {
|
||||
process.lock().unwrap().start = Instant::now();
|
||||
// spawn pty
|
||||
|
@ -348,9 +416,11 @@ impl Helper {
|
|||
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
|
||||
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
|
||||
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
|
||||
spawn(enc!((pub_api_xvb, output_parse, output_pub) async move {
|
||||
Self::read_pty_xp(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await;
|
||||
}));
|
||||
spawn(
|
||||
enc!((pub_api_xvb, output_parse, output_pub, process_p2pool, p2pool_state, p2pool_img, state) async move {
|
||||
Self::read_pty_xp(output_parse, output_pub, reader, process_xvb, &pub_api_xvb, process_p2pool, &p2pool_state, &p2pool_img, &state).await;
|
||||
}),
|
||||
);
|
||||
// 1b. Create command
|
||||
debug!("XMRig-Proxy | Creating command...");
|
||||
let mut cmd = portable_pty::cmdbuilder::CommandBuilder::new(path.clone());
|
||||
|
@ -362,8 +432,11 @@ impl Helper {
|
|||
drop(pair.slave);
|
||||
let mut stdin = pair.master.take_writer().unwrap();
|
||||
// to refactor to let user use his own ports
|
||||
let api_summary_xp = XMRIG_PROXY_SUMMARY_URL;
|
||||
let api_config_xmrig = XMRIG_CONFIG_URL;
|
||||
let api_summary_xp = format!(
|
||||
"http://127.0.0.1:{}/{}",
|
||||
state.api_port(),
|
||||
XMRIG_API_SUMMARY_ENDPOINT
|
||||
);
|
||||
|
||||
// set state
|
||||
let client = client();
|
||||
|
@ -393,6 +466,8 @@ impl Helper {
|
|||
error!("XMRig-Proxy Watchdog | STDIN error: {}", e);
|
||||
}
|
||||
info!("XMRig-Proxy | Entering watchdog mode... woof!");
|
||||
let mut last_redirect_request = Instant::now();
|
||||
let mut first_loop = true;
|
||||
loop {
|
||||
let now = Instant::now();
|
||||
debug!("XMRig-Proxy Watchdog | ----------- Start of loop -----------");
|
||||
|
@ -435,12 +510,17 @@ impl Helper {
|
|||
&output_parse,
|
||||
start.elapsed(),
|
||||
&mut process_lock,
|
||||
&process_p2pool.lock().unwrap(),
|
||||
p2pool_img,
|
||||
p2pool_state,
|
||||
state,
|
||||
);
|
||||
drop(pub_api_lock);
|
||||
drop(process_lock);
|
||||
// update data from api
|
||||
debug!("XMRig-Proxy Watchdog | Attempting HTTP API request...");
|
||||
match PrivXmrigProxyApi::request_xp_api(&client, api_summary_xp, token_proxy).await
|
||||
match PrivXmrigProxyApi::request_xp_api(&client, &api_summary_xp, &state.token)
|
||||
.await
|
||||
{
|
||||
Ok(priv_api) => {
|
||||
debug!(
|
||||
|
@ -456,18 +536,23 @@ impl Helper {
|
|||
}
|
||||
}
|
||||
// update xmrig to use xmrig-proxy if option enabled and local xmrig alive
|
||||
if xmrig_redirect
|
||||
&& pub_api_xmrig.lock().unwrap().node != XvbNode::XmrigProxy.to_string()
|
||||
// if the request was just sent, do not repeat it, let xmrig time to apply the change.
|
||||
let pool = Pool::XmrigProxy(state.bind_port()); // get current port of xmrig-proxy
|
||||
if (state.redirect_local_xmrig
|
||||
&& pub_api_xmrig.lock().unwrap().pool.as_ref() != Some(&pool)
|
||||
&& (process_xmrig.lock().unwrap().state == ProcessState::Alive
|
||||
|| process_xmrig.lock().unwrap().state == ProcessState::NotMining)
|
||||
|| process_xmrig.lock().unwrap().state == ProcessState::NotMining))
|
||||
&& (first_loop || last_redirect_request.elapsed() > Duration::from_secs(5))
|
||||
{
|
||||
last_redirect_request = Instant::now();
|
||||
info!("redirect local xmrig instance to xmrig-proxy");
|
||||
let node = XvbNode::XmrigProxy;
|
||||
let api_uri =
|
||||
current_api_url_xrig(true, Some(&xmrig_img.lock().unwrap()), None);
|
||||
if let Err(err) = update_xmrig_config(
|
||||
&client,
|
||||
api_config_xmrig,
|
||||
&state_xmrig.token,
|
||||
&node,
|
||||
&api_uri,
|
||||
&xmrig_img.lock().unwrap().token,
|
||||
&pool,
|
||||
"",
|
||||
GUPAX_VERSION_UNDERSCORE,
|
||||
)
|
||||
|
@ -490,6 +575,9 @@ impl Helper {
|
|||
} // locked are dropped here
|
||||
// do not use more than 1 second for the loop
|
||||
sleep_end_loop(now, ProcessName::XmrigProxy).await;
|
||||
if first_loop {
|
||||
first_loop = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. If loop broke, we must be done here.
|
||||
|
@ -497,6 +585,29 @@ impl Helper {
|
|||
// sleep
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------- [ImgProxy]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ImgProxy {
|
||||
pub api_port: u16,
|
||||
pub port: u16,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
impl Default for ImgProxy {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ImgProxy {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
api_port: PROXY_API_PORT_DEFAULT,
|
||||
port: PROXY_PORT_DEFAULT,
|
||||
token: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PubXmrigProxyApi {
|
||||
|
@ -511,7 +622,7 @@ pub struct PubXmrigProxyApi {
|
|||
pub hashrate_12h: f32,
|
||||
pub hashrate_24h: f32,
|
||||
pub miners: u16,
|
||||
pub node: String,
|
||||
pub pool: Option<Pool>,
|
||||
}
|
||||
|
||||
impl Default for PubXmrigProxyApi {
|
||||
|
@ -533,15 +644,20 @@ impl PubXmrigProxyApi {
|
|||
hashrate_12h: 0.0,
|
||||
hashrate_24h: 0.0,
|
||||
miners: 0,
|
||||
node: UNKNOWN_DATA.to_string(),
|
||||
pool: None,
|
||||
}
|
||||
}
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn update_from_output(
|
||||
public: &mut Self,
|
||||
output_parse: &Arc<Mutex<String>>,
|
||||
output_pub: &Arc<Mutex<String>>,
|
||||
elapsed: std::time::Duration,
|
||||
process: &mut Process,
|
||||
process_p2pool: &Process,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
p2pool_state: &P2pool,
|
||||
state: &XmrigProxy,
|
||||
) {
|
||||
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
|
||||
let mut output_pub = output_pub.lock().unwrap();
|
||||
|
@ -562,15 +678,19 @@ impl PubXmrigProxyApi {
|
|||
{
|
||||
process.state = ProcessState::Alive;
|
||||
// get the pool we mine on to put it on stats
|
||||
if let Some(name_pool) = crate::regex::detect_node_xmrig(&output_parse) {
|
||||
public.node = name_pool;
|
||||
if let Some(name_pool) = detect_pool_xmrig(
|
||||
&output_parse,
|
||||
state.bind_port(),
|
||||
p2pool_state.current_port(process_p2pool, &p2pool_img.lock().unwrap()),
|
||||
) {
|
||||
public.pool = Some(name_pool);
|
||||
}
|
||||
} else if XMRIG_REGEX.timeout.is_match(&output_parse)
|
||||
|| XMRIG_REGEX.invalid_conn.is_match(&output_parse)
|
||||
|| XMRIG_REGEX.error.is_match(&output_parse)
|
||||
{
|
||||
process.state = ProcessState::NotMining;
|
||||
public.node = NO_POOL.to_string();
|
||||
public.pool = None;
|
||||
}
|
||||
// 3. Throw away [output_parse]
|
||||
output_parse.clear();
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::XVB_MIN_TIME_SEND;
|
||||
use crate::helper::Process;
|
||||
use crate::helper::p2pool::ImgP2pool;
|
||||
use crate::helper::xrig::current_api_url_xrig;
|
||||
use crate::helper::xrig::xmrig::ImgXmrig;
|
||||
use crate::helper::xrig::xmrig_proxy::ImgProxy;
|
||||
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
use crate::helper::xvb::api_url_xmrig;
|
||||
use crate::helper::xvb::current_controllable_hr;
|
||||
use crate::miscs::output_console;
|
||||
use crate::miscs::output_console_without_time;
|
||||
|
@ -38,7 +42,7 @@ use crate::{
|
|||
helper::{
|
||||
p2pool::PubP2poolApi,
|
||||
xrig::{update_xmrig_config, xmrig::PubXmrigApi},
|
||||
xvb::{nodes::XvbNode, priv_stats::RuntimeMode},
|
||||
xvb::{nodes::Pool, priv_stats::RuntimeMode},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -52,14 +56,22 @@ pub(crate) async fn algorithm(
|
|||
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
||||
gui_api_xp: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||
gui_api_p2pool: &Arc<Mutex<PubP2poolApi>>,
|
||||
token_xmrig: &str,
|
||||
state_p2pool: &crate::disk::state::P2pool,
|
||||
share: u32,
|
||||
time_donated: &Arc<Mutex<u32>>,
|
||||
rig: &str,
|
||||
xp_alive: bool,
|
||||
p2pool_buffer: i8,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
p2pool_process: &Arc<Mutex<Process>>,
|
||||
) {
|
||||
let token_xmrig = if xp_alive {
|
||||
proxy_img.lock().unwrap().token.clone()
|
||||
} else {
|
||||
xmrig_img.lock().unwrap().token.clone()
|
||||
};
|
||||
let mut algorithm = Algorithm::new(
|
||||
client,
|
||||
pub_api,
|
||||
|
@ -67,13 +79,17 @@ pub(crate) async fn algorithm(
|
|||
gui_api_xmrig,
|
||||
gui_api_xp,
|
||||
gui_api_p2pool,
|
||||
token_xmrig,
|
||||
&token_xmrig,
|
||||
state_p2pool,
|
||||
share,
|
||||
time_donated,
|
||||
rig,
|
||||
xp_alive,
|
||||
p2pool_buffer,
|
||||
proxy_img,
|
||||
xmrig_img,
|
||||
p2pool_img,
|
||||
p2pool_process,
|
||||
);
|
||||
algorithm.run().await;
|
||||
}
|
||||
|
@ -92,6 +108,8 @@ pub struct Algorithm<'a> {
|
|||
rig: &'a str,
|
||||
xp_alive: bool,
|
||||
pub stats: Stats,
|
||||
p2pool_img: &'a Arc<Mutex<ImgP2pool>>,
|
||||
p2pool_process: &'a Arc<Mutex<Process>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -134,6 +152,10 @@ impl<'a> Algorithm<'a> {
|
|||
rig: &'a str,
|
||||
xp_alive: bool,
|
||||
p2pool_buffer: i8,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
p2pool_img: &'a Arc<Mutex<ImgP2pool>>,
|
||||
p2pool_process: &'a Arc<Mutex<Process>>,
|
||||
) -> Self {
|
||||
let use_sidechain_hr = gui_api_xvb.lock().unwrap().use_p2pool_sidechain_hr;
|
||||
let hashrate_xmrig = current_controllable_hr(xp_alive, gui_api_xp, gui_api_xmrig);
|
||||
|
@ -175,7 +197,11 @@ impl<'a> Algorithm<'a> {
|
|||
|
||||
let spareable_hashrate = hashrate_xmrig - share_min_hashrate;
|
||||
|
||||
let api_url = api_url_xmrig(xp_alive, true);
|
||||
let api_url = if xp_alive {
|
||||
current_api_url_xrig(true, None, Some(&proxy_img.lock().unwrap()))
|
||||
} else {
|
||||
current_api_url_xrig(true, Some(&xmrig_img.lock().unwrap()), None)
|
||||
};
|
||||
|
||||
let msg_xmrig_or_xp = (if xp_alive { "XMRig-Proxy" } else { "XMRig" }).to_string();
|
||||
info!("xp alive: {:?}", xp_alive);
|
||||
|
@ -224,6 +250,8 @@ impl<'a> Algorithm<'a> {
|
|||
rig,
|
||||
xp_alive,
|
||||
stats,
|
||||
p2pool_img,
|
||||
p2pool_process,
|
||||
};
|
||||
// external XvB HR is taken into account with get_target_donation_hashrate so the needed time is calculating how much time is needed from local sparable HR only
|
||||
new_instance.stats.target_donation_hashrate =
|
||||
|
@ -267,12 +295,15 @@ impl<'a> Algorithm<'a> {
|
|||
}
|
||||
|
||||
async fn target_p2pool_node(&self) {
|
||||
if self.gui_api_xvb.lock().unwrap().current_node != Some(XvbNode::P2pool) {
|
||||
let node = Pool::P2pool(self.state_p2pool.current_port(
|
||||
&self.p2pool_process.lock().unwrap(),
|
||||
&self.p2pool_img.lock().unwrap(),
|
||||
));
|
||||
if self.gui_api_xvb.lock().unwrap().current_pool != Some(node.clone()) {
|
||||
info!(
|
||||
"Algorithm | request {} to mine on p2pool",
|
||||
self.stats.msg_xmrig_or_xp
|
||||
);
|
||||
let node = XvbNode::P2pool;
|
||||
if let Err(err) = update_xmrig_config(
|
||||
self.client,
|
||||
&self.stats.api_url,
|
||||
|
@ -305,27 +336,32 @@ impl<'a> Algorithm<'a> {
|
|||
}
|
||||
|
||||
async fn target_xvb_node(&self) {
|
||||
let node = self.gui_api_xvb.lock().unwrap().stats_priv.node;
|
||||
let pool = self.gui_api_xvb.lock().unwrap().stats_priv.pool.clone();
|
||||
|
||||
info!(
|
||||
"Algorithm | request {} to mine on XvB",
|
||||
self.stats.msg_xmrig_or_xp
|
||||
);
|
||||
|
||||
if self.gui_api_xvb.lock().unwrap().current_node.is_none()
|
||||
if self.gui_api_xvb.lock().unwrap().current_pool.is_none()
|
||||
|| self
|
||||
.gui_api_xvb
|
||||
.lock()
|
||||
.unwrap()
|
||||
.current_node
|
||||
.current_pool
|
||||
.as_ref()
|
||||
.is_some_and(|n| n == &XvbNode::P2pool)
|
||||
.is_some_and(|n| {
|
||||
n == &Pool::P2pool(self.state_p2pool.current_port(
|
||||
&self.p2pool_process.lock().unwrap(),
|
||||
&self.p2pool_img.lock().unwrap(),
|
||||
))
|
||||
})
|
||||
{
|
||||
if let Err(err) = update_xmrig_config(
|
||||
self.client,
|
||||
&self.stats.api_url,
|
||||
self.token_xmrig,
|
||||
&node,
|
||||
&pool,
|
||||
&self.stats.address,
|
||||
"",
|
||||
)
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::helper::xrig::update_xmrig_config;
|
||||
use crate::helper::xrig::{current_api_url_xrig, update_xmrig_config};
|
||||
use crate::helper::xvb::algorithm::algorithm;
|
||||
use crate::helper::xvb::priv_stats::XvbPrivStats;
|
||||
use crate::helper::xvb::public_stats::XvbPubStats;
|
||||
use crate::helper::{ProcessName, sleep_end_loop};
|
||||
use crate::miscs::{client, output_console};
|
||||
use crate::{XMRIG_CONFIG_URL, XMRIG_PROXY_CONFIG_URL, XMRIG_PROXY_SUMMARY_URL, XMRIG_SUMMARY_URL};
|
||||
use bounded_vec_deque::BoundedVecDeque;
|
||||
use enclose::enc;
|
||||
use log::{debug, info, warn};
|
||||
|
@ -44,11 +43,11 @@ use crate::{
|
|||
utils::macros::sleep,
|
||||
};
|
||||
|
||||
use self::nodes::XvbNode;
|
||||
use self::nodes::Pool;
|
||||
|
||||
use super::p2pool::PubP2poolApi;
|
||||
use super::xrig::xmrig::PubXmrigApi;
|
||||
use super::xrig::xmrig_proxy::PubXmrigProxyApi;
|
||||
use super::p2pool::{ImgP2pool, PubP2poolApi};
|
||||
use super::xrig::xmrig::{ImgXmrig, PubXmrigApi};
|
||||
use super::xrig::xmrig_proxy::{ImgProxy, PubXmrigProxyApi};
|
||||
use super::{Helper, Process};
|
||||
|
||||
pub mod algorithm;
|
||||
|
@ -116,6 +115,11 @@ impl Helper {
|
|||
// ex: read hashrate values from gui, update node to pub.
|
||||
let gui_api_xmrig = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
|
||||
let gui_api_xp = Arc::clone(&helper.lock().unwrap().gui_api_xp);
|
||||
// get the value with which xmrig and proxy started.
|
||||
let img_xmrig = Arc::clone(&helper.lock().unwrap().img_xmrig);
|
||||
let img_proxy = Arc::clone(&helper.lock().unwrap().img_proxy);
|
||||
let img_p2pool = Arc::clone(&helper.lock().unwrap().img_p2pool);
|
||||
|
||||
// Reset before printing to output.
|
||||
// Need to reset because values of stats would stay otherwise which could bring confusion even if panel is with a disabled theme.
|
||||
// at the start of a process, values must be default.
|
||||
|
@ -140,7 +144,7 @@ impl Helper {
|
|||
|
||||
info!("XvB | spawn watchdog");
|
||||
thread::spawn(
|
||||
enc!((state_xvb, state_p2pool, state_xmrig, state_xmrig,state_xp) move || {
|
||||
enc!((state_xvb, state_p2pool, state_xmrig, state_xmrig,state_xp, img_xmrig, img_proxy, img_p2pool) move || {
|
||||
// thread priority, else there are issue on windows but it is also good for other OS
|
||||
Self::spawn_xvb_watchdog(
|
||||
&gui_api,
|
||||
|
@ -156,6 +160,10 @@ impl Helper {
|
|||
&process_xmrig,
|
||||
&gui_api_xp,
|
||||
&process_xp,
|
||||
&img_xmrig,
|
||||
&img_proxy,
|
||||
&img_p2pool,
|
||||
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
@ -177,6 +185,11 @@ impl Helper {
|
|||
process_xmrig: &Arc<Mutex<Process>>,
|
||||
gui_api_xp: &Arc<Mutex<PubXmrigProxyApi>>,
|
||||
process_xp: &Arc<Mutex<Process>>,
|
||||
// get the current http port of xmrig
|
||||
// This port could be changed by the user without restarting xvb
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
) {
|
||||
// create uniq client that is going to be used for during the life of the thread.
|
||||
let client = client();
|
||||
|
@ -248,6 +261,9 @@ impl Helper {
|
|||
state_xmrig,
|
||||
state_xp,
|
||||
xp_alive,
|
||||
xmrig_img,
|
||||
proxy_img,
|
||||
p2pool_img,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
@ -258,6 +274,7 @@ impl Helper {
|
|||
if signal_interrupt(
|
||||
process,
|
||||
if xp_alive { process_xp } else { process_xmrig },
|
||||
process_p2pool,
|
||||
start.into(),
|
||||
&client,
|
||||
pub_api,
|
||||
|
@ -266,6 +283,9 @@ impl Helper {
|
|||
state_xmrig,
|
||||
state_xp,
|
||||
xp_alive,
|
||||
xmrig_img,
|
||||
proxy_img,
|
||||
p2pool_img,
|
||||
) {
|
||||
info!("XvB Watchdog | Signal has stopped the loop");
|
||||
break;
|
||||
|
@ -305,7 +325,7 @@ impl Helper {
|
|||
// first_loop is false here but could be changed to true under some conditions.
|
||||
// will send a stop signal if public stats failed or update data with new one.
|
||||
*handle_request.lock().unwrap() = Some(spawn(
|
||||
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, gui_api_xp, state_xvb, state_p2pool, state_xmrig, state_xp, process, last_algorithm, retry, handle_algo, time_donated, last_request) async move {
|
||||
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, gui_api_xp, state_xvb, state_p2pool, state_xmrig, process, last_algorithm, retry, handle_algo, time_donated, last_request, proxy_img, xmrig_img, process_p2pool, p2pool_img) async move {
|
||||
// needs to wait here for public stats to get private stats.
|
||||
if last_request_expired || first_loop || should_refresh_before_next_algo {
|
||||
XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await;
|
||||
|
@ -348,12 +368,7 @@ impl Helper {
|
|||
*retry.lock().unwrap() = false;
|
||||
// reset instant because algo will start.
|
||||
*last_algorithm.lock().unwrap() = Instant::now();
|
||||
*handle_algo.lock().unwrap() = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, state_xp, time_donated, state_xvb) async move {
|
||||
let token_xmrig = if xp_alive {
|
||||
&state_xp.token
|
||||
} else {
|
||||
&state_xmrig.token
|
||||
};
|
||||
*handle_algo.lock().unwrap() = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, time_donated, state_xvb, proxy_img, xmrig_img, p2pool_img, process_p2pool) async move {
|
||||
let rig = if xp_alive {
|
||||
""
|
||||
} else {
|
||||
|
@ -366,13 +381,16 @@ impl Helper {
|
|||
&gui_api_xmrig,
|
||||
&gui_api_xp,
|
||||
&gui_api_p2pool,
|
||||
token_xmrig,
|
||||
&state_p2pool,
|
||||
share,
|
||||
&time_donated,
|
||||
rig,
|
||||
xp_alive,
|
||||
state_xvb.p2pool_buffer
|
||||
state_xvb.p2pool_buffer,
|
||||
&proxy_img,
|
||||
&xmrig_img,
|
||||
&p2pool_img,
|
||||
&process_p2pool
|
||||
).await;
|
||||
})));
|
||||
} else {
|
||||
|
@ -440,7 +458,7 @@ pub struct PubXvbApi {
|
|||
// where xmrig is mining right now (or trying to).
|
||||
// will be updated by output of xmrig.
|
||||
// could also be retrieved by fetching current config.
|
||||
pub current_node: Option<XvbNode>,
|
||||
pub current_pool: Option<Pool>,
|
||||
// Instead of watching stratum data that will account for HR sent only on this p2pool node,
|
||||
// Take the value of estimated HR that will account for external miners mininf on the same address.
|
||||
pub use_p2pool_sidechain_hr: bool,
|
||||
|
@ -523,7 +541,7 @@ async fn check_conditions_for_start(
|
|||
);
|
||||
ProcessState::NotMining
|
||||
} else if process_p2pool.lock().unwrap().state != ProcessState::Alive {
|
||||
info!("XvB | verify p2pool node");
|
||||
info!("XvB | verify p2pool pool");
|
||||
// send to console: p2pool process is not running
|
||||
warn!("Xvb | Start ... Partially failed because P2pool instance is not ready.");
|
||||
let msg = if process_p2pool.lock().unwrap().state == ProcessState::Syncing {
|
||||
|
@ -549,7 +567,7 @@ async fn check_conditions_for_start(
|
|||
ProcessState::Syncing
|
||||
} else {
|
||||
// all test passed, so it can be Alive
|
||||
// stay at middle, updateNodes will finish by syncing or offlinenodes and check_status in loop will change state accordingly.
|
||||
// stay at middle, updatePools will finish by syncing or offlinenodes and check_status in loop will change state accordingly.
|
||||
ProcessState::Middle
|
||||
};
|
||||
if state != ProcessState::Middle {
|
||||
|
@ -561,8 +579,8 @@ async fn check_conditions_for_start(
|
|||
ProcessName::Xvb,
|
||||
);
|
||||
}
|
||||
// will update the preferred node for the first loop, even if partially started.
|
||||
process_xvb.lock().unwrap().signal = ProcessSignal::UpdateNodes(XvbNode::default());
|
||||
// will update the preferred pool for the first loop, even if partially started.
|
||||
process_xvb.lock().unwrap().signal = ProcessSignal::UpdatePools(Pool::default());
|
||||
process_xvb.lock().unwrap().state = state;
|
||||
}
|
||||
/// return a bool to continue to next loop if needed.
|
||||
|
@ -581,6 +599,9 @@ async fn check_state_outcauses_xvb(
|
|||
state_xmrig: &crate::disk::state::Xmrig,
|
||||
state_xp: &crate::disk::state::XmrigProxy,
|
||||
xp_start_alive: bool,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
) -> bool {
|
||||
// will check if the state can stay as it is.
|
||||
// p2pool and xmrig are alive if ready and running (syncing is not alive).
|
||||
|
@ -609,7 +630,11 @@ async fn check_state_outcauses_xvb(
|
|||
ProcessName::Xvb,
|
||||
);
|
||||
// only update xmrig if it is alive and wasn't on p2pool already.
|
||||
if gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool)
|
||||
if gui_api.lock().unwrap().current_pool
|
||||
!= Some(Pool::P2pool(state_p2pool.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
)))
|
||||
&& (process_xmrig.lock().unwrap().state == ProcessState::Alive || xp_is_alive)
|
||||
{
|
||||
let token_xmrig = if xp_is_alive {
|
||||
|
@ -623,37 +648,52 @@ async fn check_state_outcauses_xvb(
|
|||
} else {
|
||||
state_xmrig.rig.clone()
|
||||
};
|
||||
spawn(enc!((client, gui_api) async move {
|
||||
let url_api = api_url_xmrig(xp_is_alive, true);
|
||||
let node = XvbNode::P2pool;
|
||||
if let Err(err) = update_xmrig_config(
|
||||
&client,
|
||||
&url_api,
|
||||
&token_xmrig,
|
||||
&node,
|
||||
&address,
|
||||
&rig
|
||||
)
|
||||
.await
|
||||
{
|
||||
// show to console error about updating xmrig config
|
||||
output_console(
|
||||
&mut gui_api.lock().unwrap().output,
|
||||
&format!(
|
||||
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
|
||||
err
|
||||
),
|
||||
ProcessName::Xvb
|
||||
);
|
||||
} else {
|
||||
output_console(
|
||||
&mut gui_api.lock().unwrap().output,
|
||||
&format!("XvB process can not completely continue, falling back to {}", XvbNode::P2pool),
|
||||
ProcessName::Xvb
|
||||
);
|
||||
}
|
||||
spawn(
|
||||
enc!((client, gui_api, xmrig_img, proxy_img, process_p2pool, p2pool_img, state_p2pool) async move {
|
||||
|
||||
}));
|
||||
let url_api = if xp_is_alive {
|
||||
current_api_url_xrig(true, None, Some(&proxy_img.lock().unwrap()) )
|
||||
} else {
|
||||
current_api_url_xrig(true, Some(&xmrig_img.lock().unwrap()), None)
|
||||
};
|
||||
let pool = Pool::P2pool(state_p2pool.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
));
|
||||
if let Err(err) = update_xmrig_config(
|
||||
&client,
|
||||
&url_api,
|
||||
&token_xmrig,
|
||||
&pool,
|
||||
&address,
|
||||
&rig
|
||||
)
|
||||
.await
|
||||
{
|
||||
// show to console error about updating xmrig config
|
||||
output_console(
|
||||
&mut gui_api.lock().unwrap().output,
|
||||
&format!(
|
||||
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
|
||||
err
|
||||
),
|
||||
ProcessName::Xvb
|
||||
);
|
||||
} else {
|
||||
let pool =
|
||||
Pool::P2pool(state_p2pool.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
));
|
||||
output_console(
|
||||
&mut gui_api.lock().unwrap().output,
|
||||
&format!("XvB process can not completely continue, falling back to {}", pool),
|
||||
ProcessName::Xvb
|
||||
);
|
||||
}
|
||||
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,7 +712,7 @@ async fn check_state_outcauses_xvb(
|
|||
ProcessState::Alive if !p2pool_xmrig_alive => {
|
||||
// they are not both alives, so state will be at syncing and data reset, state of loop also.
|
||||
warn!(
|
||||
"XvB | stopped partially because P2pool node or xmrig/xmrig-proxy are not reachable."
|
||||
"XvB | stopped partially because P2pool pool or xmrig/xmrig-proxy are not reachable."
|
||||
);
|
||||
// stats must be empty put to default so the UI reflect that XvB private is not running.
|
||||
reset_data_xvb(pub_api, gui_api);
|
||||
|
@ -680,7 +720,7 @@ async fn check_state_outcauses_xvb(
|
|||
*first_loop = true;
|
||||
output_console(
|
||||
&mut gui_api.lock().unwrap().output,
|
||||
"XvB is now partially stopped because p2pool node or XMRig/XMRig-Proxy came offline.\nCheck P2pool and Xmrig/Xmrig-Proxy Tabs",
|
||||
"XvB is now partially stopped because p2pool pool or XMRig/XMRig-Proxy came offline.\nCheck P2pool and Xmrig/Xmrig-Proxy Tabs",
|
||||
ProcessName::Xvb,
|
||||
);
|
||||
output_console(
|
||||
|
@ -692,7 +732,7 @@ async fn check_state_outcauses_xvb(
|
|||
}
|
||||
ProcessState::Syncing if p2pool_xmrig_alive => {
|
||||
info!("XvB | started this time with p2pool and xmrig");
|
||||
// will put state on middle and update nodes
|
||||
// will put state on middle and update pools
|
||||
process.lock().unwrap().state = ProcessState::Alive;
|
||||
reset_data_xvb(pub_api, gui_api);
|
||||
*first_loop = true;
|
||||
|
@ -716,6 +756,7 @@ async fn check_state_outcauses_xvb(
|
|||
fn signal_interrupt(
|
||||
process: &Arc<Mutex<Process>>,
|
||||
process_xrig: &Arc<Mutex<Process>>,
|
||||
process_p2pool: &Arc<Mutex<Process>>,
|
||||
start: Instant,
|
||||
client: &Client,
|
||||
pub_api: &Arc<Mutex<PubXvbApi>>,
|
||||
|
@ -724,12 +765,15 @@ fn signal_interrupt(
|
|||
state_xmrig: &crate::disk::state::Xmrig,
|
||||
state_xp: &crate::disk::state::XmrigProxy,
|
||||
xp_alive: bool,
|
||||
xmrig_img: &Arc<Mutex<ImgXmrig>>,
|
||||
proxy_img: &Arc<Mutex<ImgProxy>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
) -> bool {
|
||||
// Check SIGNAL
|
||||
// check if STOP or RESTART Signal is given.
|
||||
// if STOP, will put Signal to None, if Restart to Wait
|
||||
// in either case, will break from loop.
|
||||
let signal = process.lock().unwrap().signal;
|
||||
let signal = process.lock().unwrap().signal.clone();
|
||||
match signal {
|
||||
ProcessSignal::Stop => {
|
||||
debug!("P2Pool Watchdog | Stop SIGNAL caught");
|
||||
|
@ -763,9 +807,9 @@ fn signal_interrupt(
|
|||
reset_data_xvb(pub_api, gui_api);
|
||||
return true;
|
||||
}
|
||||
ProcessSignal::UpdateNodes(node) => {
|
||||
ProcessSignal::UpdatePools(pool) => {
|
||||
if process.lock().unwrap().state != ProcessState::Waiting {
|
||||
warn!("received the UpdateNode signal");
|
||||
warn!("received the UpdatePool signal");
|
||||
let token_xmrig = if xp_alive {
|
||||
state_xp.token.clone()
|
||||
} else {
|
||||
|
@ -777,54 +821,61 @@ fn signal_interrupt(
|
|||
state_xmrig.rig.clone()
|
||||
};
|
||||
let address = state_p2pool.address.clone();
|
||||
// check if state is alive. If it is and it is receiving such a signal, it means something a node (XvB or P2Pool) has failed.
|
||||
// if XvB, xmrig needs to be switch to the other node (both will be checked though to be sure).
|
||||
// if both XvB nodes fail after checking, process will be partially stopped and a new spawn will verify if nodes are again online and so will continue the process completely if that's the case.
|
||||
// check if state is alive. If it is and it is receiving such a signal, it means something a pool (XvB or P2Pool) has failed.
|
||||
// if XvB, xmrig needs to be switch to the other pool (both will be checked though to be sure).
|
||||
// if both XvB pools fail after checking, process will be partially stopped and a new spawn will verify if pools are again online and so will continue the process completely if that's the case.
|
||||
// if P2pool, the process has to stop the algo and continue partially. The process will continue completely if the confitions are met again.
|
||||
// if XvB was not alive, then if it is for XvB nodes, it will check and update preferred node and set XMRig to P2pool if that's not the case.
|
||||
// if XvB was not alive, then if it is for XvB pools, it will check and update preferred pool and set XMRig to P2pool if that's not the case.
|
||||
let was_alive = process.lock().unwrap().state == ProcessState::Alive;
|
||||
// so it won't execute another signal of update nodes if it is already doing it.
|
||||
// so it won't execute another signal of update pools if it is already doing it.
|
||||
process.lock().unwrap().state = ProcessState::Waiting;
|
||||
process.lock().unwrap().signal = ProcessSignal::None;
|
||||
spawn(
|
||||
enc!((node, process, client, gui_api, pub_api, was_alive, address, token_xmrig, process_xrig) async move {
|
||||
match node {
|
||||
XvbNode::NorthAmerica|XvbNode::Europe if was_alive => {
|
||||
// a node is failing. We need to first verify if a node is available
|
||||
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
|
||||
if process.lock().unwrap().state == ProcessState::OfflineNodesAll {
|
||||
// No available nodes, so launch a process to verify periodically.
|
||||
enc!((pool, process, client, gui_api, pub_api, was_alive, address, token_xmrig, process_xrig, xmrig_img, proxy_img, process_p2pool, state_p2pool, p2pool_img) async move {
|
||||
match pool {
|
||||
Pool::XvBNorthAmerica|Pool::XvBEurope if was_alive => {
|
||||
// a pool is failing. We need to first verify if a pool is available
|
||||
Pool::update_fastest_pool(&client, &gui_api, &pub_api, &process, &process_p2pool, &p2pool_img, &state_p2pool).await;
|
||||
if process.lock().unwrap().state == ProcessState::OfflinePoolsAll {
|
||||
// No available pools, so launch a process to verify periodically.
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
warn!("node fail, set spawn that will retry nodes and update state.");
|
||||
while process.lock().unwrap().state == ProcessState::OfflineNodesAll {
|
||||
// this spawn will stay alive until nodes are joignable or XvB process is stopped or failed.
|
||||
XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await;
|
||||
warn!("pool fail, set spawn that will retry pools and update state.");
|
||||
while process.lock().unwrap().state == ProcessState::OfflinePoolsAll {
|
||||
// this spawn will stay alive until pools are joignable or XvB process is stopped or failed.
|
||||
Pool::update_fastest_pool(&client, &pub_api, &gui_api, &process, &process_p2pool, &p2pool_img, &state_p2pool).await;
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
|
||||
}
|
||||
// a good node is found, so the next check of the loop should be good and the algo will update XMRig with the good one.
|
||||
// a good pool is found, so the next check of the loop should be good and the algo will update XMRig with the good one.
|
||||
|
||||
|
||||
},
|
||||
XvbNode::NorthAmerica|XvbNode::Europe if !was_alive => {
|
||||
Pool::XvBNorthAmerica|Pool::XvBEurope if !was_alive => {
|
||||
process.lock().unwrap().state = ProcessState::Syncing;
|
||||
// Probably a start. We don't consider XMRig using XvB nodes without algo.
|
||||
// Probably a start. We don't consider XMRig using XvB pools without algo.
|
||||
// can update xmrig and check status of state in the same time.
|
||||
// update prefred node
|
||||
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
|
||||
// update prefred pool
|
||||
Pool::update_fastest_pool(&client, &pub_api, &gui_api, &process, &process_p2pool, &p2pool_img, &state_p2pool).await;
|
||||
// Need to set XMRig to P2Pool if it wasn't. XMRig should have populated this value at his start.
|
||||
// but if xmrig didn't start, don't update it.
|
||||
|
||||
if process_xrig.lock().unwrap().state == ProcessState::Alive && gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool) {
|
||||
spawn(enc!((client, token_xmrig, address, gui_api) async move{
|
||||
let url_api = api_url_xmrig(xp_alive, true);
|
||||
let node = XvbNode::P2pool;
|
||||
let p2pool_pool = Pool::P2pool(state_p2pool.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
));
|
||||
if process_xrig.lock().unwrap().state == ProcessState::Alive && gui_api.lock().unwrap().current_pool != Some(p2pool_pool.clone()) {
|
||||
spawn(enc!((client, token_xmrig, address, xmrig_img, proxy_img, gui_api) async move{
|
||||
let url_api = if xp_alive {
|
||||
current_api_url_xrig(true, None, Some(&proxy_img.lock().unwrap()) )
|
||||
} else {
|
||||
current_api_url_xrig(true, Some(&xmrig_img.lock().unwrap()), None)
|
||||
};
|
||||
if let Err(err) = update_xmrig_config(
|
||||
&client,
|
||||
&url_api,
|
||||
&token_xmrig,
|
||||
&node,
|
||||
&p2pool_pool,
|
||||
&address,
|
||||
&rig
|
||||
)
|
||||
|
@ -856,7 +907,7 @@ fn signal_interrupt(
|
|||
false
|
||||
}
|
||||
fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) {
|
||||
let current_node = mem::take(&mut pub_api.lock().unwrap().current_node.clone());
|
||||
let current_pool = mem::take(&mut pub_api.lock().unwrap().current_pool.clone());
|
||||
// even if it is a restart, we want to keep set values by the user without the need from him to click on save button.
|
||||
let runtime_mode = mem::take(&mut gui_api.lock().unwrap().stats_priv.runtime_mode);
|
||||
let runtime_manual_amount =
|
||||
|
@ -866,7 +917,7 @@ fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi
|
|||
*pub_api.lock().unwrap() = PubXvbApi::new();
|
||||
*gui_api.lock().unwrap() = PubXvbApi::new();
|
||||
// to keep the value modified by xmrig even if xvb is dead.
|
||||
pub_api.lock().unwrap().current_node = current_node;
|
||||
pub_api.lock().unwrap().current_pool = current_pool;
|
||||
// to not loose the information of runtime hero mode between restart
|
||||
gui_api.lock().unwrap().stats_priv.runtime_mode = runtime_mode;
|
||||
gui_api.lock().unwrap().stats_priv.runtime_manual_amount = runtime_manual_amount;
|
||||
|
@ -888,13 +939,13 @@ fn update_indicator_algo(
|
|||
&& !is_algo_finished
|
||||
&& process.lock().unwrap().state == ProcessState::Alive
|
||||
{
|
||||
let node = pub_api.lock().unwrap().current_node;
|
||||
let msg_indicator = match node {
|
||||
Some(XvbNode::P2pool) if time_donated > 0 && time_donated != XVB_TIME_ALGO => {
|
||||
let pool = pub_api.lock().unwrap().current_pool.clone();
|
||||
let msg_indicator = match pool {
|
||||
Some(Pool::P2pool(_)) if time_donated > 0 && time_donated != XVB_TIME_ALGO => {
|
||||
// algo is mining on p2pool but will switch to XvB after
|
||||
// show time remaining on p2pool
|
||||
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_pool = XVB_TIME_ALGO
|
||||
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
|
||||
.unwrap_or_default()
|
||||
.checked_sub(time_donated)
|
||||
|
@ -905,7 +956,7 @@ fn update_indicator_algo(
|
|||
// algo is mining on XvB or complelty mining on p2pool.
|
||||
// show remaining time before next decision of algo
|
||||
// because time of last algorithm could depass a little bit XVB_TIME_ALGO before next run, check the sub.
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_pool = XVB_TIME_ALGO
|
||||
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
|
||||
.unwrap_or_default();
|
||||
"time until next decision of algorithm".to_string()
|
||||
|
@ -914,27 +965,11 @@ fn update_indicator_algo(
|
|||
pub_api.lock().unwrap().stats_priv.msg_indicator = msg_indicator;
|
||||
} else {
|
||||
// if algo is not running or process not alive
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_node = 0;
|
||||
pub_api.lock().unwrap().stats_priv.time_switch_pool = 0;
|
||||
pub_api.lock().unwrap().stats_priv.msg_indicator = "Algorithm is not running".to_string();
|
||||
}
|
||||
}
|
||||
|
||||
// quick temporary function before refactor, but better than repeating this code
|
||||
// if xp is alive, put true
|
||||
// to get config url, true. False for summary
|
||||
pub fn api_url_xmrig(xp: bool, config: bool) -> String {
|
||||
if xp {
|
||||
if config {
|
||||
XMRIG_PROXY_CONFIG_URL.to_string()
|
||||
} else {
|
||||
XMRIG_PROXY_SUMMARY_URL.to_string()
|
||||
}
|
||||
} else if config {
|
||||
XMRIG_CONFIG_URL.to_string()
|
||||
} else {
|
||||
XMRIG_SUMMARY_URL.to_string()
|
||||
}
|
||||
}
|
||||
// get the current HR of xmrig or xmrig-proxy
|
||||
// will get a longer average HR since it will be more accurate. Shorter timeframe can induce volatility.
|
||||
fn current_controllable_hr(
|
||||
|
|
|
@ -28,108 +28,139 @@ use tokio::spawn;
|
|||
use crate::{
|
||||
GUPAX_VERSION_UNDERSCORE, XVB_NODE_EU, XVB_NODE_NA, XVB_NODE_PORT, XVB_NODE_RPC,
|
||||
components::node::{GetInfo, TIMEOUT_NODE_PING},
|
||||
helper::{Process, ProcessName, ProcessState, xvb::output_console},
|
||||
disk::state::P2pool,
|
||||
helper::{Process, ProcessName, ProcessState, p2pool::ImgP2pool, xvb::output_console},
|
||||
};
|
||||
|
||||
use super::PubXvbApi;
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Display)]
|
||||
pub enum XvbNode {
|
||||
#[display("XvB North America Node")]
|
||||
NorthAmerica,
|
||||
#[derive(Clone, Debug, Default, PartialEq, Display)]
|
||||
pub enum Pool {
|
||||
#[display("XvB North America Pool")]
|
||||
XvBNorthAmerica,
|
||||
#[default]
|
||||
#[display("XvB European Node")]
|
||||
Europe,
|
||||
#[display("XvB European Pool")]
|
||||
XvBEurope,
|
||||
#[display("Local P2pool")]
|
||||
P2pool,
|
||||
P2pool(u16),
|
||||
#[display("Xmrig Proxy")]
|
||||
XmrigProxy,
|
||||
XmrigProxy(u16),
|
||||
#[display("Custom Pool")]
|
||||
Custom(String, u16),
|
||||
#[display("Not connected to any pool")]
|
||||
Unknown,
|
||||
}
|
||||
impl XvbNode {
|
||||
impl Pool {
|
||||
pub fn url(&self) -> String {
|
||||
match self {
|
||||
Self::NorthAmerica => String::from(XVB_NODE_NA),
|
||||
Self::Europe => String::from(XVB_NODE_EU),
|
||||
Self::P2pool => String::from("127.0.0.1"),
|
||||
Self::XmrigProxy => String::from("127.0.0.1"),
|
||||
Self::XvBNorthAmerica => String::from(XVB_NODE_NA),
|
||||
Self::XvBEurope => String::from(XVB_NODE_EU),
|
||||
Self::P2pool(_) => String::from("127.0.0.1"),
|
||||
Self::XmrigProxy(_) => String::from("127.0.0.1"),
|
||||
Self::Custom(url, _) => url.clone(),
|
||||
_ => "???".to_string(),
|
||||
}
|
||||
}
|
||||
pub fn port(&self) -> String {
|
||||
match self {
|
||||
Self::NorthAmerica | Self::Europe => String::from(XVB_NODE_PORT),
|
||||
Self::P2pool => String::from("3333"),
|
||||
Self::XmrigProxy => String::from("3355"),
|
||||
Self::XvBNorthAmerica | Self::XvBEurope => String::from(XVB_NODE_PORT),
|
||||
Self::P2pool(port) => port.to_string(),
|
||||
Self::XmrigProxy(port) => port.to_string(),
|
||||
Self::Custom(_, port) => port.to_string(),
|
||||
_ => "???".to_string(),
|
||||
}
|
||||
}
|
||||
pub fn user(&self, address: &str) -> String {
|
||||
match self {
|
||||
Self::NorthAmerica => address.chars().take(8).collect(),
|
||||
Self::Europe => address.chars().take(8).collect(),
|
||||
Self::P2pool => GUPAX_VERSION_UNDERSCORE.to_string(),
|
||||
Self::XmrigProxy => GUPAX_VERSION_UNDERSCORE.to_string(),
|
||||
Self::XvBNorthAmerica => address.chars().take(8).collect(),
|
||||
Self::XvBEurope => address.chars().take(8).collect(),
|
||||
_ => GUPAX_VERSION_UNDERSCORE.to_string(),
|
||||
}
|
||||
}
|
||||
pub fn tls(&self) -> bool {
|
||||
match self {
|
||||
Self::NorthAmerica => true,
|
||||
Self::Europe => true,
|
||||
Self::P2pool => false,
|
||||
Self::XmrigProxy => false,
|
||||
Self::XvBNorthAmerica => true,
|
||||
Self::XvBEurope => true,
|
||||
Self::P2pool(_) => false,
|
||||
Self::XmrigProxy(_) => false,
|
||||
Self::Custom(_, _) => false,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn keepalive(&self) -> bool {
|
||||
match self {
|
||||
Self::NorthAmerica => true,
|
||||
Self::Europe => true,
|
||||
Self::P2pool => false,
|
||||
Self::XmrigProxy => false,
|
||||
Self::XvBNorthAmerica => true,
|
||||
Self::XvBEurope => true,
|
||||
Self::P2pool(_) => false,
|
||||
Self::XmrigProxy(_) => false,
|
||||
Self::Custom(_, _) => false,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_fastest_node(
|
||||
pub async fn update_fastest_pool(
|
||||
client: &Client,
|
||||
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
gui_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||
process_xvb: &Arc<Mutex<Process>>,
|
||||
process_p2pool: &Arc<Mutex<Process>>,
|
||||
p2pool_img: &Arc<Mutex<ImgP2pool>>,
|
||||
p2pool_state: &P2pool,
|
||||
) {
|
||||
let client_eu = client.clone();
|
||||
let client_na = client.clone();
|
||||
// two spawn to ping the two nodes in parallel and not one after the other.
|
||||
let ms_eu = spawn(async move {
|
||||
info!("Node | ping European XvB Node");
|
||||
XvbNode::ping(&XvbNode::Europe.url(), &client_eu).await
|
||||
info!("Node | ping XvBEuropean XvB Node");
|
||||
Pool::ping(&Pool::XvBEurope.url(), &client_eu).await
|
||||
});
|
||||
let ms_na = spawn(async move {
|
||||
info!("Node | ping North America Node");
|
||||
XvbNode::ping(&XvbNode::NorthAmerica.url(), &client_na).await
|
||||
Pool::ping(&Pool::XvBNorthAmerica.url(), &client_na).await
|
||||
});
|
||||
let node = if let Ok(ms_eu) = ms_eu.await {
|
||||
let pool = if let Ok(ms_eu) = ms_eu.await {
|
||||
if let Ok(ms_na) = ms_na.await {
|
||||
// if two nodes are up, compare ping latency and return fastest.
|
||||
if ms_na != TIMEOUT_NODE_PING && ms_eu != TIMEOUT_NODE_PING {
|
||||
if ms_na < ms_eu {
|
||||
XvbNode::NorthAmerica
|
||||
Pool::XvBNorthAmerica
|
||||
} else {
|
||||
XvbNode::Europe
|
||||
Pool::XvBEurope
|
||||
}
|
||||
} else if ms_na != TIMEOUT_NODE_PING && ms_eu == TIMEOUT_NODE_PING {
|
||||
// if only na is online, return it.
|
||||
XvbNode::NorthAmerica
|
||||
Pool::XvBNorthAmerica
|
||||
} else if ms_na == TIMEOUT_NODE_PING && ms_eu != TIMEOUT_NODE_PING {
|
||||
// if only eu is online, return it.
|
||||
XvbNode::Europe
|
||||
Pool::XvBEurope
|
||||
} else {
|
||||
// if P2pool is returned, it means none of the two nodes are available.
|
||||
XvbNode::P2pool
|
||||
Pool::P2pool(
|
||||
p2pool_state.current_port(
|
||||
&process_p2pool.lock().unwrap(),
|
||||
&p2pool_img.lock().unwrap(),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
error!("ping has failed !");
|
||||
XvbNode::P2pool
|
||||
Pool::P2pool(
|
||||
p2pool_state
|
||||
.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap()),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
error!("ping has failed !");
|
||||
XvbNode::P2pool
|
||||
Pool::P2pool(
|
||||
p2pool_state
|
||||
.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap()),
|
||||
)
|
||||
};
|
||||
if node == XvbNode::P2pool {
|
||||
if pool
|
||||
== Pool::P2pool(
|
||||
p2pool_state
|
||||
.current_port(&process_p2pool.lock().unwrap(), &p2pool_img.lock().unwrap()),
|
||||
)
|
||||
{
|
||||
// if both nodes are dead, then the state of the process must be NodesOffline
|
||||
info!("XvB node ping, all offline or ping failed, switching back to local p2pool",);
|
||||
output_console(
|
||||
|
@ -137,13 +168,13 @@ impl XvbNode {
|
|||
"XvB node ping, all offline or ping failed, switching back to local p2pool",
|
||||
ProcessName::Xvb,
|
||||
);
|
||||
process_xvb.lock().unwrap().state = ProcessState::OfflineNodesAll;
|
||||
process_xvb.lock().unwrap().state = ProcessState::OfflinePoolsAll;
|
||||
} else {
|
||||
// if node is up and because update_fastest is used only if token/address is valid, it means XvB process is Alive.
|
||||
info!("XvB node ping, both online and best is {}", node.url());
|
||||
info!("XvB node ping, both online and best is {}", pool.url());
|
||||
output_console(
|
||||
&mut gui_api_xvb.lock().unwrap().output,
|
||||
&format!("XvB node ping, {} is selected as the fastest.", node),
|
||||
&format!("XvB Pool ping, {} is selected as the fastest.", pool),
|
||||
ProcessName::Xvb,
|
||||
);
|
||||
info!("ProcessState to Syncing after finding joinable node");
|
||||
|
@ -154,7 +185,7 @@ impl XvbNode {
|
|||
process_xvb.lock().unwrap().state = ProcessState::Syncing;
|
||||
}
|
||||
}
|
||||
pub_api_xvb.lock().unwrap().stats_priv.node = node;
|
||||
pub_api_xvb.lock().unwrap().stats_priv.pool = pool;
|
||||
}
|
||||
async fn ping(ip: &str, client: &Client) -> u128 {
|
||||
let request = client
|
||||
|
|
|
@ -36,7 +36,7 @@ use crate::{
|
|||
helper::{Process, ProcessName, ProcessState, xvb::output_console},
|
||||
};
|
||||
|
||||
use super::{PubXvbApi, nodes::XvbNode, rounds::XvbRound};
|
||||
use super::{PubXvbApi, nodes::Pool, rounds::XvbRound};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)]
|
||||
pub enum RuntimeMode {
|
||||
|
@ -78,11 +78,11 @@ pub struct XvbPrivStats {
|
|||
#[serde(skip)]
|
||||
pub round_participate: Option<XvbRound>,
|
||||
#[serde(skip)]
|
||||
pub node: XvbNode,
|
||||
pub pool: Pool,
|
||||
#[serde(skip)]
|
||||
// it is the time remaining before switching from P2pool to XvB or XvB to P2ool.
|
||||
// it is not the time remaining of the algo, even if it could be the same if never mining on XvB.
|
||||
pub time_switch_node: u32,
|
||||
pub time_switch_pool: u32,
|
||||
#[serde(skip)]
|
||||
pub msg_indicator: String,
|
||||
#[serde(skip)]
|
||||
|
|
12
src/inits.rs
12
src/inits.rs
|
@ -1,4 +1,6 @@
|
|||
use crate::components::update::{Update, check_binary_path};
|
||||
#[cfg(not(feature = "distro"))]
|
||||
use crate::components::update::Update;
|
||||
use crate::components::update::check_binary_path;
|
||||
use crate::errors::process_running;
|
||||
use crate::helper::{Helper, ProcessName, ProcessSignal};
|
||||
use crate::utils::constants::{
|
||||
|
@ -202,12 +204,12 @@ pub fn init_auto(app: &mut App) {
|
|||
"Gupaxx | P2pool instance is already running outside of Gupaxx ! Skipping auto-node..."
|
||||
);
|
||||
} else {
|
||||
let backup_hosts = app.gather_backup_hosts();
|
||||
Helper::start_p2pool(
|
||||
&app.helper,
|
||||
&app.state.p2pool,
|
||||
&app.state.node,
|
||||
&app.state.gupax.absolute_p2pool_path,
|
||||
backup_hosts,
|
||||
app.backup_hosts.clone(),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
@ -234,6 +236,8 @@ pub fn init_auto(app: &mut App) {
|
|||
Helper::start_xmrig(
|
||||
&app.helper,
|
||||
&app.state.xmrig,
|
||||
&app.state.p2pool,
|
||||
&app.state.xmrig_proxy,
|
||||
&app.state.gupax.absolute_xmrig_path,
|
||||
Arc::clone(&app.sudo),
|
||||
);
|
||||
|
@ -263,7 +267,7 @@ pub fn init_auto(app: &mut App) {
|
|||
Helper::start_xp(
|
||||
&app.helper,
|
||||
&app.state.xmrig_proxy,
|
||||
&app.state.xmrig,
|
||||
&app.state.p2pool,
|
||||
&app.state.gupax.absolute_xp_path,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -92,14 +92,8 @@ pub const P2POOL_API_PATH_NETWORK: &str = "network/stats";
|
|||
pub const P2POOL_API_PATH_POOL: &str = "pool/stats";
|
||||
#[cfg(target_family = "unix")]
|
||||
pub const P2POOL_API_PATH_P2P: &str = "local/p2p";
|
||||
pub const XMRIG_API_SUMMARY_URI: &str = "1/summary"; // The default relative URI of XMRig's API summary
|
||||
// pub const XMRIG_API_CONFIG_URI: &str = "1/config"; // The default relative URI of XMRig's API config
|
||||
// todo allow user to change the port of the http api for xmrig and xmrig-proxy
|
||||
pub const XMRIG_CONFIG_URL: &str = "http://127.0.0.1:18088/1/config"; // The default relative URI of XMRig's API config
|
||||
pub const XMRIG_PROXY_CONFIG_URL: &str = "http://127.0.0.1:18089/1/config"; // The default relative URI of XMRig Proxy's API config
|
||||
pub const XMRIG_SUMMARY_URL: &str = "http://127.0.0.1:18088/1/summary"; // The default relative URI of XMRig's API config
|
||||
pub const XMRIG_PROXY_SUMMARY_URL: &str = "http://127.0.0.1:18089/1/summary"; // The default relative URI of XMRig Proxy's API config
|
||||
pub const NO_POOL: &str = "Not connected to any pool"; // status tab xrig if no pool is used
|
||||
pub const XMRIG_API_SUMMARY_ENDPOINT: &str = "1/summary"; // The default relative URI of XMRig's API summary
|
||||
pub const XMRIG_API_CONFIG_ENDPOINT: &str = "1/config"; // The default relative URI of XMRig's API config
|
||||
|
||||
// Process state tooltips (online, offline, etc)
|
||||
pub const P2POOL_ALIVE: &str = "P2Pool is online and fully synchronized";
|
||||
|
@ -148,9 +142,9 @@ pub const STATUS_XMRIG_PROXY_POOL: &str = "The pool XMRig-Proxy is currently min
|
|||
pub const STATUS_XMRIG_PROXY_HASHRATE: &str = "The average hashrate of XMRig-Proxy";
|
||||
|
||||
pub const XVB_ALIVE: &str =
|
||||
"XvB process is configured and distributing hashrate, XvB node is online";
|
||||
"XvB process is configured and distributing hashrate, XvB pool is online";
|
||||
pub const XVB_DEAD: &str = "XvB process is offline";
|
||||
pub const XVB_FAILED: &str = "XvB process is misconfigured or the XvB node is offline";
|
||||
pub const XVB_FAILED: &str = "XvB process is misconfigured or the XvB pool is offline";
|
||||
pub const XVB_MIDDLE: &str = "XvB is in the middle of (re)starting/stopping";
|
||||
pub const XVB_NOT_CONFIGURED: &str = "You need to insert an existent token before starting XvB";
|
||||
pub const XVB_PUBLIC_ONLY: &str = "XvB process is started only to get public stats.";
|
||||
|
@ -383,6 +377,7 @@ pub const GUPAX_PATH_XMRIG: &str = "The location of the XMRig binary: Both absol
|
|||
pub const GUPAX_PATH_XMRIG_PROXY: &str = "The location of the XMRig-Proxy binary: Both absolute and relative paths are accepted; A red [X] will appear if there is no file found at the given path";
|
||||
|
||||
// P2Pool
|
||||
pub const P2POOL_PORT_DEFAULT: u16 = 3333;
|
||||
pub const P2POOL_MAIN: &str = "Use the P2Pool main-chain. This P2Pool finds blocks faster, but has a higher difficulty. Suitable for miners with more than 50kH/s";
|
||||
pub const P2POOL_MINI: &str = "Use the P2Pool mini-chain. This P2Pool finds blocks slower, but has a lower difficulty. Suitable for miners with less than 50kH/s";
|
||||
pub const P2POOL_OUT: &str = "How many out-bound peers to connect to? (you connecting to others)";
|
||||
|
@ -444,6 +439,8 @@ 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_RPC_PORT_DEFAULT: u16 = 18081;
|
||||
pub const NODE_ZMQ_PORT_DEFAULT: u16 = 18083;
|
||||
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))]
|
||||
|
@ -480,6 +477,7 @@ pub const NODE_API_PORT: &str = "RPC API listen port";
|
|||
pub const NODE_ZMQ_BIND: &str = "bind address of ZMQ API";
|
||||
pub const NODE_ZMQ_PORT: &str = "ZMQ API listen port";
|
||||
// XMRig
|
||||
pub const XMRIG_API_PORT_DEFAULT: u16 = 18088;
|
||||
pub const XMRIG_SIMPLE: &str = r#"Use simple XMRig settings:
|
||||
- Mine to local P2Pool (localhost:3333)
|
||||
- CPU thread slider
|
||||
|
@ -517,6 +515,8 @@ pub const XMRIG_PATH_NOT_VALID: &str = "XMRig binary at the given PATH in the Gu
|
|||
pub const XMRIG_PATH_OK: &str = "XMRig was found at the given PATH";
|
||||
pub const XMRIG_PATH_EMPTY: &str = "XMRig PATH is empty! To fix: goto the [GupaxxAdvanced] tab, select [Open] and specify where XMRig is located.";
|
||||
pub const XMRIG_PROXY_URL: &str = "https://github.com/xmrig/xmrig-proxy";
|
||||
pub const PROXY_API_PORT_DEFAULT: u16 = 18089;
|
||||
pub const PROXY_PORT_DEFAULT: u16 = 3355;
|
||||
|
||||
// XvB
|
||||
pub const XVB_HELP: &str = "You need to register an account by clicking on the link above to get your token with the same p2pool XMR address you use for payment.";
|
||||
|
@ -559,6 +559,9 @@ pub const XVB_ROUND_DONOR_VIP_MIN_HR: u32 = 10000;
|
|||
pub const XVB_ROUND_DONOR_WHALE_MIN_HR: u32 = 100000;
|
||||
pub const XVB_ROUND_DONOR_MEGA_MIN_HR: u32 = 1000000;
|
||||
|
||||
// Common help
|
||||
pub const HELP_STRATUM_PORT: &str = "Specify the stratum port to bind to";
|
||||
pub const HELP_STRATUM_IP: &str = "Specify the stratum ip to bind to";
|
||||
// Manual Mode
|
||||
pub const XVB_MODE_MANUAL_XVB_HELP: &str = "Manually set the amount to donate to XmrVsBeast, If value is more than xmrig hashrate it might be changed";
|
||||
pub const XVB_MODE_MANUAL_P2POOL_HELP: &str = "Manually set the amount to keep on P2pool, If value is more than xmrig hashrate it might be changed";
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
|
||||
// Some regexes used throughout Gupax.
|
||||
|
||||
use crate::helper::xvb::nodes::Pool;
|
||||
use log::{error, warn};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::helper::xvb::nodes::XvbNode;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Lazy
|
||||
pub static REGEXES: Lazy<Regexes> = Lazy::new(Regexes::new);
|
||||
pub static P2POOL_REGEX: Lazy<P2poolRegex> = Lazy::new(P2poolRegex::new);
|
||||
|
@ -157,26 +156,41 @@ pub fn nb_current_shares(s: &str) -> Option<u32> {
|
|||
}
|
||||
None
|
||||
}
|
||||
pub fn detect_new_node_xmrig(s: &str) -> Option<XvbNode> {
|
||||
static CURRENT_SHARE: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"use pool (?P<pool>.*?) ").unwrap());
|
||||
pub fn detect_pool_xmrig(s: &str, proxy_port: u16, p2pool_port: u16) -> Option<Pool> {
|
||||
static CURRENT_SHARE: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new(
|
||||
r"(use pool|new job from) (?P<pool>(?:[0-9]{1,3}\.){3}[0-9]{1,3}:\d{1,5})(| diff)",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
if let Some(c) = CURRENT_SHARE.captures(s) {
|
||||
if let Some(m) = c.name("pool") {
|
||||
match m.as_str() {
|
||||
// if user change address of local p2pool, it could create issue
|
||||
"127.0.0.1:3333" => {
|
||||
return Some(XvbNode::P2pool);
|
||||
}
|
||||
"127.0.0.1:3355" => {
|
||||
return Some(XvbNode::XmrigProxy);
|
||||
x if x.contains("127.0.0.1") => {
|
||||
let port = x.split_once(":").unwrap_or_default().1.parse::<u16>();
|
||||
if let Ok(port) = port {
|
||||
if port == proxy_port {
|
||||
return Some(Pool::XmrigProxy(port));
|
||||
}
|
||||
if port == p2pool_port {
|
||||
return Some(Pool::P2pool(port));
|
||||
}
|
||||
return Some(Pool::Custom("127.0.0.1".to_string(), port));
|
||||
}
|
||||
}
|
||||
"eu.xmrvsbeast.com:4247" => {
|
||||
return Some(XvbNode::Europe);
|
||||
return Some(Pool::XvBEurope);
|
||||
}
|
||||
"na.xmrvsbeast.com:4247" => {
|
||||
return Some(XvbNode::NorthAmerica);
|
||||
return Some(Pool::XvBNorthAmerica);
|
||||
}
|
||||
x => {
|
||||
let (ip, port) = x.split_once(":").unwrap_or_default();
|
||||
if let Ok(port) = port.parse() {
|
||||
return Some(Pool::Custom(ip.to_string(), port));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,28 +199,6 @@ pub fn detect_new_node_xmrig(s: &str) -> Option<XvbNode> {
|
|||
);
|
||||
None
|
||||
}
|
||||
// this detection removes the need to update pub_api.node everytime xmrig/proxy are updated to mine to another p2pool node.
|
||||
pub fn detect_node_xmrig(s: &str) -> Option<String> {
|
||||
static CURRENT_SHARE: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"new job from (?P<pool>.*?) diff").unwrap());
|
||||
if let Some(c) = CURRENT_SHARE.captures(s) {
|
||||
if let Some(m) = c.name("pool") {
|
||||
// let's make nicer name appear on status tab
|
||||
let name = match m.as_str() {
|
||||
"127.0.0.1:3333" => XvbNode::P2pool.to_string(),
|
||||
"127.0.0.1:3355" => XvbNode::XmrigProxy.to_string(),
|
||||
"eu.xmrvsbeast.com:4247" => XvbNode::Europe.to_string(),
|
||||
"na.xmrvsbeast.com:4247" => XvbNode::NorthAmerica.to_string(),
|
||||
x => x.to_string(),
|
||||
};
|
||||
return Some(name);
|
||||
}
|
||||
}
|
||||
warn!(
|
||||
"a line on xmrig console was detected as using a new pool but the syntax was not recognized or it was not a pool useable for the algorithm."
|
||||
);
|
||||
None
|
||||
}
|
||||
pub fn estimated_hr(s: &str) -> Option<f32> {
|
||||
static CURRENT_SHARE: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new(r"(?P<nb>[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?) (?P<unit>.*)H/s").unwrap()
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
|
||||
use crate::{
|
||||
constants::*,
|
||||
disk::state::Xmrig,
|
||||
disk::state::{P2pool, Xmrig, XmrigProxy},
|
||||
helper::{Helper, ProcessSignal},
|
||||
};
|
||||
use enclose::enc;
|
||||
use log::*;
|
||||
use std::{
|
||||
io::Write,
|
||||
|
@ -116,12 +117,12 @@ impl SudoState {
|
|||
state: Arc<Mutex<Self>>,
|
||||
helper: &Arc<Mutex<Helper>>,
|
||||
xmrig: &Xmrig,
|
||||
p2pool: &P2pool,
|
||||
proxy: &XmrigProxy,
|
||||
path: &Path,
|
||||
) {
|
||||
let helper = Arc::clone(helper);
|
||||
let xmrig = xmrig.clone();
|
||||
let path = path.to_path_buf();
|
||||
thread::spawn(move || {
|
||||
thread::spawn(enc!((helper, xmrig, p2pool, proxy) move || {
|
||||
// Set to testing
|
||||
state.lock().unwrap().testing = true;
|
||||
|
||||
|
@ -192,6 +193,8 @@ impl SudoState {
|
|||
ProcessSignal::Restart => crate::helper::Helper::restart_xmrig(
|
||||
&helper,
|
||||
&xmrig,
|
||||
&p2pool,
|
||||
&proxy,
|
||||
&path,
|
||||
Arc::clone(&state),
|
||||
),
|
||||
|
@ -199,6 +202,8 @@ impl SudoState {
|
|||
_ => crate::helper::Helper::start_xmrig(
|
||||
&helper,
|
||||
&xmrig,
|
||||
&p2pool,
|
||||
&proxy,
|
||||
&path,
|
||||
Arc::clone(&state),
|
||||
),
|
||||
|
@ -209,6 +214,6 @@ impl SudoState {
|
|||
}
|
||||
state.lock().unwrap().signal = ProcessSignal::None;
|
||||
state.lock().unwrap().testing = false;
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue