Add SyncOptions as the second argument to Wallet::sync
The current options are awkward and it would be good if we could introduce more in the future without breaking changes.
This commit is contained in:
@@ -110,10 +110,10 @@ impl GetHeight for AnyBlockchain {
|
||||
|
||||
#[maybe_async]
|
||||
impl WalletSync for AnyBlockchain {
|
||||
fn wallet_sync<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_sync<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
maybe_await!(impl_inner_method!(
|
||||
self,
|
||||
@@ -123,10 +123,10 @@ impl WalletSync for AnyBlockchain {
|
||||
))
|
||||
}
|
||||
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
maybe_await!(impl_inner_method!(
|
||||
self,
|
||||
|
||||
@@ -251,10 +251,10 @@ impl GetHeight for CompactFiltersBlockchain {
|
||||
|
||||
impl WalletSync for CompactFiltersBlockchain {
|
||||
#[allow(clippy::mutex_atomic)] // Mutex is easier to understand than a CAS loop.
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
let first_peer = &self.peers[0];
|
||||
|
||||
|
||||
@@ -95,10 +95,10 @@ impl GetHeight for ElectrumBlockchain {
|
||||
}
|
||||
|
||||
impl WalletSync for ElectrumBlockchain {
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
_progress_update: P,
|
||||
_progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
let mut request = script_sync::start(database, self.stop_gap)?;
|
||||
let mut block_times = HashMap::<u32, u32>::new();
|
||||
|
||||
@@ -114,10 +114,10 @@ impl GetHeight for EsploraBlockchain {
|
||||
|
||||
#[maybe_async]
|
||||
impl WalletSync for EsploraBlockchain {
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
_progress_update: P,
|
||||
_progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
use crate::blockchain::script_sync::Request;
|
||||
let mut request = script_sync::start(database, self.stop_gap)?;
|
||||
|
||||
@@ -109,10 +109,10 @@ impl GetHeight for EsploraBlockchain {
|
||||
}
|
||||
|
||||
impl WalletSync for EsploraBlockchain {
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
_progress_update: P,
|
||||
_progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
use crate::blockchain::script_sync::Request;
|
||||
let mut request = script_sync::start(database, self.stop_gap)?;
|
||||
|
||||
@@ -118,10 +118,10 @@ pub trait WalletSync {
|
||||
/// For types that do not have that distinction, only this method can be implemented, since
|
||||
/// [`WalletSync::wallet_sync`] defaults to calling this internally if not overridden.
|
||||
/// Populate the internal database with transactions and UTXOs
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
/// If not overridden, it defaults to calling [`Self::wallet_setup`] internally.
|
||||
@@ -141,10 +141,10 @@ pub trait WalletSync {
|
||||
/// [`BatchOperations::set_tx`]: crate::database::BatchOperations::set_tx
|
||||
/// [`BatchOperations::set_utxo`]: crate::database::BatchOperations::set_utxo
|
||||
/// [`BatchOperations::del_utxo`]: crate::database::BatchOperations::del_utxo
|
||||
fn wallet_sync<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_sync<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
maybe_await!(self.wallet_setup(database, progress_update))
|
||||
}
|
||||
@@ -164,7 +164,7 @@ pub type ProgressData = (f32, Option<String>);
|
||||
|
||||
/// Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and
|
||||
/// [`WalletSync::wallet_setup`]
|
||||
pub trait Progress: Send + 'static {
|
||||
pub trait Progress: Send + 'static + core::fmt::Debug {
|
||||
/// Send a new progress update
|
||||
///
|
||||
/// The `progress` value should be in the range 0.0 - 100.0, and the `message` value is an
|
||||
@@ -189,7 +189,7 @@ impl Progress for Sender<ProgressData> {
|
||||
}
|
||||
|
||||
/// Type that implements [`Progress`] and drops every update received
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default, Debug)]
|
||||
pub struct NoopProgress;
|
||||
|
||||
/// Create a new instance of [`NoopProgress`]
|
||||
@@ -204,7 +204,7 @@ impl Progress for NoopProgress {
|
||||
}
|
||||
|
||||
/// Type that implements [`Progress`] and logs at level `INFO` every update received
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default, Debug)]
|
||||
pub struct LogProgress;
|
||||
|
||||
/// Create a new instance of [`LogProgress`]
|
||||
@@ -251,18 +251,18 @@ impl<T: GetHeight> GetHeight for Arc<T> {
|
||||
|
||||
#[maybe_async]
|
||||
impl<T: WalletSync> WalletSync for Arc<T> {
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
maybe_await!(self.deref().wallet_setup(database, progress_update))
|
||||
}
|
||||
|
||||
fn wallet_sync<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_sync<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
maybe_await!(self.deref().wallet_sync(database, progress_update))
|
||||
}
|
||||
|
||||
@@ -168,10 +168,10 @@ impl GetHeight for RpcBlockchain {
|
||||
}
|
||||
|
||||
impl WalletSync for RpcBlockchain {
|
||||
fn wallet_setup<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_setup<D: BatchDatabase>(
|
||||
&self,
|
||||
database: &mut D,
|
||||
progress_update: P,
|
||||
progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
let mut scripts_pubkeys = database.iter_script_pubkeys(Some(KeychainKind::External))?;
|
||||
scripts_pubkeys.extend(database.iter_script_pubkeys(Some(KeychainKind::Internal))?);
|
||||
@@ -219,10 +219,10 @@ impl WalletSync for RpcBlockchain {
|
||||
self.wallet_sync(database, progress_update)
|
||||
}
|
||||
|
||||
fn wallet_sync<D: BatchDatabase, P: Progress>(
|
||||
fn wallet_sync<D: BatchDatabase>(
|
||||
&self,
|
||||
db: &mut D,
|
||||
_progress_update: P,
|
||||
_progress_update: Box<dyn Progress>,
|
||||
) -> Result<(), Error> {
|
||||
let mut indexes = HashMap::new();
|
||||
for keykind in &[KeychainKind::External, KeychainKind::Internal] {
|
||||
|
||||
13
src/lib.rs
13
src/lib.rs
@@ -53,9 +53,9 @@
|
||||
|
||||
### Example
|
||||
```no_run
|
||||
use bdk::Wallet;
|
||||
use bdk::{Wallet, SyncOptions};
|
||||
use bdk::database::MemoryDatabase;
|
||||
use bdk::blockchain::{noop_progress, ElectrumBlockchain};
|
||||
use bdk::blockchain::ElectrumBlockchain;
|
||||
use bdk::electrum_client::Client;
|
||||
|
||||
fn main() -> Result<(), bdk::Error> {
|
||||
@@ -68,7 +68,7 @@ fn main() -> Result<(), bdk::Error> {
|
||||
MemoryDatabase::default(),
|
||||
)?;
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None)?;
|
||||
wallet.sync(&blockchain, SyncOptions::default())?;
|
||||
|
||||
println!("Descriptor balance: {} SAT", wallet.get_balance()?);
|
||||
|
||||
@@ -108,9 +108,9 @@ fn main() -> Result<(), bdk::Error> {
|
||||
|
||||
### Example
|
||||
```no_run
|
||||
use bdk::{FeeRate, Wallet};
|
||||
use bdk::{FeeRate, Wallet, SyncOptions};
|
||||
use bdk::database::MemoryDatabase;
|
||||
use bdk::blockchain::{noop_progress, ElectrumBlockchain};
|
||||
use bdk::blockchain::ElectrumBlockchain;
|
||||
use bdk::electrum_client::Client;
|
||||
|
||||
use bitcoin::consensus::serialize;
|
||||
@@ -126,7 +126,7 @@ fn main() -> Result<(), bdk::Error> {
|
||||
)?;
|
||||
let blockchain = ElectrumBlockchain::from(client);
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None)?;
|
||||
wallet.sync(&blockchain, SyncOptions::default())?;
|
||||
|
||||
let send_to = wallet.get_address(New)?;
|
||||
let (psbt, details) = {
|
||||
@@ -272,6 +272,7 @@ pub use wallet::address_validator;
|
||||
pub use wallet::signer;
|
||||
pub use wallet::signer::SignOptions;
|
||||
pub use wallet::tx_builder::TxBuilder;
|
||||
pub use wallet::SyncOptions;
|
||||
pub use wallet::Wallet;
|
||||
|
||||
/// Get the version of BDK at runtime
|
||||
|
||||
@@ -361,10 +361,10 @@ macro_rules! bdk_blockchain_tests {
|
||||
mod bdk_blockchain_tests {
|
||||
use $crate::bitcoin::{Transaction, Network};
|
||||
use $crate::testutils::blockchain_tests::TestClient;
|
||||
use $crate::blockchain::{Blockchain, noop_progress};
|
||||
use $crate::blockchain::Blockchain;
|
||||
use $crate::database::MemoryDatabase;
|
||||
use $crate::types::KeychainKind;
|
||||
use $crate::{Wallet, FeeRate};
|
||||
use $crate::{Wallet, FeeRate, SyncOptions};
|
||||
use $crate::testutils;
|
||||
|
||||
use super::*;
|
||||
@@ -392,7 +392,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
|
||||
// rpc need to call import_multi before receiving any tx, otherwise will not see tx in the mempool
|
||||
#[cfg(feature = "test-rpc")]
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
(wallet, blockchain, descriptors, test_client)
|
||||
}
|
||||
@@ -415,7 +415,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
#[cfg(not(feature = "test-rpc"))]
|
||||
assert!(wallet.database().deref().get_sync_time().unwrap().is_none(), "initial sync_time not none");
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert!(wallet.database().deref().get_sync_time().unwrap().is_some(), "sync_time hasn't been updated");
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
@@ -439,7 +439,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 25) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 100_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs");
|
||||
@@ -449,14 +449,14 @@ macro_rules! bdk_blockchain_tests {
|
||||
fn test_sync_before_and_after_receive() {
|
||||
let (wallet, blockchain, descriptors, mut test_client) = init_single_sig();
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 0);
|
||||
|
||||
test_client.receive(testutils! {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs");
|
||||
@@ -470,7 +470,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000, (@external descriptors, 5) => 30_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 105_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs");
|
||||
@@ -494,7 +494,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 5) => 25_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs");
|
||||
@@ -509,14 +509,14 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000);
|
||||
|
||||
test_client.receive(testutils! {
|
||||
@tx ( (@external descriptors, 0) => 25_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
|
||||
}
|
||||
|
||||
@@ -528,7 +528,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 ) ( @replaceable true )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs");
|
||||
@@ -542,7 +542,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
|
||||
let new_txid = test_client.bump_fee(&txid);
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance after bump");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs after bump");
|
||||
@@ -566,7 +566,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 ) ( @confirmations 1 ) ( @replaceable true )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs");
|
||||
@@ -579,7 +579,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
// Invalidate 1 block
|
||||
test_client.invalidate(1);
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance after invalidate");
|
||||
|
||||
@@ -598,7 +598,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -609,7 +609,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let tx = psbt.extract_tx();
|
||||
println!("{}", bitcoin::consensus::encode::serialize_hex(&tx));
|
||||
blockchain.broadcast(&tx).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect balance after send");
|
||||
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs");
|
||||
@@ -623,13 +623,13 @@ macro_rules! bdk_blockchain_tests {
|
||||
let (wallet, blockchain, descriptors, mut test_client) = init_single_sig();
|
||||
let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
|
||||
// need to sync so rpc can start watching
|
||||
receiver_wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
test_client.receive(testutils! {
|
||||
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1)
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
|
||||
let target_addr = receiver_wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address;
|
||||
|
||||
@@ -654,7 +654,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
blockchain.broadcast(&tx1).unwrap();
|
||||
blockchain.broadcast(&tx2).unwrap();
|
||||
|
||||
receiver_wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(receiver_wallet.get_balance().unwrap(), 49_000, "should have received coins once and only once");
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
});
|
||||
}
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert_eq!(wallet.get_balance().unwrap(), 100_000);
|
||||
}
|
||||
@@ -694,7 +694,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let tx_map = wallet.list_transactions(false).unwrap().into_iter().map(|tx| (tx.txid, tx)).collect::<std::collections::HashMap<_, _>>();
|
||||
@@ -702,7 +702,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
assert!(details.confirmation_time.is_none());
|
||||
|
||||
test_client.generate(1, Some(node_addr));
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
let tx_map = wallet.list_transactions(false).unwrap().into_iter().map(|tx| (tx.txid, tx)).collect::<std::collections::HashMap<_, _>>();
|
||||
let details = tx_map.get(&received_txid).unwrap();
|
||||
@@ -718,7 +718,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -730,7 +730,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let sent_tx = psbt.extract_tx();
|
||||
blockchain.broadcast(&sent_tx).unwrap();
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect balance after receive");
|
||||
|
||||
// empty wallet
|
||||
@@ -739,7 +739,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
#[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti
|
||||
test_client.generate(1, Some(node_addr));
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
let tx_map = wallet.list_transactions(false).unwrap().into_iter().map(|tx| (tx.txid, tx)).collect::<std::collections::HashMap<_, _>>();
|
||||
|
||||
let received = tx_map.get(&received_txid).unwrap();
|
||||
@@ -761,7 +761,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut total_sent = 0;
|
||||
@@ -773,12 +773,12 @@ macro_rules! bdk_blockchain_tests {
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&psbt.extract_tx()).unwrap();
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
total_sent += 5_000 + details.fee.unwrap_or(0);
|
||||
}
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000 - total_sent, "incorrect balance after chain");
|
||||
|
||||
// empty wallet
|
||||
@@ -788,7 +788,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
#[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti
|
||||
test_client.generate(1, Some(node_addr));
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000 - total_sent, "incorrect balance empty wallet");
|
||||
|
||||
}
|
||||
@@ -802,7 +802,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 ) (@confirmations 1)
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -811,7 +811,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000 - details.fee.unwrap_or(0) - 5_000, "incorrect balance from fees");
|
||||
assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect balance from received");
|
||||
|
||||
@@ -821,7 +821,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&new_psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000 - new_details.fee.unwrap_or(0) - 5_000, "incorrect balance from fees after bump");
|
||||
assert_eq!(wallet.get_balance().unwrap(), new_details.received, "incorrect balance from received after bump");
|
||||
|
||||
@@ -837,7 +837,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 ) (@confirmations 1)
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -846,7 +846,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 1_000 - details.fee.unwrap_or(0), "incorrect balance after send");
|
||||
assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect received after send");
|
||||
|
||||
@@ -856,7 +856,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&new_psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance after change removal");
|
||||
assert_eq!(new_details.received, 0, "incorrect received after change removal");
|
||||
|
||||
@@ -872,7 +872,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1)
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -881,7 +881,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 26_000 - details.fee.unwrap_or(0), "incorrect balance after send");
|
||||
assert_eq!(details.received, 1_000 - details.fee.unwrap_or(0), "incorrect received after send");
|
||||
|
||||
@@ -891,7 +891,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&new_psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(new_details.sent, 75_000, "incorrect sent");
|
||||
assert_eq!(wallet.get_balance().unwrap(), new_details.received, "incorrect balance after add input");
|
||||
}
|
||||
@@ -905,7 +905,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1)
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -914,7 +914,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 26_000 - details.fee.unwrap_or(0), "incorrect balance after send");
|
||||
assert_eq!(details.received, 1_000 - details.fee.unwrap_or(0), "incorrect received after send");
|
||||
|
||||
@@ -926,7 +926,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
|
||||
assert!(finalized, "Cannot finalize transaction");
|
||||
blockchain.broadcast(&new_psbt.extract_tx()).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(new_details.sent, 75_000, "incorrect sent");
|
||||
assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance after add input");
|
||||
assert_eq!(new_details.received, 0, "incorrect received after add input");
|
||||
@@ -941,7 +941,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
|
||||
|
||||
let mut builder = wallet.build_tx();
|
||||
@@ -956,7 +956,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
assert!(serialized_tx.windows(data.len()).any(|e| e==data), "cannot find op_return data in transaction");
|
||||
blockchain.broadcast(&tx).unwrap();
|
||||
test_client.generate(1, Some(node_addr));
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000 - details.fee.unwrap_or(0), "incorrect balance after send");
|
||||
|
||||
let tx_map = wallet.list_transactions(false).unwrap().into_iter().map(|tx| (tx.txid, tx)).collect::<std::collections::HashMap<_, _>>();
|
||||
@@ -969,7 +969,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
|
||||
let wallet_addr = wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address;
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance");
|
||||
|
||||
test_client.generate(1, Some(wallet_addr));
|
||||
@@ -982,7 +982,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
}
|
||||
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert!(wallet.get_balance().unwrap() > 0, "incorrect balance after receiving coinbase");
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
@tx ( (@external descriptors, 0) => 50_000 )
|
||||
});
|
||||
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), 50_000, "wallet has incorrect balance");
|
||||
|
||||
// 4. Send 25_000 sats from test BDK wallet to test bitcoind node taproot wallet
|
||||
@@ -1070,7 +1070,7 @@ macro_rules! bdk_blockchain_tests {
|
||||
assert!(finalized, "wallet cannot finalize transaction");
|
||||
let tx = psbt.extract_tx();
|
||||
blockchain.broadcast(&tx).unwrap();
|
||||
wallet.sync(&blockchain, noop_progress(), None).unwrap();
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap(), details.received, "wallet has incorrect balance after send");
|
||||
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "wallet has incorrect number of txs");
|
||||
assert_eq!(wallet.list_unspent().unwrap().len(), 1, "wallet has incorrect number of unspents");
|
||||
|
||||
@@ -55,7 +55,7 @@ use signer::{SignOptions, Signer, SignerOrdering, SignersContainer};
|
||||
use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
|
||||
use utils::{check_nlocktime, check_nsequence_rbf, After, Older, SecpCtx};
|
||||
|
||||
use crate::blockchain::{GetHeight, Progress, WalletSync};
|
||||
use crate::blockchain::{GetHeight, NoopProgress, Progress, WalletSync};
|
||||
use crate::database::memory::MemoryDatabase;
|
||||
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
|
||||
use crate::descriptor::derived::AsDerived;
|
||||
@@ -156,6 +156,17 @@ impl fmt::Display for AddressInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
/// Options to a [`sync`].
|
||||
///
|
||||
/// [`sync`]: Wallet::sync
|
||||
pub struct SyncOptions {
|
||||
/// The progress tracker which may be informed when progress is made.
|
||||
pub progress: Option<Box<dyn Progress>>,
|
||||
/// The maximum number of addresses sync on.
|
||||
pub max_addresses: Option<u32>,
|
||||
}
|
||||
|
||||
impl<D> Wallet<D>
|
||||
where
|
||||
D: BatchDatabase,
|
||||
@@ -1431,27 +1442,26 @@ where
|
||||
pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ {
|
||||
self.database.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> Wallet<D>
|
||||
where
|
||||
D: BatchDatabase,
|
||||
{
|
||||
/// Sync the internal database with the blockchain
|
||||
#[maybe_async]
|
||||
pub fn sync<P: 'static + Progress, B: WalletSync + GetHeight>(
|
||||
pub fn sync<B: WalletSync + GetHeight>(
|
||||
&self,
|
||||
blockchain: &B,
|
||||
progress_update: P,
|
||||
max_address_param: Option<u32>,
|
||||
sync_opts: SyncOptions,
|
||||
) -> Result<(), Error> {
|
||||
debug!("Begin sync...");
|
||||
|
||||
let mut run_setup = false;
|
||||
let SyncOptions {
|
||||
max_addresses,
|
||||
progress,
|
||||
} = sync_opts;
|
||||
let progress = progress.unwrap_or_else(|| Box::new(NoopProgress));
|
||||
|
||||
let max_address = match self.descriptor.is_deriveable() {
|
||||
false => 0,
|
||||
true => max_address_param.unwrap_or(CACHE_ADDR_BATCH_SIZE),
|
||||
true => max_addresses.unwrap_or(CACHE_ADDR_BATCH_SIZE),
|
||||
};
|
||||
debug!("max_address {}", max_address);
|
||||
if self
|
||||
@@ -1468,7 +1478,7 @@ where
|
||||
if let Some(change_descriptor) = &self.change_descriptor {
|
||||
let max_address = match change_descriptor.is_deriveable() {
|
||||
false => 0,
|
||||
true => max_address_param.unwrap_or(CACHE_ADDR_BATCH_SIZE),
|
||||
true => max_addresses.unwrap_or(CACHE_ADDR_BATCH_SIZE),
|
||||
};
|
||||
|
||||
if self
|
||||
@@ -1488,12 +1498,10 @@ where
|
||||
// TODO: we should sync if generating an address triggers a new batch to be stored
|
||||
if run_setup {
|
||||
maybe_await!(
|
||||
blockchain.wallet_setup(self.database.borrow_mut().deref_mut(), progress_update,)
|
||||
blockchain.wallet_setup(self.database.borrow_mut().deref_mut(), progress,)
|
||||
)?;
|
||||
} else {
|
||||
maybe_await!(
|
||||
blockchain.wallet_sync(self.database.borrow_mut().deref_mut(), progress_update,)
|
||||
)?;
|
||||
maybe_await!(blockchain.wallet_sync(self.database.borrow_mut().deref_mut(), progress,))?;
|
||||
}
|
||||
|
||||
let sync_time = SyncTime {
|
||||
|
||||
Reference in New Issue
Block a user