mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-11-16 15:27:46 +00:00
feat: beta release 0.1.8
fix: algorithm time too short under some conditions fix: countdown too short under some conditions fix: request api stuck after some time fix: average local HR sent not saved feat: better manage fail of nodes from XvB
This commit is contained in:
parent
755fe234cd
commit
70250775ec
8 changed files with 173 additions and 140 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,3 +1,20 @@
|
||||||
|
# v0.1.8
|
||||||
|
Fix release for beta version.
|
||||||
|
This version is only made for testing purposes and have feedback.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
### Internal
|
||||||
|
Better manage fail of nodes from XvB
|
||||||
|
## Fixes
|
||||||
|
Algorithm time too short under some conditions.
|
||||||
|
Countdown too short under some conditions
|
||||||
|
Request API stuck after some time
|
||||||
|
Average local HR sent not saved
|
||||||
|
|
||||||
|
## Bundled Versions
|
||||||
|
* [`P2Pool v3.10`](https://github.com/SChernykh/p2pool/releases/tag/v3.10)
|
||||||
|
* [`XMRig v6.21.1`](https://github.com/xmrig/xmrig/releases/tag/v6.21.1)
|
||||||
|
|
||||||
# v0.1.7
|
# v0.1.7
|
||||||
Fix release for beta version.
|
Fix release for beta version.
|
||||||
This version is only made for testing purposes and have feedback.
|
This version is only made for testing purposes and have feedback.
|
||||||
|
|
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1144,9 +1144,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-graphics"
|
name = "core-graphics"
|
||||||
version = "0.23.1"
|
version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212"
|
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
|
@ -2084,7 +2084,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gupaxx"
|
name = "gupaxx"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"benri",
|
"benri",
|
||||||
|
@ -2131,9 +2131,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
|
checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
cargo-features = ["profile-rustflags"]
|
cargo-features = ["profile-rustflags"]
|
||||||
[package]
|
[package]
|
||||||
name = "gupaxx"
|
name = "gupaxx"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
authors = ["cyrix126 <gupaxx@baermail.fr>"]
|
authors = ["cyrix126 <gupaxx@baermail.fr>"]
|
||||||
description = "Fork of Gupax integrating the XMRvsBeast Raffle "
|
description = "Fork of Gupax integrating the XMRvsBeast Raffle "
|
||||||
documentation = "https://github.com/cyrix126/gupaxx"
|
documentation = "https://github.com/cyrix126/gupaxx"
|
||||||
|
|
|
@ -48,7 +48,7 @@ use std::{
|
||||||
time::*,
|
time::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::xvb::PubXvbApi;
|
use self::xvb::{nodes::XvbNode, PubXvbApi};
|
||||||
pub mod p2pool;
|
pub mod p2pool;
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
pub mod xmrig;
|
pub mod xmrig;
|
||||||
|
@ -218,13 +218,13 @@ impl Default for ProcessState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub enum ProcessSignal {
|
pub enum ProcessSignal {
|
||||||
None,
|
None,
|
||||||
Start,
|
Start,
|
||||||
Stop,
|
Stop,
|
||||||
Restart,
|
Restart,
|
||||||
UpdateNodes,
|
UpdateNodes(XvbNode),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProcessSignal {
|
impl Default for ProcessSignal {
|
||||||
|
|
|
@ -60,11 +60,14 @@ impl Helper {
|
||||||
// need to verify if node still working
|
// need to verify if node still working
|
||||||
// for that need to catch "connect error"
|
// for that need to catch "connect error"
|
||||||
if contains_connect_error(&line) {
|
if contains_connect_error(&line) {
|
||||||
// updating current node to None.
|
let current_node = lock!(pub_api_xvb).current_node;
|
||||||
lock!(pub_api_xvb).current_node = None;
|
if let Some(current_node) = current_node {
|
||||||
// send signal to update node.
|
// updating current node to None, will stop sending signal of FailedNode until new node is set
|
||||||
warn!("XMRig PTY Parse | node is offline, switching to backup.");
|
// send signal to update node.
|
||||||
lock!(process_xvb).signal = ProcessSignal::UpdateNodes;
|
warn!("XMRig PTY Parse | node is offline, sending signal to update nodes.");
|
||||||
|
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(current_node);
|
||||||
|
lock!(pub_api_xvb).current_node = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if contains_usepool(&line) {
|
if contains_usepool(&line) {
|
||||||
info!("XMRig PTY Parse | new pool detected");
|
info!("XMRig PTY Parse | new pool detected");
|
||||||
|
@ -73,7 +76,8 @@ impl Helper {
|
||||||
let node = detect_new_node_xmrig(&line);
|
let node = detect_new_node_xmrig(&line);
|
||||||
if node.is_none() {
|
if node.is_none() {
|
||||||
error!("XMRig PTY Parse | node is not understood, switching to backup.");
|
error!("XMRig PTY Parse | node is not understood, switching to backup.");
|
||||||
lock!(process_xvb).signal = ProcessSignal::UpdateNodes;
|
// update with default will choose which XvB to prefer. Will update XvB to use p2pool.
|
||||||
|
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default());
|
||||||
}
|
}
|
||||||
lock!(pub_api_xvb).current_node = node;
|
lock!(pub_api_xvb).current_node = node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use readable::num::Float;
|
use readable::num::Float;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use tokio::time::{sleep_until, Instant};
|
use tokio::time::sleep;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
helper::{
|
helper::{
|
||||||
|
@ -166,7 +166,6 @@ fn minimum_time_for_highest_accessible_round(st: u32, lhr: f32, chr: f32, shr: f
|
||||||
}
|
}
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn sleep_then_update_node_xmrig(
|
async fn sleep_then_update_node_xmrig(
|
||||||
was_instant: Instant,
|
|
||||||
spared_time: u32,
|
spared_time: u32,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
api_uri: &str,
|
api_uri: &str,
|
||||||
|
@ -175,12 +174,12 @@ async fn sleep_then_update_node_xmrig(
|
||||||
gui_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
gui_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||||
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
||||||
) {
|
) {
|
||||||
let node = lock!(gui_api_xvb).stats_priv.node.clone();
|
let node = lock!(gui_api_xvb).stats_priv.node;
|
||||||
debug!(
|
debug!(
|
||||||
"Xvb Process | algo sleep for {} while mining on P2pool",
|
"Xvb Process | algo sleep for {} while mining on P2pool",
|
||||||
XVB_TIME_ALGO - spared_time
|
XVB_TIME_ALGO - spared_time
|
||||||
);
|
);
|
||||||
sleep_until(was_instant + Duration::from_secs((XVB_TIME_ALGO - spared_time) as u64)).await;
|
sleep(Duration::from_secs((XVB_TIME_ALGO - spared_time).into())).await;
|
||||||
// only update xmrig config if it is actually mining.
|
// only update xmrig config if it is actually mining.
|
||||||
if spared_time > 0 {
|
if spared_time > 0 {
|
||||||
debug!("Xvb Process | request xmrig to mine on XvB");
|
debug!("Xvb Process | request xmrig to mine on XvB");
|
||||||
|
@ -215,7 +214,7 @@ async fn sleep_then_update_node_xmrig(
|
||||||
}
|
}
|
||||||
// will not quit the process until it is really done.
|
// will not quit the process until it is really done.
|
||||||
// xvb process watch this algo handle to see if process is finished or not.
|
// xvb process watch this algo handle to see if process is finished or not.
|
||||||
sleep_until(was_instant + Duration::from_secs(spared_time.into())).await;
|
sleep(Duration::from_secs(spared_time.into())).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// push new value into samples before executing this calcul
|
// push new value into samples before executing this calcul
|
||||||
|
@ -225,7 +224,6 @@ fn calc_last_hour_avg_hash_rate(samples: &SamplesAverageHour) -> f32 {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) async fn algorithm(
|
pub(crate) async fn algorithm(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
last_algorithm: Instant,
|
|
||||||
gui_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
gui_api_xvb: &Arc<Mutex<PubXvbApi>>,
|
||||||
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
|
||||||
gui_api_p2pool: &Arc<Mutex<PubP2poolApi>>,
|
gui_api_p2pool: &Arc<Mutex<PubP2poolApi>>,
|
||||||
|
@ -300,7 +298,6 @@ pub(crate) async fn algorithm(
|
||||||
|
|
||||||
// sleep 10m less spared time then request XMrig to mine on XvB
|
// sleep 10m less spared time then request XMrig to mine on XvB
|
||||||
sleep_then_update_node_xmrig(
|
sleep_then_update_node_xmrig(
|
||||||
last_algorithm,
|
|
||||||
time_donated,
|
time_donated,
|
||||||
client,
|
client,
|
||||||
XMRIG_CONFIG_URI,
|
XMRIG_CONFIG_URI,
|
||||||
|
@ -313,11 +310,14 @@ pub(crate) async fn algorithm(
|
||||||
lock!(gui_api_xvb)
|
lock!(gui_api_xvb)
|
||||||
.p2pool_sent_last_hour_samples
|
.p2pool_sent_last_hour_samples
|
||||||
.0
|
.0
|
||||||
.push_back(hashrate_xmrig * ((XVB_TIME_ALGO - time_donated) / XVB_TIME_ALGO) as f32);
|
.push_back(
|
||||||
|
hashrate_xmrig
|
||||||
|
* ((XVB_TIME_ALGO as f32 - time_donated as f32) / XVB_TIME_ALGO as f32),
|
||||||
|
);
|
||||||
lock!(gui_api_xvb)
|
lock!(gui_api_xvb)
|
||||||
.xvb_sent_last_hour_samples
|
.xvb_sent_last_hour_samples
|
||||||
.0
|
.0
|
||||||
.push_back(hashrate_xmrig * (time_donated / XVB_TIME_ALGO) as f32);
|
.push_back(hashrate_xmrig * (time_donated as f32 / XVB_TIME_ALGO as f32));
|
||||||
} else {
|
} else {
|
||||||
// no share, so we mine on p2pool. We update xmrig only if it was still mining on XvB.
|
// no share, so we mine on p2pool. We update xmrig only if it was still mining on XvB.
|
||||||
if lock!(gui_api_xvb).current_node != Some(XvbNode::P2pool) {
|
if lock!(gui_api_xvb).current_node != Some(XvbNode::P2pool) {
|
||||||
|
@ -345,13 +345,13 @@ pub(crate) async fn algorithm(
|
||||||
}
|
}
|
||||||
output_console(gui_api_xvb, "No share in the current PPLNS Window !");
|
output_console(gui_api_xvb, "No share in the current PPLNS Window !");
|
||||||
output_console(gui_api_xvb, "Mining on P2pool for the next ten minutes.");
|
output_console(gui_api_xvb, "Mining on P2pool for the next ten minutes.");
|
||||||
sleep_until(last_algorithm + Duration::from_secs(XVB_TIME_ALGO.into())).await;
|
sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await;
|
||||||
lock!(gui_api_xvb)
|
lock!(gui_api_xvb)
|
||||||
.p2pool_sent_last_hour_samples
|
.p2pool_sent_last_hour_samples
|
||||||
.0
|
.0
|
||||||
.push_back(lock!(gui_api_xmrig).hashrate_raw_15m);
|
.push_back(lock!(gui_api_xmrig).hashrate_raw_15m);
|
||||||
lock!(gui_api_xvb)
|
lock!(gui_api_xvb)
|
||||||
.p2pool_sent_last_hour_samples
|
.xvb_sent_last_hour_samples
|
||||||
.0
|
.0
|
||||||
.push_back(0.0);
|
.push_back(0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl Helper {
|
||||||
// uptime of last run of algo
|
// uptime of last run of algo
|
||||||
let last_algorithm = Arc::new(Mutex::new(tokio::time::Instant::now()));
|
let last_algorithm = Arc::new(Mutex::new(tokio::time::Instant::now()));
|
||||||
// uptime of last request (public and private)
|
// uptime of last request (public and private)
|
||||||
let mut last_request = tokio::time::Instant::now();
|
let last_request = Arc::new(Mutex::new(tokio::time::Instant::now()));
|
||||||
// algo check if his behavior must be like the first time or second time. It can reset those values to re-act like first time even if it's not the case.
|
// algo check if his behavior must be like the first time or second time. It can reset those values to re-act like first time even if it's not the case.
|
||||||
let mut first_loop = true;
|
let mut first_loop = true;
|
||||||
// retry will be accessed from the 1m spawn, it can influence the start of algo.
|
// retry will be accessed from the 1m spawn, it can influence the start of algo.
|
||||||
|
@ -180,7 +180,7 @@ impl Helper {
|
||||||
let time_donated = Arc::new(Mutex::new(0));
|
let time_donated = Arc::new(Mutex::new(0));
|
||||||
// let handles;
|
// let handles;
|
||||||
let handle_algo = Arc::new(Mutex::new(None));
|
let handle_algo = Arc::new(Mutex::new(None));
|
||||||
let mut handle_request = None;
|
let handle_request = Arc::new(Mutex::new(None));
|
||||||
let mut msg_retry_done = false;
|
let mut msg_retry_done = false;
|
||||||
info!("XvB | Entering Process mode... ");
|
info!("XvB | Entering Process mode... ");
|
||||||
loop {
|
loop {
|
||||||
|
@ -217,33 +217,42 @@ impl Helper {
|
||||||
info!("XvB Watchdog | Signal has stopped the loop");
|
info!("XvB Watchdog | Signal has stopped the loop");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let handle = lock!(handle_algo);
|
let handle_algo_c = lock!(handle_algo);
|
||||||
let is_algo_started_once = handle.is_some();
|
let is_algo_started_once = handle_algo_c.is_some();
|
||||||
let is_algo_finished = handle.as_ref().is_some_and(|algo| algo.is_finished());
|
let is_algo_finished = handle_algo_c
|
||||||
drop(handle);
|
.as_ref()
|
||||||
|
.is_some_and(|algo| algo.is_finished());
|
||||||
|
let handle_request_c = lock!(handle_request);
|
||||||
|
let is_request_finished = handle_request_c
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|request: &JoinHandle<()>| request.is_finished())
|
||||||
|
|| handle_request_c.is_none();
|
||||||
|
drop(handle_algo_c);
|
||||||
|
drop(handle_request_c);
|
||||||
// Send an HTTP API request only if one minute is passed since the last request or if first loop or if algorithm need to retry or if request is finished and algo is finished or almost finished (only public and private stats). We make sure public and private stats are refreshed before doing another run of the algo.
|
// Send an HTTP API request only if one minute is passed since the last request or if first loop or if algorithm need to retry or if request is finished and algo is finished or almost finished (only public and private stats). We make sure public and private stats are refreshed before doing another run of the algo.
|
||||||
// We make sure algo or request are not rerun when they are not over.
|
// We make sure algo or request are not rerun when they are not over.
|
||||||
if last_request.elapsed() >= Duration::from_secs(60)
|
// in the case of quick refresh before new run of algo, make sure it doesn't happen multiple times.
|
||||||
|| first_loop
|
let last_request_expired = lock!(last_request).elapsed() >= Duration::from_secs(60);
|
||||||
|| *lock!(retry)
|
let should_refresh_before_next_algo = is_algo_started_once
|
||||||
|| ((is_algo_finished
|
&& lock!(last_algorithm).elapsed()
|
||||||
|| lock!(last_algorithm).elapsed()
|
>= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95) as u64)
|
||||||
>= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95) as u64))
|
&& lock!(last_request).elapsed() >= Duration::from_secs(25);
|
||||||
&& (handle_request
|
let process_alive = lock!(process).state == ProcessState::Alive;
|
||||||
.as_ref()
|
if ((last_request_expired || first_loop)
|
||||||
.is_some_and(|req: &JoinHandle<()>| req.is_finished())
|
|| (*lock!(retry) || is_algo_finished || should_refresh_before_next_algo)
|
||||||
|| handle_request.is_none()))
|
&& process_alive)
|
||||||
|
&& is_request_finished
|
||||||
{
|
{
|
||||||
// do not wait for the request to finish so that they are retrieved at exactly one minute interval and not block the thread.
|
// do not wait for the request to finish so that they are retrieved at exactly one minute interval and not block the thread.
|
||||||
// Private API will also use this instant if XvB is Alive.
|
// Private API will also use this instant if XvB is Alive.
|
||||||
last_request = tokio::time::Instant::now();
|
|
||||||
// first_loop is false here but could be changed to true under some conditions.
|
// 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.
|
// will send a stop signal if public stats failed or update data with new one.
|
||||||
handle_request = Some(spawn(
|
*lock!(handle_request) = Some(spawn(
|
||||||
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, state_xvb, state_p2pool, state_xmrig, process, last_algorithm, retry, handle_algo, time_donated) async move {
|
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, state_xvb, state_p2pool, state_xmrig, process, last_algorithm, retry, handle_algo, time_donated, last_request) async move {
|
||||||
// needs to wait here for public stats to get private stats.
|
// needs to wait here for public stats to get private stats.
|
||||||
if last_request.elapsed() >= Duration::from_secs(60) || first_loop || lock!(last_algorithm).elapsed() >= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95)as u64) {
|
if last_request_expired || first_loop || should_refresh_before_next_algo {
|
||||||
XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await;
|
XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await;
|
||||||
|
*lock!(last_request) = Instant::now();
|
||||||
}
|
}
|
||||||
// private stats needs valid token and address.
|
// private stats needs valid token and address.
|
||||||
// other stats needs everything to be alive, so just require alive here for now.
|
// other stats needs everything to be alive, so just require alive here for now.
|
||||||
|
@ -253,13 +262,14 @@ impl Helper {
|
||||||
let share = lock!(gui_api_p2pool).sidechain_shares;
|
let share = lock!(gui_api_p2pool).sidechain_shares;
|
||||||
debug!("XvB | Number of current shares: {}", share);
|
debug!("XvB | Number of current shares: {}", share);
|
||||||
// private stats can be requested every minute or first loop or if the have almost finished.
|
// private stats can be requested every minute or first loop or if the have almost finished.
|
||||||
if last_request.elapsed() >= Duration::from_secs(60) || first_loop || lock!(last_algorithm).elapsed() >= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95)as u64) {
|
if last_request_expired || first_loop || should_refresh_before_next_algo {
|
||||||
debug!("XvB Watchdog | Attempting HTTP private API request...");
|
debug!("XvB Watchdog | Attempting HTTP private API request...");
|
||||||
// reload private stats, it send a signal if error that will be captured on the upper thread.
|
// reload private stats, it send a signal if error that will be captured on the upper thread.
|
||||||
XvbPrivStats::update_stats(
|
XvbPrivStats::update_stats(
|
||||||
&client, &state_p2pool.address, &state_xvb.token, &pub_api, &gui_api, &process,
|
&client, &state_p2pool.address, &state_xvb.token, &pub_api, &gui_api, &process,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
*lock!(last_request) = Instant::now();
|
||||||
|
|
||||||
// verify in which round type we are
|
// verify in which round type we are
|
||||||
let round = round_type(share, &pub_api);
|
let round = round_type(share, &pub_api);
|
||||||
|
@ -279,14 +289,9 @@ impl Helper {
|
||||||
*lock!(retry) = false;
|
*lock!(retry) = false;
|
||||||
// reset instant because algo will start.
|
// reset instant because algo will start.
|
||||||
*lock!(last_algorithm) = Instant::now();
|
*lock!(last_algorithm) = Instant::now();
|
||||||
// send the instant that will be consumed by algo. Algo does not modify it.
|
|
||||||
let last_algorithm = *lock!(last_algorithm);
|
|
||||||
|
|
||||||
|
|
||||||
*lock!(handle_algo) = Some(spawn(enc!((client, gui_api, gui_api_xmrig, state_xmrig, time_donated) async move {
|
*lock!(handle_algo) = Some(spawn(enc!((client, gui_api, gui_api_xmrig, state_xmrig, time_donated) async move {
|
||||||
algorithm(
|
algorithm(
|
||||||
&client,
|
&client,
|
||||||
last_algorithm,
|
|
||||||
&gui_api,
|
&gui_api,
|
||||||
&gui_api_xmrig,
|
&gui_api_xmrig,
|
||||||
&gui_api_p2pool,
|
&gui_api_p2pool,
|
||||||
|
@ -447,7 +452,6 @@ async fn check_conditions_for_start(
|
||||||
ProcessState::Syncing
|
ProcessState::Syncing
|
||||||
} else {
|
} else {
|
||||||
// all test passed, so it can be Alive
|
// all test passed, so it can be Alive
|
||||||
info!("XvB will ping nodes");
|
|
||||||
// stay at middle, updateNodes will finish by syncing or offlinenodes and check_status in loop will change state accordingly.
|
// stay at middle, updateNodes will finish by syncing or offlinenodes and check_status in loop will change state accordingly.
|
||||||
ProcessState::Middle
|
ProcessState::Middle
|
||||||
};
|
};
|
||||||
|
@ -460,7 +464,7 @@ async fn check_conditions_for_start(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// will update the preferred node for the first loop, even if partially started.
|
// will update the preferred node for the first loop, even if partially started.
|
||||||
lock!(process_xvb).signal = ProcessSignal::UpdateNodes;
|
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default());
|
||||||
lock!(process_xvb).state = state;
|
lock!(process_xvb).state = state;
|
||||||
}
|
}
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -575,85 +579,58 @@ fn signal_interrupt(
|
||||||
// check if STOP or RESTART Signal is given.
|
// check if STOP or RESTART Signal is given.
|
||||||
// if STOP, will put Signal to None, if Restart to Wait
|
// if STOP, will put Signal to None, if Restart to Wait
|
||||||
// in either case, will break from loop.
|
// in either case, will break from loop.
|
||||||
if lock!(process).signal == ProcessSignal::Stop {
|
let signal = lock!(process).signal;
|
||||||
debug!("P2Pool Watchdog | Stop SIGNAL caught");
|
match signal {
|
||||||
// Wait to get the exit status
|
ProcessSignal::Stop => {
|
||||||
let uptime = start.elapsed();
|
debug!("P2Pool Watchdog | Stop SIGNAL caught");
|
||||||
info!(
|
// Wait to get the exit status
|
||||||
"Xvb Watchdog | Stopped ... Uptime was: [{}]",
|
let uptime = start.elapsed();
|
||||||
Uptime::from(uptime)
|
info!(
|
||||||
);
|
"Xvb Watchdog | Stopped ... Uptime was: [{}]",
|
||||||
// insert the signal into output of XvB
|
Uptime::from(uptime)
|
||||||
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
);
|
||||||
output_console(gui_api, "\n\n\nXvB stopped\n\n\n");
|
// insert the signal into output of XvB
|
||||||
debug!("XvB Watchdog | Stop SIGNAL done, breaking");
|
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
||||||
lock!(process).signal = ProcessSignal::None;
|
output_console(gui_api, "\n\n\nXvB stopped\n\n\n");
|
||||||
lock!(process).state = ProcessState::Dead;
|
debug!("XvB Watchdog | Stop SIGNAL done, breaking");
|
||||||
// reset stats
|
lock!(process).signal = ProcessSignal::None;
|
||||||
reset_data_xvb(pub_api, gui_api);
|
lock!(process).state = ProcessState::Dead;
|
||||||
return true;
|
// reset stats
|
||||||
// Check RESTART
|
reset_data_xvb(pub_api, gui_api);
|
||||||
} else if lock!(process).signal == ProcessSignal::Restart {
|
return true;
|
||||||
debug!("XvB Watchdog | Restart SIGNAL caught");
|
}
|
||||||
let uptime = Uptime::from(start.elapsed());
|
ProcessSignal::Restart => {
|
||||||
info!("XvB Watchdog | Stopped ... Uptime was: [{}]", uptime);
|
debug!("XvB Watchdog | Restart SIGNAL caught");
|
||||||
// no output to console because service will be started with fresh output.
|
let uptime = Uptime::from(start.elapsed());
|
||||||
debug!("XvB Watchdog | Restart SIGNAL done, breaking");
|
info!("XvB Watchdog | Stopped ... Uptime was: [{}]", uptime);
|
||||||
lock!(process).state = ProcessState::Waiting;
|
// no output to console because service will be started with fresh output.
|
||||||
reset_data_xvb(pub_api, gui_api);
|
debug!("XvB Watchdog | Restart SIGNAL done, breaking");
|
||||||
return true;
|
lock!(process).state = ProcessState::Waiting;
|
||||||
// Check UPDATE NODES
|
reset_data_xvb(pub_api, gui_api);
|
||||||
} else if lock!(process).signal == ProcessSignal::UpdateNodes
|
return true;
|
||||||
&& lock!(process).state != ProcessState::Waiting
|
}
|
||||||
{
|
ProcessSignal::UpdateNodes(node) => {
|
||||||
info!("XvB Watchdog | Signal has been given to ping and reselect Nodes.");
|
if lock!(process).state != ProcessState::Waiting {
|
||||||
// if signal is waiting, he is restarting or already updating nodes.
|
let token_xmrig = state_xmrig.token.clone();
|
||||||
// need to know if it was starting xvb
|
let address = state_p2pool.address.clone();
|
||||||
// A signal has been given to ping the nodes and select the fastest.
|
// 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.
|
||||||
let token_xmrig = state_xmrig.token.clone();
|
// if XvB, xmrig needs to be switch to the other node (both will be checked though to be sure).
|
||||||
let address = state_p2pool.address.clone();
|
// 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.
|
||||||
let alive = lock!(process).state == ProcessState::Alive;
|
// if P2pool, the process has to stop the algo and continue partially. The process will continue completely if the confitions are met again.
|
||||||
// so it won't execute another signal of update nodes if it is already doing it.
|
// 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.
|
||||||
lock!(process).state = ProcessState::Waiting;
|
// if XvB was not alive and update was for P2pool, XvB must ignore. XMRig will stop sending signals because current node will be none.
|
||||||
lock!(process).signal = ProcessSignal::None;
|
let was_alive = lock!(process).state != ProcessState::Alive;
|
||||||
spawn(
|
// so it won't execute another signal of update nodes if it is already doing it.
|
||||||
enc!((gui_api, pub_api, gui_api_xmrig, client, process) async move {
|
lock!(process).state = ProcessState::Waiting;
|
||||||
// if nodes die while being used by xmrig, it needs see which one is capable, send a signal if none is useable and switch xmrig to the good node (or p2pool if none).
|
lock!(process).signal = ProcessSignal::None;
|
||||||
// update nodes will make the state Syncing, and the loop of the thread will detected if it can be made alive.
|
spawn(
|
||||||
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
|
enc!((node, process, client, gui_api, pub_api, was_alive, address, token_xmrig, gui_api_xmrig) async move {
|
||||||
// only update xmrig if state is alive.
|
match node {
|
||||||
if alive {
|
XvbNode::NorthAmerica|XvbNode::Europe if was_alive => {
|
||||||
let node = lock!(gui_api).stats_priv.node.clone();
|
// a node is failing. We need to first verify if a node is available
|
||||||
if let Err(err) = PrivXmrigApi::update_xmrig_config(
|
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
|
||||||
&client,
|
if lock!(process).state == ProcessState::OfflineNodesAll {
|
||||||
XMRIG_CONFIG_URI,
|
// No available nodes, so launch a process to verify periodicly.
|
||||||
&token_xmrig,
|
|
||||||
&node,
|
|
||||||
&address,
|
|
||||||
&gui_api_xmrig,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
// show to console error about updating xmrig config
|
|
||||||
output_console(
|
|
||||||
&gui_api,
|
|
||||||
&format!(
|
|
||||||
"Failure to update xmrig config with HTTP API.\nError: {}",
|
|
||||||
err
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
output_console(
|
|
||||||
&gui_api,
|
|
||||||
&format!("XvB node failed, falling back to {}", node),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// verify if nodes were joignable.
|
|
||||||
if lock!(process).state == ProcessState::OfflineNodesAll {
|
|
||||||
// if state did not change after updating fastest node, it means all xvb nodes failed.
|
|
||||||
// we need to spawn a process to verify periodiccly until the nodes are online. The service state will be Alive then.
|
|
||||||
|
|
||||||
sleep(Duration::from_secs(10)).await;
|
sleep(Duration::from_secs(10)).await;
|
||||||
info!("node fail, set spawn that will retry nodes and update state.");
|
info!("node fail, set spawn that will retry nodes and update state.");
|
||||||
while lock!(process).state == ProcessState::OfflineNodesAll {
|
while lock!(process).state == ProcessState::OfflineNodesAll {
|
||||||
|
@ -661,12 +638,47 @@ fn signal_interrupt(
|
||||||
XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await;
|
XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await;
|
||||||
sleep(Duration::from_secs(10)).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.
|
||||||
// the state will be Offline or Alive after update_fastest_node is done, meanwhile Signal will be None so not re-treated before update_fastest is done.
|
|
||||||
// so if a backup was used, it will be alive. If not, the algorithm stop and xmrig is updated to mine on p2pool.
|
|
||||||
|
},
|
||||||
|
XvbNode::NorthAmerica|XvbNode::Europe if !was_alive => {
|
||||||
|
// Probably a start. We don't consider XMRig using XvB nodes without algo.
|
||||||
|
// can update xmrig and check status of state in the same time.
|
||||||
|
// Need to set XMRig to P2Pool if it wasn't. XMRig should have populated this value at his start.
|
||||||
|
|
||||||
|
if lock!(gui_api).current_node != Some(XvbNode::P2pool) {
|
||||||
|
spawn(enc!((client, token_xmrig, address, gui_api_xmrig, gui_api) async move{
|
||||||
|
if let Err(err) = PrivXmrigApi::update_xmrig_config(
|
||||||
|
&client,
|
||||||
|
XMRIG_CONFIG_URI,
|
||||||
|
&token_xmrig,
|
||||||
|
&XvbNode::P2pool,
|
||||||
|
&address,
|
||||||
|
&gui_api_xmrig,
|
||||||
|
)
|
||||||
|
.await {
|
||||||
|
output_console(
|
||||||
|
&gui_api,
|
||||||
|
&format!(
|
||||||
|
"Failure to update xmrig config with HTTP API.\nError: {}",
|
||||||
|
err
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
} } ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) {
|
fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) {
|
||||||
|
@ -706,7 +718,7 @@ fn update_indicator_algo(
|
||||||
last_algorithm: &Arc<Mutex<Instant>>,
|
last_algorithm: &Arc<Mutex<Instant>>,
|
||||||
) {
|
) {
|
||||||
if is_algo_started_once && !is_algo_finished && lock!(process).state == ProcessState::Alive {
|
if is_algo_started_once && !is_algo_finished && lock!(process).state == ProcessState::Alive {
|
||||||
let node = lock!(pub_api).current_node.clone();
|
let node = lock!(pub_api).current_node;
|
||||||
let msg_indicator = match node {
|
let msg_indicator = match node {
|
||||||
Some(XvbNode::P2pool) if time_donated > 0 => {
|
Some(XvbNode::P2pool) if time_donated > 0 => {
|
||||||
// algo is mining on p2pool but will switch to XvB after
|
// algo is mining on p2pool but will switch to XvB after
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PubXvbApi;
|
use super::PubXvbApi;
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Display)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Display)]
|
||||||
pub enum XvbNode {
|
pub enum XvbNode {
|
||||||
#[display(fmt = "XvB North America Node")]
|
#[display(fmt = "XvB North America Node")]
|
||||||
NorthAmerica,
|
NorthAmerica,
|
||||||
|
|
Loading…
Reference in a new issue