Skip to content

Commit 29dca23

Browse files
authored
Merge pull request dmnd-pool#74 from Priceless-P/fix/auto-update
Fixes
2 parents a94688e + 33b7b25 commit 29dca23

9 files changed

Lines changed: 448 additions & 164 deletions

File tree

Cargo.lock

Lines changed: 269 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ serde = { version = "1.0.219", features = ["derive"] }
2424
sysinfo = {version = "0.33.1"}
2525
primitive-types = { version = "0.13.1" }
2626
toml ={ version = "0.8.22" }
27-
self_update = {version = "0.42.0"}
27+
self_update = {version = "0.42.0", features = ["archive-tar"]}
28+
reqwest ={ version = "0.12.20"}
2829
#roles_logic_sv2 = "1.2.1"
2930
#sv1_api = "1.0.1"
3031
#demand-sv2-connection = "0.0.3"

src/config.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ struct Args {
2121
loglevel: Option<String>,
2222
#[clap(long = "nc", short = 'n')]
2323
noise_connection_log: Option<String>,
24+
#[clap(long = "sv1_loglevel")]
25+
sv1_loglevel: bool,
2426
#[clap(long = "delay")]
2527
delay: Option<u64>,
2628
#[clap(long = "interval", short = 'i')]
@@ -56,6 +58,7 @@ struct ConfigFile {
5658
downstream_hashrate: Option<String>,
5759
loglevel: Option<String>,
5860
nc_loglevel: Option<String>,
61+
sv1_log: Option<bool>,
5962
test: Option<bool>,
6063
listening_addr: Option<String>,
6164
api_server_port: Option<String>,
@@ -73,6 +76,7 @@ pub struct Configuration {
7376
downstream_hashrate: f32,
7477
loglevel: String,
7578
nc_loglevel: String,
79+
sv1_log: bool,
7680
test: bool,
7781
listening_addr: Option<String>,
7882
api_server_port: String,
@@ -111,6 +115,7 @@ impl Configuration {
111115
pub fn downstream_listening_addr() -> Option<String> {
112116
CONFIG.listening_addr.clone()
113117
}
118+
114119
pub fn api_server_port() -> String {
115120
CONFIG.api_server_port.clone()
116121
}
@@ -140,6 +145,9 @@ impl Configuration {
140145
}
141146
}
142147
}
148+
pub fn sv1_ingress_log() -> bool {
149+
CONFIG.sv1_log
150+
}
143151

144152
pub fn test() -> bool {
145153
CONFIG.test
@@ -170,6 +178,7 @@ impl Configuration {
170178
downstream_hashrate: None,
171179
loglevel: None,
172180
nc_loglevel: None,
181+
sv1_log: None,
173182
test: None,
174183
listening_addr: None,
175184
api_server_port: None,
@@ -302,6 +311,10 @@ impl Configuration {
302311
.or_else(|| std::env::var("NC_LOGLEVEL").ok())
303312
.unwrap_or("off".to_string());
304313

314+
let sv1_log = args.sv1_loglevel
315+
|| config.sv1_log.unwrap_or(false)
316+
|| std::env::var("SV1_LOGLEVEL").is_ok();
317+
305318
let test = args.test || config.test.unwrap_or(false) || std::env::var("TEST").is_ok();
306319

307320
let monitor =
@@ -321,6 +334,7 @@ impl Configuration {
321334
downstream_hashrate,
322335
loglevel,
323336
nc_loglevel,
337+
sv1_log,
324338
test,
325339
listening_addr,
326340
api_server_port,

src/ingress/sv1_ingress.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use std::net::{IpAddr, SocketAddr};
22

3-
use crate::shared::{error::Sv1IngressError, utils::AbortOnDrop};
3+
use crate::{
4+
config::Configuration,
5+
shared::{error::Sv1IngressError, utils::AbortOnDrop},
6+
};
47
use futures::{
58
stream::{SplitSink, SplitStream},
69
SinkExt, StreamExt,
@@ -79,6 +82,9 @@ impl Downstream {
7982
) -> Sv1IngressError {
8083
let task = tokio::spawn(async move {
8184
while let Some(Ok(message)) = recv.next().await {
85+
if Configuration::sv1_ingress_log() {
86+
info!("Sending msg to upstream: {}", message);
87+
}
8288
if send.send(message).await.is_err() {
8389
error!("Upstream dropped trying to send");
8490
return Sv1IngressError::TranslatorDropped;
@@ -100,6 +106,9 @@ impl Downstream {
100106
let task = tokio::spawn(async move {
101107
while let Some(message) = recv.recv().await {
102108
let message = message.replace(['\n', '\r'], "");
109+
if Configuration::sv1_ingress_log() {
110+
info!("Sending msg to downstream: {}", message);
111+
}
103112
if send.send(message).await.is_err() {
104113
warn!("Downstream dropped while trying to send message down");
105114
return Sv1IngressError::DownstreamDropped;

src/main.rs

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use config::Configuration;
1111
use key_utils::Secp256k1PublicKey;
1212
use lazy_static::lazy_static;
1313
use proxy_state::{PoolState, ProxyState, TpState, TranslatorState};
14-
use self_update::{backends, cargo_crate_version, Status};
14+
use self_update::{backends, cargo_crate_version, update::UpdateStatus, TempDir};
1515
use std::{net::SocketAddr, time::Duration};
1616
use tokio::sync::mpsc::channel;
1717
use tracing::{debug, error, info, warn};
@@ -322,6 +322,9 @@ fn check_update_proxy() {
322322

323323
debug!("OS: {}", target_bin);
324324
debug!("DMND-PROXY version: {}", cargo_crate_version!());
325+
let original_path = std::env::current_exe().expect("Failed to get current executable path");
326+
let tmp_dir = TempDir::new_in(::std::env::current_dir().expect("Failed to get current dir"))
327+
.expect("Failed to create tmp dir");
325328

326329
let updater = match backends::github::Update::configure()
327330
.repo_owner(REPO_OWNER)
@@ -331,6 +334,7 @@ fn check_update_proxy() {
331334
.target(target_bin)
332335
.show_output(false)
333336
.no_confirm(true)
337+
.bin_install_path(tmp_dir.path())
334338
.build()
335339
{
336340
Ok(updater) => updater,
@@ -340,33 +344,75 @@ fn check_update_proxy() {
340344
}
341345
};
342346

343-
match updater.update() {
347+
match updater.update_extended() {
344348
Ok(status) => match status {
345-
Status::UpToDate(_) => {
349+
UpdateStatus::UpToDate => {
346350
info!("Starting latest version of DMND-PROXY.");
347351
}
348-
Status::Updated(version) => {
349-
info!("Proxy updated to version {}. Restarting Proxy", version);
350-
351-
let current_exe =
352-
std::env::current_exe().expect("Failed to get current executable path");
352+
UpdateStatus::Updated(release) => {
353+
info!(
354+
"Proxy updated to version {}. Restarting Proxy",
355+
release.version
356+
);
357+
for asset in release.assets {
358+
if asset.name == target_bin {
359+
let bin_name = std::path::PathBuf::from(target_bin);
360+
let new_exe = tmp_dir.path().join(&bin_name);
361+
let mut file =
362+
std::fs::File::create(&new_exe).expect("Failed to create file");
363+
let mut download = self_update::Download::from_url(&asset.download_url);
364+
download.set_header(
365+
reqwest::header::ACCEPT,
366+
reqwest::header::HeaderValue::from_static("application/octet-stream"), // to triggers a redirect to the actual binary.
367+
);
368+
download
369+
.download_to(&mut file)
370+
.expect("Failed to download file");
371+
}
372+
}
373+
let bin_name = std::path::PathBuf::from(target_bin);
374+
let new_exe = tmp_dir.path().join(&bin_name);
375+
if let Err(e) = std::fs::rename(&new_exe, &original_path) {
376+
error!(
377+
"Failed to move new binary to {}: {}",
378+
original_path.display(),
379+
e
380+
);
381+
return;
382+
}
353383

354-
// Get original cli rgs
384+
let _ = std::fs::remove_dir_all(tmp_dir); // clean up tmp dir
385+
// Get original cli rgs
355386
let args = std::env::args().skip(1).collect::<Vec<_>>();
356387

357388
#[cfg(unix)]
358389
{
359-
// On Unix-like systems, replace the current process with the new binary
390+
use std::os::unix::fs::PermissionsExt;
360391
use std::os::unix::process::CommandExt;
361-
let err = std::process::Command::new(current_exe).args(&args).exec();
392+
// On Unix-like systems, replace the current process with the new binary
393+
if let Err(e) = std::fs::set_permissions(
394+
&original_path,
395+
std::fs::Permissions::from_mode(0o755),
396+
) {
397+
error!(
398+
"Failed to set executable permissions on {}: {}",
399+
original_path.display(),
400+
e
401+
);
402+
return;
403+
}
404+
405+
let err = std::process::Command::new(&original_path)
406+
.args(&args)
407+
.exec();
362408
// If exec fails, log the error and exit
363409
error!("Failed to exec new binary: {:?}", err);
364410
std::process::exit(1);
365411
}
366412
#[cfg(not(unix))]
367413
{
368414
// On Windows, spawn the new process and exit the current one
369-
std::process::Command::new(current_exe)
415+
std::process::Command::new(&original_path)
370416
.args(&args)
371417
.spawn()
372418
.expect("Failed to start proxy");

src/translator/downstream/diff_management.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ impl Downstream {
1919
pub async fn init_difficulty_management(self_: &Arc<Mutex<Self>>) -> ProxyResult<()> {
2020
let (diff, stats_sender, connection_id, estimated_hashrate) = self_.safe_lock(|d| {
2121
(
22-
d.difficulty_mgmt.current_difficulty,
22+
d.difficulty_mgmt
23+
.current_difficulties
24+
.back()
25+
.copied()
26+
.unwrap_or(d.difficulty_mgmt.initial_difficulty),
2327
d.stats_sender.clone(),
2428
d.connection_id,
2529
d.difficulty_mgmt.estimated_downstream_hash_rate,
@@ -200,16 +204,20 @@ impl Downstream {
200204
return Err(Error::Unrecoverable);
201205
}
202206

203-
let (mut pid, current_difficulty, initial_difficulty) = self_.safe_lock(|d| {
207+
let (mut pid, latest_difficulty, initial_difficulty) = self_.safe_lock(|d| {
204208
(
205209
d.difficulty_mgmt.pid_controller,
206-
d.difficulty_mgmt.current_difficulty,
210+
d.difficulty_mgmt
211+
.current_difficulties
212+
.back()
213+
.copied()
214+
.unwrap_or(d.difficulty_mgmt.initial_difficulty),
207215
d.difficulty_mgmt.initial_difficulty,
208216
)
209217
})?;
210218

211219
let pid_output = pid.next_control_output(realized_share_per_min).output;
212-
let new_difficulty = (current_difficulty + pid_output).max(initial_difficulty * 0.1);
220+
let new_difficulty = (latest_difficulty + pid_output).max(initial_difficulty * 0.1);
213221
let nearest = nearest_power_of_10(new_difficulty);
214222
if nearest != initial_difficulty {
215223
let mut pid: Pid<f32> = Pid::new(crate::SHARE_PER_MIN, nearest * 10.0);
@@ -229,7 +237,7 @@ impl Downstream {
229237
} else {
230238
// TODO check if we can improve stale share with a threshold here
231239
let threshold = 0.0;
232-
let change = (new_difficulty - current_difficulty).abs() / current_difficulty;
240+
let change = (new_difficulty - latest_difficulty).abs() / latest_difficulty;
233241
if change > threshold {
234242
let new_estimation =
235243
Self::estimate_hash_rate_from_difficulty(new_difficulty, crate::SHARE_PER_MIN);
@@ -259,7 +267,7 @@ impl Downstream {
259267
let old_estimation = d.difficulty_mgmt.estimated_downstream_hash_rate;
260268
d.difficulty_mgmt.estimated_downstream_hash_rate = new_estimation;
261269
d.difficulty_mgmt.reset();
262-
d.difficulty_mgmt.current_difficulty = current_diff;
270+
d.difficulty_mgmt.add_difficulty(current_diff);
263271

264272
(
265273
d.upstream_difficulty_config.clone(),
@@ -417,10 +425,12 @@ mod test {
417425
}
418426

419427
async fn test_converge_to_spm(start_hashrate: f64) {
428+
let mut diff = VecDeque::new();
429+
diff.push_back(10_000_000_000.0);
420430
let downstream_conf = DownstreamDifficultyConfig {
421431
estimated_downstream_hash_rate: 0.0, // updated below
422432
pid_controller: Pid::new(10.0, 100_000_000.0),
423-
current_difficulty: 10_000_000_000.0,
433+
current_difficulties: diff,
424434
submits: VecDeque::new(),
425435
initial_difficulty: 10_000_000_000.0,
426436
};
@@ -466,8 +476,10 @@ mod test {
466476
mock_mine(initial_target.clone().into(), &mut share);
467477
Downstream::save_share(downstream.clone()).unwrap();
468478
let _ = Downstream::try_update_difficulty_settings(&downstream).await;
469-
initial_target =
470-
Downstream::difficulty_to_target(downstream_conf.current_difficulty).into();
479+
initial_target = Downstream::difficulty_to_target(
480+
*downstream_conf.current_difficulties.back().unwrap(),
481+
)
482+
.into();
471483
elapsed = timer.elapsed();
472484
}
473485
let expected_0s = trailing_0s(expected_target.inner_as_ref().to_vec());

0 commit comments

Comments
 (0)