From: 志宇 Date: Sun, 17 Jul 2022 13:02:19 +0000 (+0800) Subject: Fix wallet sync not finding coins of addresses which are not cached X-Git-Tag: v0.21.0~15^2 X-Git-Url: http://internal-gitweb-vhost/script/%22https:/database/struct.EncoderStringWriter.html?a=commitdiff_plain;h=5c940c33cb1f1a166c6e28e8bbfd9cdaef6c1ab6;p=bdk Fix wallet sync not finding coins of addresses which are not cached Previously, electrum-based blockchain implementations only synced for `scriptPubKey`s that are already cached in `Database`. This PR introduces a feedback mechanism, that uses `stop_gap` and the difference between "current index" and "last active index" to determine whether we need to cache more `scriptPubKeys`. The `WalletSync::wallet_setup` trait now may return an `Error::MissingCachedScripts` error which contains the number of extra `scriptPubKey`s to cache, in order to satisfy `stop_gap` for the next call. `Wallet::sync` now calls `WalletSync` in a loop, cacheing inbetween subsequent calls (if needed). --- diff --git a/src/blockchain/esplora/reqwest.rs b/src/blockchain/esplora/reqwest.rs index 0d405060..302e811f 100644 --- a/src/blockchain/esplora/reqwest.rs +++ b/src/blockchain/esplora/reqwest.rs @@ -213,7 +213,6 @@ impl WalletSync for EsploraBlockchain { }; database.commit_batch(batch_update)?; - Ok(()) } } diff --git a/src/blockchain/script_sync.rs b/src/blockchain/script_sync.rs index 05752736..2c4b26ce 100644 --- a/src/blockchain/script_sync.rs +++ b/src/blockchain/script_sync.rs @@ -5,6 +5,7 @@ returns associated transactions i.e. electrum. #![allow(dead_code)] use crate::{ database::{BatchDatabase, BatchOperations, DatabaseUtils}, + error::MissingCachedScripts, wallet::time::Instant, BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails, }; @@ -34,11 +35,12 @@ pub fn start(db: &D, stop_gap: usize) -> Result let scripts_needed = db .iter_script_pubkeys(Some(keychain))? .into_iter() - .collect(); + .collect::>(); let state = State::new(db); Ok(Request::Script(ScriptReq { state, + initial_scripts_needed: scripts_needed.len(), scripts_needed, script_index: 0, stop_gap, @@ -50,6 +52,7 @@ pub fn start(db: &D, stop_gap: usize) -> Result pub struct ScriptReq<'a, D: BatchDatabase> { state: State<'a, D>, script_index: usize, + initial_scripts_needed: usize, // if this is 1, we assume the descriptor is not derivable scripts_needed: VecDeque