Skip to content
This repository has been archived by the owner on Feb 3, 2025. It is now read-only.

Commit

Permalink
Retry wallet lock for syncing on-chain wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Jun 19, 2023
1 parent 0fb1cf4 commit 3e8a0d1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 13 deletions.
3 changes: 3 additions & 0 deletions mutiny-core/src/keymanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ mod tests {
use bitcoin::Network;
use esplora_client::Builder;
use std::str::FromStr;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;

#[test]
Expand All @@ -270,6 +271,7 @@ mod tests {
esplora.clone(),
logger.clone(),
));
let stop = Arc::new(AtomicBool::new(false));

let wallet = Arc::new(
OnChainWallet::new(
Expand All @@ -278,6 +280,7 @@ mod tests {
Network::Testnet,
esplora,
fees,
stop,
logger.clone(),
)
.unwrap(),
Expand Down
1 change: 1 addition & 0 deletions mutiny-core/src/nodemanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ impl<S: MutinyStorage> NodeManager<S> {
network,
esplora.clone(),
fee_estimator.clone(),
stop.clone(),
logger.clone(),
)?);

Expand Down
46 changes: 33 additions & 13 deletions mutiny-core/src/onchain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::anyhow;
use std::collections::HashSet;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock};

use bdk::chain::{BlockId, ConfirmationTime};
Expand All @@ -22,6 +23,7 @@ use crate::fees::MutinyFeeEstimator;
use crate::labels::*;
use crate::logging::MutinyLogger;
use crate::storage::{MutinyStorage, OnChainStorage};
use crate::utils::sleep;

#[derive(Clone)]
pub struct OnChainWallet<S: MutinyStorage> {
Expand All @@ -30,6 +32,7 @@ pub struct OnChainWallet<S: MutinyStorage> {
pub network: Network,
pub blockchain: Arc<AsyncClient>,
pub fees: Arc<MutinyFeeEstimator<S>>,
pub(crate) stop: Arc<AtomicBool>,
logger: Arc<MutinyLogger>,
}

Expand All @@ -40,6 +43,7 @@ impl<S: MutinyStorage> OnChainWallet<S> {
network: Network,
esplora: Arc<AsyncClient>,
fees: Arc<MutinyFeeEstimator<S>>,
stop: Arc<AtomicBool>,
logger: Arc<MutinyLogger>,
) -> Result<OnChainWallet<S>, MutinyError> {
let seed = mnemonic.to_seed("");
Expand All @@ -61,6 +65,7 @@ impl<S: MutinyStorage> OnChainWallet<S> {
network,
blockchain: esplora,
fees,
stop,
logger,
})
}
Expand Down Expand Up @@ -115,23 +120,37 @@ impl<S: MutinyStorage> OnChainWallet<S> {
.await?;

// get new wallet lock for writing and apply the update
match self.wallet.try_write() {
Ok(mut wallet) => match wallet.apply_update(update) {
Ok(_) => wallet.commit()?,
for _ in 0..10 {
match self.wallet.try_write() {
Ok(mut wallet) => match wallet.apply_update(update) {
Ok(_) => {
wallet.commit()?;
return Ok(());
}
Err(e) => {
// failed to apply wallet update
log_error!(self.logger, "Could not apply wallet update: {e}");
return Err(MutinyError::Other(anyhow!("Could not apply update: {e}")));
}
},
Err(e) => {
// failed to apply wallet update
log_error!(self.logger, "Could not apply wallet update: {e}");
return Err(MutinyError::Other(anyhow!("Could not apply update: {e}")));
// if we can't get the lock, we just return and try again later
log_error!(
self.logger,
"Could not get wallet lock: {e}, retrying in 250ms"
);

if self.stop.load(Ordering::Relaxed) {
return Err(MutinyError::NotRunning);
};

sleep(250).await;
}
},
Err(e) => {
// if we can't get the lock, we just return and try again later
log_error!(self.logger, "Could not get wallet lock: {e}");
return Ok(());
}
}

Ok(())
log_error!(self.logger, "Could not get wallet lock after 10 retries");
Err(MutinyError::WalletOperationFailed)
}

pub(crate) async fn insert_tx(
Expand Down Expand Up @@ -499,8 +518,9 @@ mod tests {
esplora.clone(),
logger.clone(),
));
let stop = Arc::new(AtomicBool::new(false));

OnChainWallet::new(&mnemonic, db, Network::Testnet, esplora, fees, logger).unwrap()
OnChainWallet::new(&mnemonic, db, Network::Testnet, esplora, fees, stop, logger).unwrap()
}

#[test]
Expand Down

0 comments on commit 3e8a0d1

Please sign in to comment.