mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-04-20 07:56:05 -04:00
Merge 82cbea49186b3c39463ca0aa14879498a67b5171 into 2b850924b1118492c1e9de4053971758971a376d
This commit is contained in:
commit
1adc5ee3d5
@ -30,14 +30,27 @@ use uuid::Uuid;
|
||||
|
||||
pub mod transport {
|
||||
use super::*;
|
||||
use crate::network::tor_transport::TorDialOnlyTransport;
|
||||
use libp2p::core::transport::OptionalTransport;
|
||||
|
||||
/// Creates the libp2p transport for the ASB.
|
||||
pub fn new(identity: &identity::Keypair) -> Result<Boxed<(PeerId, StreamMuxerBox)>> {
|
||||
pub fn new(
|
||||
identity: &identity::Keypair,
|
||||
maybe_tor_socks5_port: Option<u16>,
|
||||
) -> Result<Boxed<(PeerId, StreamMuxerBox)>> {
|
||||
let tcp = TokioTcpConfig::new().nodelay(true);
|
||||
let tcp_with_dns = TokioDnsConfig::system(tcp)?;
|
||||
let websocket_with_dns = WsConfig::new(tcp_with_dns.clone());
|
||||
|
||||
let transport = tcp_with_dns.or_transport(websocket_with_dns).boxed();
|
||||
let maybe_tor_transport = match maybe_tor_socks5_port {
|
||||
Some(port) => OptionalTransport::some(TorDialOnlyTransport::new(port)),
|
||||
None => OptionalTransport::none(),
|
||||
};
|
||||
|
||||
let transport = maybe_tor_transport
|
||||
.or_transport(tcp_with_dns)
|
||||
.or_transport(websocket_with_dns)
|
||||
.boxed();
|
||||
|
||||
authenticate_and_multiplex(transport, identity)
|
||||
}
|
||||
|
@ -100,6 +100,36 @@ async fn main() -> Result<()> {
|
||||
let seed =
|
||||
Seed::from_file_or_generate(&config.data.dir).expect("Could not retrieve/initialize seed");
|
||||
|
||||
let tor_client =
|
||||
tor::Client::new(config.tor.socks5_port).with_control_port(config.tor.control_port);
|
||||
let _ac = match tor_client.assert_tor_running().await {
|
||||
Ok(_) => {
|
||||
tracing::info!("Setting up Tor hidden service");
|
||||
let ac =
|
||||
register_tor_services(config.network.clone().listen, tor_client, &seed).await?;
|
||||
Some(ac)
|
||||
}
|
||||
Err(_) => {
|
||||
tracing::warn!("Tor not found. Running on clear net");
|
||||
None
|
||||
}
|
||||
};
|
||||
let tor_port = if _ac.is_some() {
|
||||
config.tor.socks5_port
|
||||
} else {
|
||||
0u16
|
||||
};
|
||||
let proxy_string = if tor_port != 0u16 {
|
||||
format!("127.0.0.1:{}", tor_port)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
if proxy_string.is_empty() {
|
||||
tracing::info!(%proxy_string, "Not using SOCKS5 proxy");
|
||||
} else {
|
||||
tracing::info!(%proxy_string, "Using SOCKS5 proxy at");
|
||||
}
|
||||
|
||||
match cmd {
|
||||
Command::Start { resume_only } => {
|
||||
// check and warn for duplicate rendezvous points
|
||||
@ -140,29 +170,13 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||
tracing::info!(%bitcoin_balance, "Bitcoin wallet balance");
|
||||
|
||||
let kraken_price_updates = kraken::connect(config.maker.price_ticker_ws_url.clone())?;
|
||||
|
||||
// setup Tor hidden services
|
||||
let tor_client =
|
||||
tor::Client::new(config.tor.socks5_port).with_control_port(config.tor.control_port);
|
||||
let _ac = match tor_client.assert_tor_running().await {
|
||||
Ok(_) => {
|
||||
tracing::info!("Setting up Tor hidden service");
|
||||
let ac =
|
||||
register_tor_services(config.network.clone().listen, tor_client, &seed)
|
||||
.await?;
|
||||
Some(ac)
|
||||
}
|
||||
Err(_) => {
|
||||
tracing::warn!("Tor not found. Running on clear net");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let kraken_rate = KrakenRate::new(config.maker.ask_spread, kraken_price_updates);
|
||||
let namespace = XmrBtcNamespace::from_is_testnet(testnet);
|
||||
|
||||
@ -175,7 +189,9 @@ async fn main() -> Result<()> {
|
||||
env_config,
|
||||
namespace,
|
||||
&rendezvous_addrs,
|
||||
)?;
|
||||
tor_port,
|
||||
)
|
||||
.await?;
|
||||
|
||||
for listen in config.network.listen.clone() {
|
||||
Swarm::listen_on(&mut swarm, listen.clone())
|
||||
@ -241,7 +257,8 @@ async fn main() -> Result<()> {
|
||||
println!("{}", config_json);
|
||||
}
|
||||
Command::WithdrawBtc { amount, address } => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
|
||||
let amount = match amount {
|
||||
Some(amount) => amount,
|
||||
@ -264,20 +281,23 @@ async fn main() -> Result<()> {
|
||||
let monero_balance = monero_wallet.get_balance().await?;
|
||||
tracing::info!(%monero_balance);
|
||||
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||
tracing::info!(%bitcoin_balance);
|
||||
tracing::info!(%bitcoin_balance, %monero_balance, "Current balance");
|
||||
}
|
||||
Command::Cancel { swap_id } => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
|
||||
let (txid, _) = cancel(swap_id, Arc::new(bitcoin_wallet), db).await?;
|
||||
|
||||
tracing::info!("Cancel transaction successfully published with id {}", txid);
|
||||
}
|
||||
Command::Refund { swap_id } => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
let monero_wallet = init_monero_wallet(&config, env_config).await?;
|
||||
|
||||
refund(
|
||||
@ -291,7 +311,8 @@ async fn main() -> Result<()> {
|
||||
tracing::info!("Monero successfully refunded");
|
||||
}
|
||||
Command::Punish { swap_id } => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
|
||||
let (txid, _) = punish(swap_id, Arc::new(bitcoin_wallet), db).await?;
|
||||
|
||||
@ -306,7 +327,8 @@ async fn main() -> Result<()> {
|
||||
swap_id,
|
||||
do_not_await_finality,
|
||||
} => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
|
||||
let (txid, _) = redeem(
|
||||
swap_id,
|
||||
@ -319,7 +341,8 @@ async fn main() -> Result<()> {
|
||||
tracing::info!("Redeem transaction successfully published with id {}", txid);
|
||||
}
|
||||
Command::ExportBitcoinWallet => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let bitcoin_wallet =
|
||||
init_bitcoin_wallet(&config, &seed, env_config, proxy_string).await?;
|
||||
let wallet_export = bitcoin_wallet.wallet_export("asb").await?;
|
||||
println!("{}", wallet_export.to_string())
|
||||
}
|
||||
@ -332,11 +355,13 @@ async fn init_bitcoin_wallet(
|
||||
config: &Config,
|
||||
seed: &Seed,
|
||||
env_config: swap::env::Config,
|
||||
proxy_string: String,
|
||||
) -> Result<bitcoin::Wallet> {
|
||||
tracing::debug!("Opening Bitcoin wallet");
|
||||
let data_dir = &config.data.dir;
|
||||
let wallet = bitcoin::Wallet::new(
|
||||
config.bitcoin.electrum_rpc_url.clone(),
|
||||
proxy_string.as_str(),
|
||||
data_dir,
|
||||
seed.derive_extended_private_key(env_config.bitcoin_network)?,
|
||||
env_config,
|
||||
|
@ -505,6 +505,7 @@ async fn init_bitcoin_wallet(
|
||||
|
||||
let wallet = bitcoin::Wallet::new(
|
||||
electrum_rpc_url.clone(),
|
||||
"",
|
||||
data_dir,
|
||||
xprivkey,
|
||||
env_config,
|
||||
|
@ -6,7 +6,7 @@ use ::bitcoin::Txid;
|
||||
use anyhow::{bail, Context, Result};
|
||||
use bdk::blockchain::{Blockchain, ElectrumBlockchain, GetTx};
|
||||
use bdk::database::BatchDatabase;
|
||||
use bdk::electrum_client::{ElectrumApi, GetHistoryRes};
|
||||
use bdk::electrum_client::{ElectrumApi, GetHistoryRes, Socks5Config};
|
||||
use bdk::sled::Tree;
|
||||
use bdk::wallet::export::FullyNodedExport;
|
||||
use bdk::wallet::AddressIndex;
|
||||
@ -20,6 +20,7 @@ use rust_decimal_macros::dec;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::ops::Not;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
@ -47,6 +48,7 @@ pub struct Wallet<D = Tree, C = Client> {
|
||||
impl Wallet {
|
||||
pub async fn new(
|
||||
electrum_rpc_url: Url,
|
||||
electrum_socks5_proxy_string: &str,
|
||||
data_dir: impl AsRef<Path>,
|
||||
xprivkey: ExtendedPrivKey,
|
||||
env_config: env::Config,
|
||||
@ -70,7 +72,11 @@ impl Wallet {
|
||||
err => err?,
|
||||
};
|
||||
|
||||
let client = Client::new(electrum_rpc_url, env_config.bitcoin_sync_interval())?;
|
||||
let client = Client::new(
|
||||
electrum_rpc_url,
|
||||
electrum_socks5_proxy_string,
|
||||
env_config.bitcoin_sync_interval(),
|
||||
)?;
|
||||
|
||||
let network = wallet.network();
|
||||
|
||||
@ -723,20 +729,32 @@ pub struct Client {
|
||||
}
|
||||
|
||||
impl Client {
|
||||
fn new(electrum_rpc_url: Url, interval: Duration) -> Result<Self> {
|
||||
let config = bdk::electrum_client::ConfigBuilder::default()
|
||||
.retry(5)
|
||||
.build();
|
||||
let electrum = bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config)
|
||||
.context("Failed to initialize Electrum RPC client")?;
|
||||
fn new(
|
||||
electrum_rpc_url: Url,
|
||||
electrum_socks5_proxy_string: &str,
|
||||
interval: Duration,
|
||||
) -> Result<Self> {
|
||||
let mut config_builder = bdk::electrum_client::ConfigBuilder::default().retry(5);
|
||||
if electrum_socks5_proxy_string.is_empty().not() {
|
||||
config_builder = config_builder
|
||||
.socks5(Option::from(Socks5Config::new(
|
||||
electrum_socks5_proxy_string.to_string(),
|
||||
)))
|
||||
.unwrap() // use Tor with the Electrum client
|
||||
}
|
||||
let config = config_builder.build();
|
||||
let electrum =
|
||||
bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config.clone())
|
||||
.context("Failed to initialize Electrum RPC client")?;
|
||||
// Initially fetch the latest block for storing the height.
|
||||
// We do not act on this subscription after this call.
|
||||
let latest_block = electrum
|
||||
.block_headers_subscribe()
|
||||
.context("Failed to subscribe to header notifications")?;
|
||||
|
||||
let client = bdk::electrum_client::Client::new(electrum_rpc_url.as_str())
|
||||
.context("Failed to initialize Electrum RPC client")?;
|
||||
let client =
|
||||
bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config.clone())
|
||||
.context("Failed to initialize Electrum RPC client")?;
|
||||
let blockchain = ElectrumBlockchain::from(client);
|
||||
let last_sync = Instant::now()
|
||||
.checked_sub(interval)
|
||||
|
@ -9,7 +9,7 @@ use libp2p::{identity, Multiaddr, Swarm};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn asb<LR>(
|
||||
pub async fn asb<LR>(
|
||||
seed: &Seed,
|
||||
min_buy: bitcoin::Amount,
|
||||
max_buy: bitcoin::Amount,
|
||||
@ -18,10 +18,16 @@ pub fn asb<LR>(
|
||||
env_config: env::Config,
|
||||
namespace: XmrBtcNamespace,
|
||||
rendezvous_addrs: &[Multiaddr],
|
||||
tor_socks5_port: u16,
|
||||
) -> Result<Swarm<asb::Behaviour<LR>>>
|
||||
where
|
||||
LR: LatestRate + Send + 'static + Debug + Clone,
|
||||
{
|
||||
let maybe_tor_socks5_port = match tor::Client::new(tor_socks5_port).assert_tor_running().await {
|
||||
Ok(()) => Some(tor_socks5_port),
|
||||
Err(_) => None,
|
||||
};
|
||||
|
||||
let identity = seed.derive_libp2p_identity();
|
||||
|
||||
let rendezvous_nodes = rendezvous_addrs
|
||||
@ -45,7 +51,7 @@ where
|
||||
rendezvous_nodes,
|
||||
);
|
||||
|
||||
let transport = asb::transport::new(&identity)?;
|
||||
let transport = asb::transport::new(&identity, maybe_tor_socks5_port)?;
|
||||
let peer_id = identity.public().into();
|
||||
|
||||
let swarm = SwarmBuilder::new(transport, behaviour, peer_id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user