fix: use lazy init for all swapper clients (#841)

This commit is contained in:
yse
2025-04-01 09:10:36 +02:00
committed by GitHub
parent e1fdbd19d2
commit 126bfc651b
4 changed files with 74 additions and 37 deletions

View File

@@ -22,6 +22,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
swap: &Swap,
refund_address: &str,
) -> Result<BtcSwapTx, SdkError> {
let bitcoin_client = self.get_bitcoin_client()?;
let refund_wrapper = match swap {
Swap::Chain(swap) => match swap.direction {
Direction::Incoming => {
@@ -29,7 +30,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
BtcSwapTx::new_refund(
swap_script.as_bitcoin_script()?,
refund_address,
&self.bitcoin_client,
bitcoin_client,
self.get_url().await?,
swap.id.clone(),
)
@@ -113,12 +114,13 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
swap: &ChainSwap,
claim_address: String,
) -> Result<Transaction, PaymentError> {
let bitcoin_client = self.get_bitcoin_client()?;
let claim_keypair = swap.get_claim_keypair()?;
let claim_swap_script = swap.get_claim_swap_script()?.as_bitcoin_script()?;
let claim_tx_wrapper = BtcSwapTx::new_claim(
claim_swap_script,
claim_address,
&self.bitcoin_client,
bitcoin_client,
self.get_url().await?,
swap.id.clone(),
)

View File

@@ -32,12 +32,13 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
swap: &ReceiveSwap,
claim_address: String,
) -> Result<Transaction, PaymentError> {
let liquid_client = self.get_liquid_client()?;
let swap_script = swap.get_swap_script()?;
let claim_tx_wrapper = LBtcSwapTx::new_claim(
swap_script,
claim_address,
&self.liquid_client,
liquid_client,
self.get_url().await?,
swap.id.clone(),
)
@@ -62,12 +63,13 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
swap: &ChainSwap,
claim_address: String,
) -> Result<Transaction, PaymentError> {
let liquid_client = self.get_liquid_client()?;
let claim_keypair = swap.get_claim_keypair()?;
let swap_script = swap.get_claim_swap_script()?.as_liquid_script()?;
let claim_tx_wrapper = LBtcSwapTx::new_claim(
swap_script,
claim_address,
&self.liquid_client,
liquid_client,
self.get_url().await?,
swap.id.clone(),
)
@@ -98,6 +100,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
swap: &Swap,
refund_address: &str,
) -> Result<LBtcSwapTx, SdkError> {
let liquid_client = self.get_liquid_client()?;
let refund_wrapper = match swap {
Swap::Chain(swap) => match swap.direction {
Direction::Incoming => {
@@ -111,7 +114,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
LBtcSwapTx::new_refund(
swap_script.as_liquid_script()?,
refund_address,
&self.liquid_client,
liquid_client,
self.get_url().await?,
swap.id.clone(),
)
@@ -123,7 +126,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
LBtcSwapTx::new_refund(
swap_script,
refund_address,
&self.liquid_client,
liquid_client,
self.get_url().await?,
swap.id.clone(),
)
@@ -146,6 +149,8 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
utxos: Vec<Utxo>,
is_cooperative: bool,
) -> Result<Transaction, SdkError> {
let liquid_client = self.get_liquid_client()?;
let (swap_script, refund_keypair) = match swap {
Swap::Chain(swap) => {
ensure_sdk!(
@@ -170,7 +175,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
let address = Address::from_str(refund_address)
.map_err(|err| SdkError::generic(format!("Could not parse address: {err:?}")))?;
let genesis_hash = self.liquid_client.get_genesis_hash().await?;
let genesis_hash = liquid_client.get_genesis_hash().await?;
let (funding_outpoint, funding_tx_out) =
*utxos

View File

@@ -5,7 +5,7 @@ use crate::{
model::LIQUID_FEE_RATE_SAT_PER_VBYTE,
prelude::{ChainSwap, Config, Direction, LiquidNetwork, SendSwap, Swap, Transaction, Utxo},
};
use anyhow::Result;
use anyhow::{anyhow, Result};
use boltz_client::{
boltz::{
self, BoltzApiClientV2, ChainPair, Cooperative, CreateChainRequest, CreateChainResponse,
@@ -38,9 +38,9 @@ pub(crate) struct BoltzClient {
pub struct BoltzSwapper<P: ProxyUrlFetcher> {
config: Config,
client: OnceLock<BoltzClient>,
liquid_client: LiquidClient,
bitcoin_client: BitcoinClient,
boltz_client: OnceLock<BoltzClient>,
liquid_client: OnceLock<LiquidClient>,
bitcoin_client: OnceLock<BitcoinClient>,
proxy_url: Arc<P>,
subscription_notifier: broadcast::Sender<String>,
update_notifier: broadcast::Sender<boltz::SwapStatus>,
@@ -53,17 +53,17 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
Ok(Self {
proxy_url,
client: OnceLock::new(),
config: config.clone(),
liquid_client: LiquidClient::new(&config)?,
bitcoin_client: BitcoinClient::new(&config)?,
boltz_client: OnceLock::new(),
liquid_client: OnceLock::new(),
bitcoin_client: OnceLock::new(),
subscription_notifier,
update_notifier,
})
}
async fn get_client(&self) -> Result<&BoltzClient> {
if let Some(client) = self.client.get() {
async fn get_boltz_client(&self) -> Result<&BoltzClient> {
if let Some(client) = self.boltz_client.get() {
return Ok(client);
}
@@ -77,16 +77,36 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
let boltz_url = boltz_api_base_url.unwrap_or(self.config.default_boltz_url().to_string());
let client = self.client.get_or_init(|| BoltzClient {
let boltz_client = self.boltz_client.get_or_init(|| BoltzClient {
inner: BoltzApiClientV2::new(&boltz_url),
url: boltz_url,
referral_id,
});
Ok(client)
Ok(boltz_client)
}
fn get_liquid_client(&self) -> Result<&LiquidClient> {
if let Some(client) = self.liquid_client.get() {
return Ok(client);
}
let liquid_client = LiquidClient::new(&self.config)
.map_err(|err| anyhow!("Could not create Boltz Liquid client: {err:?}"))?;
let liquid_client = self.liquid_client.get_or_init(|| liquid_client);
Ok(liquid_client)
}
fn get_bitcoin_client(&self) -> Result<&BitcoinClient> {
if let Some(client) = self.bitcoin_client.get() {
return Ok(client);
}
let bitcoin_client = BitcoinClient::new(&self.config)
.map_err(|err| anyhow!("Could not create Boltz Bitcoin client: {err:?}"))?;
let bitcoin_client = self.bitcoin_client.get_or_init(|| bitcoin_client);
Ok(bitcoin_client)
}
async fn get_url(&self) -> Result<String> {
Ok(self.get_client().await?.url.clone())
Ok(self.get_boltz_client().await?.url.clone())
}
async fn get_claim_partial_sig(
@@ -100,7 +120,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
let lockup_address = &swap.lockup_address;
let claim_tx_details = self
.get_client()
.get_boltz_client()
.await?
.inner
.get_chain_claim_tx_details(&swap.id)
@@ -139,7 +159,7 @@ impl<P: ProxyUrlFetcher> BoltzSwapper<P> {
partial_sig: Option<MusigPartialSignature>,
) -> Result<Option<Cooperative>> {
Ok(Some(Cooperative {
boltz_api: &self.get_client().await?.inner,
boltz_api: &self.get_boltz_client().await?.inner,
swap_id,
pub_nonce,
partial_sig,
@@ -154,7 +174,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
&self,
req: CreateChainRequest,
) -> Result<CreateChainResponse, PaymentError> {
let client = self.get_client().await?;
let client = self.get_boltz_client().await?;
let modified_req = CreateChainRequest {
referral_id: client.referral_id.clone(),
..req.clone()
@@ -167,7 +187,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
&self,
req: CreateSubmarineRequest,
) -> Result<CreateSubmarineResponse, PaymentError> {
let client = self.get_client().await?;
let client = self.get_boltz_client().await?;
let modified_req = CreateSubmarineRequest {
referral_id: client.referral_id.clone(),
..req.clone()
@@ -179,7 +199,12 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
&self,
direction: Direction,
) -> Result<Option<ChainPair>, PaymentError> {
let pairs = self.get_client().await?.inner.get_chain_pairs().await?;
let pairs = self
.get_boltz_client()
.await?
.inner
.get_chain_pairs()
.await?;
let pair = match direction {
Direction::Incoming => pairs.get_btc_to_lbtc_pair(),
Direction::Outgoing => pairs.get_lbtc_to_btc_pair(),
@@ -190,14 +215,19 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
async fn get_chain_pairs(
&self,
) -> Result<(Option<ChainPair>, Option<ChainPair>), PaymentError> {
let pairs = self.get_client().await?.inner.get_chain_pairs().await?;
let pairs = self
.get_boltz_client()
.await?
.inner
.get_chain_pairs()
.await?;
let pair_outgoing = pairs.get_lbtc_to_btc_pair();
let pair_incoming = pairs.get_btc_to_lbtc_pair();
Ok((pair_outgoing, pair_incoming))
}
async fn get_zero_amount_chain_swap_quote(&self, swap_id: &str) -> Result<Amount, SdkError> {
self.get_client()
self.get_boltz_client()
.await?
.inner
.get_quote(swap_id)
@@ -211,7 +241,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
swap_id: &str,
server_lockup_sat: u64,
) -> Result<(), PaymentError> {
self.get_client()
self.get_boltz_client()
.await?
.inner
.accept_quote(swap_id, server_lockup_sat)
@@ -222,7 +252,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
/// Get a submarine pair information
async fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError> {
Ok(self
.get_client()
.get_boltz_client()
.await?
.inner
.get_submarine_pairs()
@@ -233,7 +263,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
/// Get a submarine swap's preimage
async fn get_submarine_preimage(&self, swap_id: &str) -> Result<String, PaymentError> {
Ok(self
.get_client()
.get_boltz_client()
.await?
.inner
.get_submarine_preimage(swap_id)
@@ -249,7 +279,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
swap: &SendSwap,
) -> Result<SubmarineClaimTxResponse, PaymentError> {
let claim_tx_response = self
.get_client()
.get_boltz_client()
.await?
.inner
.get_submarine_claim_tx_details(&swap.id)
@@ -282,7 +312,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
&claim_tx_response.transaction_hash,
)?;
self.get_client()
self.get_boltz_client()
.await?
.inner
.post_submarine_claim_tx_details(&swap_id.to_string(), pub_nonce, partial_sig)
@@ -296,7 +326,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
&self,
req: CreateReverseRequest,
) -> Result<CreateReverseResponse, PaymentError> {
let client = self.get_client().await?;
let client = self.get_boltz_client().await?;
let modified_req = CreateReverseRequest {
referral_id: client.referral_id.clone(),
..req.clone()
@@ -307,7 +337,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
// Get a reverse pair information
async fn get_reverse_swap_pairs(&self) -> Result<Option<ReversePair>, PaymentError> {
Ok(self
.get_client()
.get_boltz_client()
.await?
.inner
.get_reverse_pairs()
@@ -455,7 +485,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
async fn broadcast_tx(&self, chain: Chain, tx_hex: &str) -> Result<String, PaymentError> {
let response = self
.get_client()
.get_boltz_client()
.await?
.inner
.broadcast_tx(chain, &tx_hex.into())
@@ -474,7 +504,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
async fn check_for_mrh(&self, invoice: &str) -> Result<Option<(String, Amount)>, PaymentError> {
boltz_client::swaps::magic_routing::check_for_mrh(
&self.get_client().await?.inner,
&self.get_boltz_client().await?.inner,
invoice,
self.config.network.into(),
)
@@ -488,7 +518,7 @@ impl<P: ProxyUrlFetcher> Swapper for BoltzSwapper<P> {
amount_sat: u64,
) -> Result<String, PaymentError> {
let invoice_res = self
.get_client()
.get_boltz_client()
.await?
.inner
.get_bolt12_invoice(offer, amount_sat)

View File

@@ -48,7 +48,7 @@ impl<P: ProxyUrlFetcher> SwapperStatusStream for BoltzSwapper<P> {
tokio::spawn(async move {
loop {
debug!("Start of ws stream loop");
let client = match swapper.get_client().await {
let client = match swapper.get_boltz_client().await {
Ok(client) => client,
Err(e) => {
warn!("Failed to get swapper client: {e:?}");