989: Check if binary is latest version r=delta1 a=lescuer97

Needs to be decided if this is going to be used for the ASB too and where in the code base the function should be put. 

I'll wait for comments ;)

Fixes #988 

Co-authored-by: leonardo <leoescuer@protonmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Byron Hambly <bhambly@blockstream.com>
pull/1101/head
bors[bot] 2 years ago committed by GitHub
commit 74e7c1e4c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -29,6 +29,7 @@ use swap::asb::config::{
initial_setup, query_user_for_initial_config, read_config, Config, ConfigNotInitialized,
};
use swap::asb::{cancel, punish, redeem, refund, safely_abort, EventLoop, Finality, KrakenRate};
use swap::common::check_latest_version;
use swap::database::open_db;
use swap::monero::Amount;
use swap::network::rendezvous::XmrBtcNamespace;
@ -68,6 +69,10 @@ async fn main() -> Result<()> {
}
};
if let Err(e) = check_latest_version(env!("CARGO_PKG_VERSION")).await {
eprintln!("{}", e);
}
asb::tracing::init(LevelFilter::DEBUG, json, !disable_timestamp).expect("initialize tracing");
let config = match read_config(config_path.clone())? {

@ -26,6 +26,7 @@ use std::time::Duration;
use swap::bitcoin::TxLock;
use swap::cli::command::{parse_args_and_apply_defaults, Arguments, Command, ParseResult};
use swap::cli::{list_sellers, EventLoop, SellerStatus};
use swap::common::check_latest_version;
use swap::database::open_db;
use swap::env::Config;
use swap::libp2p_ext::MultiAddrExt;
@ -54,6 +55,10 @@ async fn main() -> Result<()> {
}
};
if let Err(e) = check_latest_version(env!("CARGO_PKG_VERSION")).await {
eprintln!("{}", e);
}
match cmd {
Command::BuyXmr {
seller,
@ -68,6 +73,7 @@ async fn main() -> Result<()> {
let swap_id = Uuid::new_v4();
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
let db = open_db(data_dir.join("sqlite")).await?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
@ -196,6 +202,7 @@ async fn main() -> Result<()> {
address,
} => {
cli::tracing::init(debug, json, data_dir.join("logs"), None)?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
let bitcoin_wallet = init_bitcoin_wallet(
@ -229,6 +236,7 @@ async fn main() -> Result<()> {
bitcoin_target_block,
} => {
cli::tracing::init(debug, json, data_dir.join("logs"), None)?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
let bitcoin_wallet = init_bitcoin_wallet(
@ -255,6 +263,7 @@ async fn main() -> Result<()> {
namespace,
} => {
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
let db = open_db(data_dir.join("sqlite")).await?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
@ -321,6 +330,7 @@ async fn main() -> Result<()> {
bitcoin_target_block,
} => {
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
let db = open_db(data_dir.join("sqlite")).await?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
@ -343,6 +353,7 @@ async fn main() -> Result<()> {
bitcoin_target_block,
} => {
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
let db = open_db(data_dir.join("sqlite")).await?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
@ -368,6 +379,7 @@ async fn main() -> Result<()> {
.context("Rendezvous node address must contain peer ID")?;
cli::tracing::init(debug, json, data_dir.join("logs"), None)?;
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read in seed file")?;
let identity = seed.derive_libp2p_identity();
@ -462,6 +474,8 @@ async fn main() -> Result<()> {
tracing::info!(descriptor=%wallet_export.to_string(), "Exported bitcoin wallet");
}
Command::MoneroRecovery { swap_id } => {
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
let db = open_db(data_dir.join("sqlite")).await?;
let swap_state: BobState = db.get_state(swap_id).await?.try_into()?;

@ -0,0 +1,57 @@
use anyhow::anyhow;
const LATEST_RELEASE_URL: &str = "https://github.com/comit-network/xmr-btc-swap/releases/latest";
#[derive(Clone, Debug, PartialEq)]
pub enum Version {
Current,
Available,
}
/// Check the latest release from GitHub API.
pub async fn check_latest_version(current: &str) -> anyhow::Result<Version> {
let response = reqwest::get(LATEST_RELEASE_URL).await?;
let e = "Failed to get latest release.";
let url = response.url();
let segments = url.path_segments().ok_or_else(|| anyhow!(e))?;
let latest = segments.last().ok_or_else(|| anyhow!(e))?;
let result = if is_latest_version(current, latest) {
Version::Current
} else {
println!(
"You are not on the latest version: {} is available. \n{}",
latest, url
);
Version::Available
};
Ok(result)
}
// todo: naive implementation can be improved using semver
fn is_latest_version(current: &str, latest: &str) -> bool {
current == latest
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn it_compares_versions() {
assert!(is_latest_version("0.10.2", "0.10.2"));
assert!(!is_latest_version("0.10.2", "0.10.3"));
assert!(!is_latest_version("0.10.2", "0.11.0"));
}
#[tokio::test]
#[ignore = "For local testing, makes http requests to github."]
async fn it_compares_with_github() {
let result = check_latest_version("0.10.1").await.unwrap();
assert_eq!(result, Version::Available);
let result = check_latest_version("0.10.2").await.unwrap();
assert_eq!(result, Version::Current);
}
}

@ -19,6 +19,7 @@
pub mod asb;
pub mod bitcoin;
pub mod cli;
pub mod common;
pub mod database;
pub mod env;
pub mod fs;

Loading…
Cancel
Save