diff --git a/src/helper/xvb/algorithm.rs b/src/helper/xvb/algorithm.rs index a794593..b9d61dd 100644 --- a/src/helper/xvb/algorithm.rs +++ b/src/helper/xvb/algorithm.rs @@ -8,6 +8,7 @@ use std::{ time::Duration, }; +use log::error; use log::{info, warn}; use reqwest_middleware::ClientWithMiddleware as Client; use tokio::time::sleep; @@ -83,12 +84,14 @@ pub struct Stats { pub target_donation_hashrate: f32, xvb_24h_avg: f32, xvb_1h_avg: f32, + xvb_external_hashrate: f32, address: String, runtime_mode: RuntimeMode, runtime_donation_level: RuntimeDonationLevel, + // manual slider for p2pool and xvb manual runtime_amount: f64, p2pool_total_hashrate: f32, - avg_last_hour_hashrate: f32, + p2pool_avg_last_hour_hashrate: f32, p2pool_external_hashrate: f32, share_min_hashrate: f32, spareable_hashrate: f32, @@ -129,10 +132,12 @@ impl<'a> Algorithm<'a> { let p2pool_total_hashrate = gui_api_p2pool.lock().unwrap().sidechain_ehr; - let avg_last_hour_hashrate = Self::calc_last_hour_avg_hash_rate( + let p2pool_avg_last_hour_hashrate = Self::calc_last_hour_avg_hash_rate( &gui_api_xvb.lock().unwrap().p2pool_sent_last_hour_samples, ); - let p2pool_external_hashrate = (p2pool_total_hashrate - avg_last_hour_hashrate).max(0.0); + let p2pool_external_hashrate = + (p2pool_total_hashrate - p2pool_avg_last_hour_hashrate).max(0.0); + info!("p2pool external hashrate({p2pool_external_hashrate}) = p2ool_total_hashrate({p2pool_total_hashrate}) - p2pool_avg_last_hour_hashrate({p2pool_avg_last_hour_hashrate})"); let share_min_hashrate = Self::minimum_hashrate_share( gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64, @@ -151,18 +156,24 @@ impl<'a> Algorithm<'a> { let xvb_24h_avg = pub_api.lock().unwrap().stats_priv.donor_24hr_avg * 1000.0; let xvb_1h_avg = pub_api.lock().unwrap().stats_priv.donor_1hr_avg * 1000.0; + let xvb_avg_last_hour_hashrate = Self::calc_last_hour_avg_hash_rate( + &gui_api_xvb.lock().unwrap().xvb_sent_last_hour_samples, + ); + let xvb_external_hashrate = (xvb_1h_avg - xvb_avg_last_hour_hashrate).max(0.0); + info!("xvb external hashrate({xvb_external_hashrate}) = p2ool_total_hashrate({xvb_1h_avg}) - xvb_avg_last_hour_hashrate({xvb_avg_last_hour_hashrate})"); let stats = Stats { share, hashrate_xmrig, xvb_24h_avg, xvb_1h_avg, + xvb_external_hashrate, address, target_donation_hashrate: f32::default(), runtime_mode, runtime_donation_level, runtime_amount, p2pool_total_hashrate, - avg_last_hour_hashrate, + p2pool_avg_last_hour_hashrate, p2pool_external_hashrate, share_min_hashrate, spareable_hashrate, @@ -185,7 +196,7 @@ impl<'a> Algorithm<'a> { xp_alive, stats, }; - + // 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 = new_instance.get_target_donation_hashrate(); new_instance.stats.needed_time_xvb = Self::get_needed_time_xvb( new_instance.stats.target_donation_hashrate, @@ -207,6 +218,10 @@ impl<'a> Algorithm<'a> { } fn is_xvb_24h_fulfilled(&self) -> bool { + if self.stats.runtime_mode == RuntimeMode::Hero { + info!("Algorithm | running in hero mode, no fast 24h average"); + return true; + } let is_criteria_fulfilled = self.stats.xvb_24h_avg > self.stats.target_donation_hashrate; info!( "Algorithm | xvb_24h_avg({}) > target_donation_hashrate({}) : {}", @@ -310,13 +325,13 @@ impl<'a> Algorithm<'a> { XVB_TIME_ALGO ); sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await; - + let hashrate = current_controllable_hr(self.xp_alive, self.gui_api_xp, self.gui_api_xmrig); self.gui_api_xvb .lock() .unwrap() .p2pool_sent_last_hour_samples .0 - .push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m); + .push_back(hashrate); self.gui_api_xvb .lock() .unwrap() @@ -333,18 +348,18 @@ impl<'a> Algorithm<'a> { XVB_TIME_ALGO ); sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await; - - self.gui_api_xvb - .lock() - .unwrap() - .p2pool_sent_last_hour_samples - .0 - .push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m); + let hashrate = current_controllable_hr(self.xp_alive, self.gui_api_xp, self.gui_api_xmrig); self.gui_api_xvb .lock() .unwrap() .xvb_sent_last_hour_samples .0 + .push_back(hashrate); + self.gui_api_xvb + .lock() + .unwrap() + .p2pool_sent_last_hour_samples + .0 .push_back(0.0); } @@ -371,14 +386,15 @@ impl<'a> Algorithm<'a> { self.stats.needed_time_xvb ); sleep(Duration::from_secs(self.stats.needed_time_xvb.into())).await; - + // HR could be not the same now as the avg sent the last 10mn, will be replaced later by a better history of HR + let hashrate = current_controllable_hr(self.xp_alive, self.gui_api_xp, self.gui_api_xmrig); self.gui_api_xvb .lock() .unwrap() .p2pool_sent_last_hour_samples .0 .push_back( - self.stats.hashrate_xmrig + hashrate * ((XVB_TIME_ALGO as f32 - self.stats.needed_time_xvb as f32) / XVB_TIME_ALGO as f32), ); @@ -387,10 +403,7 @@ impl<'a> Algorithm<'a> { .unwrap() .xvb_sent_last_hour_samples .0 - .push_back( - self.stats.hashrate_xmrig - * (self.stats.needed_time_xvb as f32 / XVB_TIME_ALGO as f32), - ); + .push_back(hashrate * (self.stats.needed_time_xvb as f32 / XVB_TIME_ALGO as f32)); } pub fn get_target_donation_hashrate(&self) -> f32 { @@ -416,8 +429,10 @@ impl<'a> Algorithm<'a> { target_donation_hashrate } + // manual donation level will take into account external HR RuntimeMode::ManualDonationLevel => { - let target_donation_hashrate = self.stats.runtime_donation_level.get_hashrate(); + let target_donation_hashrate = self.stats.runtime_donation_level.get_hashrate() + - self.stats.xvb_external_hashrate; info!("Algorithm | ManualDonationLevelMode target_donation_hashrate({})={:#?}.get_hashrate()", target_donation_hashrate, @@ -429,7 +444,8 @@ impl<'a> Algorithm<'a> { } fn get_auto_mode_target_donation_hashrate(&self) -> f32 { - let donation_level = match self.stats.spareable_hashrate { + let donation_level = match self.stats.spareable_hashrate + self.stats.xvb_external_hashrate + { x if x > (XVB_ROUND_DONOR_MEGA_MIN_HR as f32) => Some(RuntimeDonationLevel::DonorMega), x if x > (XVB_ROUND_DONOR_WHALE_MIN_HR as f32) => { Some(RuntimeDonationLevel::DonorWhale) @@ -445,7 +461,7 @@ impl<'a> Algorithm<'a> { ); let target_donation_hashrate = if let Some(level) = donation_level { - level.get_hashrate() + level.get_hashrate() - self.stats.xvb_external_hashrate } else { 0.0 }; @@ -457,7 +473,8 @@ impl<'a> Algorithm<'a> { target_donation_hashrate } - + // hero mode, send all spareable hashrate to XvB. the targeted hashrate is the spearable hashrate. + // 24h fast needs to be disabled in hero mode, or else the min share HR will never get his needed time. fn get_hero_mode_target_donation_hashrate(&self) -> f32 { info!( "Algorithm | HeroMode target_donation_hashrate=spareable_hashrate({})", @@ -538,12 +555,19 @@ impl<'a> Algorithm<'a> { crate::helper::ProcessName::Xvb, ); - info!("Algorithm | There is a share in p2pool and 24H avg XvB is achieved. Sending seconds {} to XvB!", self.stats.needed_time_xvb); + info!("Algorithm | There is a share in p2pool and 24H avg XvB is achieved. Sending {} seconds to XvB!", self.stats.needed_time_xvb); *self.time_donated.lock().unwrap() = self.stats.needed_time_xvb; - - self.target_p2pool_node().await; - self.sleep_then_update_node_xmrig().await; + // do not switch pool for a few seconds, let's make 6 seconds minimum. + match self.stats.needed_time_xvb { + x if x <= 6 => { + self.target_p2pool_node().await; + self.sleep_then_update_node_xmrig().await; + } + x if x <= XVB_TIME_ALGO - 6 => self.send_all_p2pool().await, + x if x >= XVB_TIME_ALGO - 6 => self.send_all_xvb().await, + _ => error!("should not be possible"), + }; } pub async fn run(&mut self) { diff --git a/src/helper/xvb/mod.rs b/src/helper/xvb/mod.rs index 87651e5..ca48cfc 100644 --- a/src/helper/xvb/mod.rs +++ b/src/helper/xvb/mod.rs @@ -464,6 +464,10 @@ impl PubXvbApi { runtime_manual_donation_level, ..pub_api.stats_priv.clone() }, + p2pool_sent_last_hour_samples: std::mem::take( + &mut gui_api.p2pool_sent_last_hour_samples, + ), + xvb_sent_last_hour_samples: std::mem::take(&mut gui_api.xvb_sent_last_hour_samples), ..pub_api.clone() }; }