diff --git a/swap/src/bin/swap.rs b/swap/src/bin/swap.rs index 2acfb61a..580b7d23 100644 --- a/swap/src/bin/swap.rs +++ b/swap/src/bin/swap.rs @@ -68,6 +68,12 @@ async fn main() -> Result<()> { let swap_id = Uuid::new_v4(); cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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")?; @@ -158,6 +164,11 @@ async fn main() -> Result<()> { Command::History => { cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + let db = open_db(data_dir.join("sqlite")).await?; let swaps = db.all().await?; @@ -182,6 +193,11 @@ async fn main() -> Result<()> { Command::Config => { cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + tracing::info!(path=%data_dir.display(), "Data directory"); tracing::info!(path=%format!("{}/logs", data_dir.display()), "Log files directory"); tracing::info!(path=%format!("{}/sqlite", data_dir.display()), "Sqlite file location"); @@ -196,6 +212,12 @@ async fn main() -> Result<()> { address, } => { cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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 +251,12 @@ async fn main() -> Result<()> { bitcoin_target_block, } => { cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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 +283,12 @@ async fn main() -> Result<()> { namespace, } => { cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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 +355,12 @@ async fn main() -> Result<()> { bitcoin_target_block, } => { cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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 +383,12 @@ async fn main() -> Result<()> { bitcoin_target_block, } => { cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + 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 +414,11 @@ async fn main() -> Result<()> { .context("Rendezvous node address must contain peer ID")?; cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + let seed = Seed::from_file_or_generate(data_dir.as_path()) .context("Failed to read in seed file")?; let identity = seed.derive_libp2p_identity(); @@ -448,6 +499,11 @@ async fn main() -> Result<()> { } => { cli::tracing::init(debug, json, data_dir.join("logs"), None)?; + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + let seed = Seed::from_file_or_generate(data_dir.as_path()) .context("Failed to read in seed file")?; let bitcoin_wallet = init_bitcoin_wallet( @@ -462,6 +518,13 @@ 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))?; + + match check_latest_version().await { + Ok(()) => (), + Err(error) => tracing::error!("{}", error), + }; + let db = open_db(data_dir.join("sqlite")).await?; let swap_state: BobState = db.get_state(swap_id).await?.try_into()?; @@ -654,10 +717,43 @@ where Ok((btc_swap_amount, fees)) } +pub async fn check_latest_version() -> Result<()> { + const GITHUB_LATEST_VERSION_URL: &str = + "https://github.com/comit-network/xmr-btc-swap/releases/latest"; + + let response = match reqwest::get(GITHUB_LATEST_VERSION_URL).await { + Ok(res) => res, + Err(_) => bail!( + "could not request the website {}", + GITHUB_LATEST_VERSION_URL + ), + }; + + let last_version_from_url: &str = match response.url().path_segments() { + Some(split_segments) => match split_segments.last() { + Some(seg) => seg, + None => bail!("could not check the latest version"), + }, + None => bail!("could not check the latest version"), + }; + + let version_from_binary: &str = env!("CARGO_PKG_VERSION"); + + if last_version_from_url != version_from_binary { + tracing::warn!( + "You are not on the lastest version {}, it's available on Github: {}", + last_version_from_url, + GITHUB_LATEST_VERSION_URL + ); + }; + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; - use crate::determine_btc_to_swap; + use crate::{check_latest_version, determine_btc_to_swap}; use ::bitcoin::Amount; use std::sync::Mutex; use swap::tracing_ext::capture_logs; @@ -1034,4 +1130,13 @@ mod tests { async fn get_dummy_address() -> Result { Ok("1PdfytjS7C8wwd9Lq5o4x9aXA2YRqaCpH6".parse()?) } + + #[tokio::test] + async fn check_correct_latest_version() { + let writer = capture_logs(LevelFilter::INFO); + + check_latest_version().await.unwrap(); + + assert_eq!(writer.captured(), r""); + } }