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

Commit 85c056a

Browse files
Merge pull request #700 from MutinyWallet/revert-696-less-efficient-esplora
Revert "Revert "More effienct esplora syncing (#690)""
2 parents 225edc3 + ef145b7 commit 85c056a

File tree

4 files changed

+95
-4
lines changed

4 files changed

+95
-4
lines changed

mutiny-core/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub use crate::ldkstorage::{CHANNEL_MANAGER_KEY, MONITORS_PREFIX_KEY};
4848
use crate::auth::MutinyAuthClient;
4949
use crate::labels::{Contact, LabelStorage};
5050
use crate::nostr::nwc::SpendingConditions;
51-
use crate::storage::MutinyStorage;
51+
use crate::storage::{MutinyStorage, NEED_FULL_SYNC_KEY};
5252
use crate::{error::MutinyError, nostr::ReservedProfile};
5353
use crate::{nodemanager::NodeManager, nostr::ProfileType};
5454
use crate::{nostr::NostrManager, utils::sleep};
@@ -163,6 +163,15 @@ impl<S: MutinyStorage> MutinyWallet<S> {
163163
// start the nostr wallet connect background process
164164
mw.start_nostr_wallet_connect(first_node).await;
165165

166+
#[cfg(not(test))]
167+
{
168+
// if we need a full sync from a restore
169+
if mw.storage.get(NEED_FULL_SYNC_KEY)?.unwrap_or_default() {
170+
mw.node_manager.wallet.full_sync().await?;
171+
mw.storage.delete(&[NEED_FULL_SYNC_KEY])?;
172+
}
173+
}
174+
166175
Ok(mw)
167176
}
168177

@@ -439,6 +448,8 @@ impl<S: MutinyStorage> MutinyWallet<S> {
439448

440449
self.start().await?;
441450

451+
self.node_manager.wallet.full_sync().await?;
452+
442453
Ok(())
443454
}
444455

@@ -451,6 +462,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
451462
S::clear().await?;
452463
storage.start().await?;
453464
storage.insert_mnemonic(m)?;
465+
storage.set_data(NEED_FULL_SYNC_KEY, true, None)?;
454466
Ok(())
455467
}
456468
}

mutiny-core/src/nodemanager.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::scb::{
1212
EncryptedSCB, StaticChannelBackup, StaticChannelBackupStorage,
1313
SCB_ENCRYPTION_KEY_DERIVATION_PATH,
1414
};
15-
use crate::storage::{MutinyStorage, DEVICE_ID_KEY, KEYCHAIN_STORE_KEY};
15+
use crate::storage::{MutinyStorage, DEVICE_ID_KEY, KEYCHAIN_STORE_KEY, NEED_FULL_SYNC_KEY};
1616
use crate::utils::sleep;
1717
use crate::MutinyWalletConfig;
1818
use crate::{
@@ -522,7 +522,7 @@ pub struct NodeManager<S: MutinyStorage> {
522522
#[cfg(target_arch = "wasm32")]
523523
websocket_proxy_addr: String,
524524
esplora: Arc<MultiEsploraClient>,
525-
wallet: Arc<OnChainWallet<S>>,
525+
pub(crate) wallet: Arc<OnChainWallet<S>>,
526526
gossip_sync: Arc<RapidGossipSync>,
527527
scorer: Arc<utils::Mutex<ProbScorer>>,
528528
chain: Arc<MutinyChain<S>>,
@@ -2293,6 +2293,7 @@ impl<S: MutinyStorage> NodeManager<S> {
22932293

22942294
// delete the bdk keychain store
22952295
self.storage.delete(&[KEYCHAIN_STORE_KEY])?;
2296+
self.storage.set_data(NEED_FULL_SYNC_KEY, true, None)?;
22962297

22972298
// shut back down after reading if it was already closed
22982299
if needs_db_connection {

mutiny-core/src/onchain.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::anyhow;
2-
use std::collections::HashSet;
2+
use std::collections::{BTreeMap, HashSet};
33
use std::str::FromStr;
44
use std::sync::atomic::{AtomicBool, Ordering};
55
use std::sync::{Arc, RwLock};
@@ -91,6 +91,83 @@ impl<S: MutinyStorage> OnChainWallet<S> {
9191
}
9292

9393
pub async fn sync(&self) -> Result<(), MutinyError> {
94+
// get first wallet lock that only needs to read
95+
let (checkpoints, spks, txids) = {
96+
if let Ok(wallet) = self.wallet.try_read() {
97+
let checkpoints = wallet.checkpoints();
98+
99+
let spk_vec = wallet
100+
.spk_index()
101+
.unused_spks(..)
102+
.map(|(k, v)| (*k, v.clone()))
103+
.collect::<Vec<_>>();
104+
105+
let mut spk_map = BTreeMap::new();
106+
for ((a, b), c) in spk_vec {
107+
spk_map.entry(a).or_insert_with(Vec::new).push((b, c));
108+
}
109+
110+
let chain = wallet.local_chain();
111+
let chain_tip = chain.tip().unwrap_or_default();
112+
113+
let unconfirmed_txids = wallet
114+
.tx_graph()
115+
.list_chain_txs(chain, chain_tip)
116+
.filter(|canonical_tx| !canonical_tx.observed_as.is_confirmed())
117+
.map(|canonical_tx| canonical_tx.node.txid)
118+
.collect::<Vec<Txid>>();
119+
120+
(checkpoints.clone(), spk_map, unconfirmed_txids)
121+
} else {
122+
log_error!(self.logger, "Could not get wallet lock to sync");
123+
return Err(MutinyError::WalletOperationFailed);
124+
}
125+
};
126+
127+
let update = self
128+
.blockchain
129+
.scan(&checkpoints, spks, txids, core::iter::empty(), 20, 5)
130+
.await?;
131+
132+
// get new wallet lock for writing and apply the update
133+
for _ in 0..10 {
134+
match self.wallet.try_write() {
135+
Ok(mut wallet) => match wallet.apply_update(update) {
136+
Ok(changed) => {
137+
// commit the changes if there were any
138+
if changed {
139+
wallet.commit()?;
140+
}
141+
142+
return Ok(());
143+
}
144+
Err(e) => {
145+
// failed to apply wallet update
146+
log_error!(self.logger, "Could not apply wallet update: {e}");
147+
return Err(MutinyError::Other(anyhow!("Could not apply update: {e}")));
148+
}
149+
},
150+
Err(e) => {
151+
// if we can't get the lock, we just return and try again later
152+
log_error!(
153+
self.logger,
154+
"Could not get wallet lock: {e}, retrying in 250ms"
155+
);
156+
157+
if self.stop.load(Ordering::Relaxed) {
158+
return Err(MutinyError::NotRunning);
159+
};
160+
161+
sleep(250).await;
162+
}
163+
}
164+
}
165+
166+
log_error!(self.logger, "Could not get wallet lock after 10 retries");
167+
Err(MutinyError::WalletOperationFailed)
168+
}
169+
170+
pub async fn full_sync(&self) -> Result<(), MutinyError> {
94171
// get first wallet lock that only needs to read
95172
let (checkpoints, spks) = {
96173
if let Ok(wallet) = self.wallet.try_read() {

mutiny-core/src/storage.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use uuid::Uuid;
1616

1717
pub const KEYCHAIN_STORE_KEY: &str = "bdk_keychain";
1818
pub(crate) const MNEMONIC_KEY: &str = "mnemonic";
19+
pub(crate) const NEED_FULL_SYNC_KEY: &str = "needs_full_sync";
1920
pub const NODES_KEY: &str = "nodes";
2021
const FEE_ESTIMATES_KEY: &str = "fee_estimates";
2122
const FIRST_SYNC_KEY: &str = "first_sync";

0 commit comments

Comments
 (0)