From 55fe7c71b08c0b4be1ada09e49714014eb471434 Mon Sep 17 00:00:00 2001 From: Roei Erez Date: Sun, 9 Jun 2024 13:36:44 +0300 Subject: [PATCH] extract out ChainService --- lib/core/src/model.rs | 11 +---------- lib/core/src/sdk.rs | 36 ++++++++++++++++-------------------- lib/core/src/send_swap.rs | 17 ++++++++++------- lib/core/src/swapper/mod.rs | 23 +++++++++++++++-------- 4 files changed, 42 insertions(+), 45 deletions(-) diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index fd14231..eff1a3d 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -1,12 +1,11 @@ use anyhow::{anyhow, Result}; -use boltz_client::network::electrum::ElectrumConfig; use boltz_client::network::Chain; use boltz_client::swaps::boltzv2::{ CreateReverseResponse, CreateSubmarineResponse, Leaf, SwapTree, BOLTZ_MAINNET_URL_V2, BOLTZ_TESTNET_URL_V2, }; use boltz_client::{Keypair, LBtcSwapScriptV2, ToHex}; -use lwk_wollet::{ElectrumClient, ElectrumUrl, ElementsNetwork}; +use lwk_wollet::ElementsNetwork; use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef}; use rusqlite::ToSql; use serde::{Deserialize, Serialize}; @@ -28,14 +27,6 @@ pub struct Config { pub payment_timeout_sec: u64, } impl Config { - pub(crate) fn get_electrum_client(&self) -> Result { - ElectrumClient::new(&ElectrumUrl::new(&self.electrum_url, true, true)) - } - - pub(crate) fn get_electrum_config(&self) -> ElectrumConfig { - ElectrumConfig::new(self.network.into(), &self.electrum_url, true, true, 100) - } - pub fn mainnet() -> Self { Config { boltz_url: BOLTZ_MAINNET_URL_V2.to_owned(), diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index 58de935..374fab5 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -20,6 +20,7 @@ use log::{debug, error, info, warn}; use lwk_wollet::bitcoin::hex::DisplayHex; use lwk_wollet::hashes::{sha256, Hash}; use lwk_wollet::{elements::LockTime, ElementsNetwork}; +use lwk_wollet::{BlockchainBackend, ElectrumClient, ElectrumUrl}; use tokio::sync::{watch, RwLock}; use tokio::time::MissedTickBehavior; use tokio_stream::wrappers::BroadcastStream; @@ -46,6 +47,9 @@ pub const LIQUID_CLAIM_TX_FEERATE_MSAT: f32 = 100.0; pub const DEFAULT_DATA_DIR: &str = ".data"; +pub(crate) trait ChainService: Send + Sync + BlockchainBackend {} +impl ChainService for ElectrumClient {} + pub struct LiquidSdk { config: Config, onchain_wallet: Arc, @@ -81,13 +85,22 @@ impl LiquidSdk { let swapper = Arc::new(BoltzSwapper::new(config.clone())); let status_stream = Arc::::from(swapper.create_status_stream()); + let chain_service = Arc::new(ElectrumClient::new(&ElectrumUrl::new( + &config.electrum_url, + true, + true, + ))?); + let onchain_wallet = Arc::new(LiquidOnchainWallet::new(mnemonic, config.clone())?); + let send_swap_state_handler = SendSwapStateHandler::new( config.clone(), onchain_wallet.clone(), persister.clone(), swapper.clone(), + chain_service.clone(), ); + let receive_swap_state_handler = ReceiveSwapStateHandler::new( onchain_wallet.clone(), persister.clone(), @@ -286,13 +299,7 @@ impl LiquidSdk { let id = &send_swap.id; let refund_tx_id = self.try_refund(send_swap).await?; info!("Broadcast refund tx for Send Swap {id}. Tx id: {refund_tx_id}"); - let send_swap_state_handler = SendSwapStateHandler::new( - self.config.clone(), - self.onchain_wallet.clone(), - self.persister.clone(), - self.swapper.clone(), - ); - send_swap_state_handler + self.send_swap_state_handler .update_swap_info(id, Pending, None, None, Some(&refund_tx_id)) .await?; } @@ -765,12 +772,7 @@ impl LiquidSdk { let mut events_stream = self.event_manager.subscribe(); let mut maybe_payment: Option = None; - let send_swap_state_handler = SendSwapStateHandler::new( - self.config.clone(), - self.onchain_wallet.clone(), - self.persister.clone(), - self.swapper.clone(), - ); + let send_swap_state_handler = self.send_swap_state_handler.clone(); loop { tokio::select! { @@ -970,12 +972,6 @@ impl LiquidSdk { let pending_send_swaps_by_refund_tx_id = self.persister.list_pending_send_swaps_by_refund_tx_id()?; - let send_swap_state_handler = SendSwapStateHandler::new( - self.config.clone(), - self.onchain_wallet.clone(), - self.persister.clone(), - self.swapper.clone(), - ); for tx in self.onchain_wallet.transactions().await? { let tx_id = tx.txid.to_string(); let is_tx_confirmed = tx.height.is_some(); @@ -1001,7 +997,7 @@ impl LiquidSdk { } } else if let Some(swap) = pending_send_swaps_by_refund_tx_id.get(&tx_id) { if is_tx_confirmed { - send_swap_state_handler + self.send_swap_state_handler .update_swap_info(&swap.id, Failed, None, None, None) .await?; } diff --git a/lib/core/src/send_swap.rs b/lib/core/src/send_swap.rs index b72c87b..14a863d 100644 --- a/lib/core/src/send_swap.rs +++ b/lib/core/src/send_swap.rs @@ -8,11 +8,11 @@ use log::{debug, error, info, warn}; use lwk_wollet::bitcoin::Witness; use lwk_wollet::elements::Transaction; use lwk_wollet::hashes::{sha256, Hash}; -use lwk_wollet::BlockchainBackend; use tokio::sync::broadcast; use crate::model::PaymentState::{Complete, Created, Failed, Pending, TimedOut}; use crate::model::{Config, SendSwap}; +use crate::sdk::ChainService; use crate::swapper::Swapper; use crate::wallet::OnchainWallet; use crate::{ensure_sdk, get_invoice_amount}; @@ -21,12 +21,13 @@ use crate::{ model::{PaymentState, PaymentTxData, PaymentType}, persist::Persister, }; - +#[derive(Clone)] pub(crate) struct SendSwapStateHandler { config: Config, onchain_wallet: Arc, persister: Arc, swapper: Arc, + chain_service: Arc, subscription_notifier: broadcast::Sender, } @@ -36,6 +37,7 @@ impl SendSwapStateHandler { onchain_wallet: Arc, persister: Arc, swapper: Arc, + chain_service: Arc, ) -> Self { let (subscription_notifier, _) = broadcast::channel::(30); Self { @@ -43,6 +45,7 @@ impl SendSwapStateHandler { onchain_wallet, persister, swapper, + chain_service, subscription_notifier, } } @@ -194,8 +197,7 @@ impl SendSwapStateHandler { ) .await?; - let electrum_client = self.config.get_electrum_client()?; - let lockup_tx_id = electrum_client.broadcast(&lockup_tx)?.to_string(); + let lockup_tx_id = self.chain_service.broadcast(&lockup_tx)?.to_string(); debug!("Successfully broadcast lockup tx for Send Swap {swap_id}. Lockup tx id: {lockup_tx_id}"); Ok(lockup_tx) @@ -262,7 +264,6 @@ impl SendSwapStateHandler { info!("Retrieving preimage from non-cooperative claim tx"); let id = &swap.id; - let electrum_client = self.config.get_electrum_client()?; let swap_script = swap.get_swap_script()?; let swap_script_pk = swap_script .to_address(self.config.network.into())? @@ -270,7 +271,8 @@ impl SendSwapStateHandler { debug!("Found Send Swap swap_script_pk: {swap_script_pk:?}"); // Get tx history of the swap script (lockup address) - let history: Vec<_> = electrum_client + let history: Vec<_> = self + .chain_service .get_scripts_history(&[&swap_script_pk])? .into_iter() .flatten() @@ -292,7 +294,8 @@ impl SendSwapStateHandler { let claim_tx_id = claim_tx_entry.txid; debug!("Send Swap {id} has claim tx {claim_tx_id}"); - let claim_tx = electrum_client + let claim_tx = self + .chain_service .get_transactions(&[claim_tx_id]) .map_err(|e| anyhow!("Failed to fetch claim tx {claim_tx_id}: {e}"))? .first() diff --git a/lib/core/src/swapper/mod.rs b/lib/core/src/swapper/mod.rs index 192012a..a0d1375 100644 --- a/lib/core/src/swapper/mod.rs +++ b/lib/core/src/swapper/mod.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use anyhow::Result; use async_trait::async_trait; use boltz_client::error::Error; +use boltz_client::network::electrum::ElectrumConfig; use boltz_client::network::Chain; use boltz_client::swaps::boltzv2::{ self, BoltzApiClientV2, ClaimTxResponse, CreateReverseRequest, CreateReverseResponse, @@ -108,13 +109,21 @@ pub trait Swapper: Send + Sync { pub struct BoltzSwapper { client: BoltzApiClientV2, config: Config, + electrum_config: ElectrumConfig, } impl BoltzSwapper { pub fn new(config: Config) -> BoltzSwapper { BoltzSwapper { client: BoltzApiClientV2::new(&config.boltz_url), - config, + config: config.clone(), + electrum_config: ElectrumConfig::new( + config.network.into(), + &config.electrum_url, + true, + true, + 100, + ), } } @@ -128,7 +137,7 @@ impl BoltzSwapper { Ok(LBtcSwapTxV2::new_refund( swap_script.clone(), output_address, - &self.config.get_electrum_config(), + &self.electrum_config, self.config.boltz_url.clone(), swap.id.to_string(), )?) @@ -194,8 +203,7 @@ impl Swapper for BoltzSwapper { Network::Mainnet => None, Network::Testnet => Some((&self.client, boltz_client::network::Chain::LiquidTestnet)), }; - let refund_tx_id = - refund_tx.broadcast(&tx, &self.config.get_electrum_config(), is_lowball)?; + let refund_tx_id = refund_tx.broadcast(&tx, &self.electrum_config, is_lowball)?; info!( "Successfully broadcast cooperative refund for Send Swap {}", &swap.id @@ -239,8 +247,7 @@ impl Swapper for BoltzSwapper { Network::Mainnet => None, Network::Testnet => Some((&self.client, boltz_client::network::Chain::LiquidTestnet)), }; - let refund_tx_id = - refund_tx.broadcast(&tx, &self.config.get_electrum_config(), is_lowball)?; + let refund_tx_id = refund_tx.broadcast(&tx, &self.electrum_config, is_lowball)?; info!( "Successfully broadcast non-cooperative refund for swap-in {}", swap.id @@ -305,7 +312,7 @@ impl Swapper for BoltzSwapper { let claim_tx_wrapper = LBtcSwapTxV2::new_claim( swap_script, claim_address, - &self.config.get_electrum_config(), + &self.electrum_config, self.config.boltz_url.clone(), swap.id.clone(), )?; @@ -322,7 +329,7 @@ impl Swapper for BoltzSwapper { let claim_tx_id = claim_tx_wrapper.broadcast( &claim_tx, - &self.config.get_electrum_config(), + &self.electrum_config, Some((&self.client, self.config.network.into())), )?; info!("Successfully broadcast claim tx {claim_tx_id} for Receive Swap {swap_id}");