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:
LLFourn 2022-01-27 16:52:53 +11:00
parent 326bfe82a8
commit 410a51355b
No known key found for this signature in database
GPG Key ID: A27093B54DA11F65
13 changed files with 124 additions and 110 deletions

View File

@ -8,10 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed default verification from `wallet::sync`. sync-time verification is added in `script_sync` and is activated by `verify` feature flag. - Removed default verification from `wallet::sync`. sync-time verification is added in `script_sync` and is activated by `verify` feature flag.
- `verify` flag removed from `TransactionDetails`. - `verify` flag removed from `TransactionDetails`.
- Removed Blockchain from Wallet.
- Removed `Wallet::broadcast` (just use blockchain.broadcast) ### Sync API change
To decouple the `Wallet` from the `Blockchain` we've made major changes:
- Removed `Blockchain` from Wallet.
- Removed `Wallet::broadcast` (just use `Blockchain::broadcast`)
- Depreciated `Wallet::new_offline` (all wallets are offline now) - Depreciated `Wallet::new_offline` (all wallets are offline now)
- Changed `Wallet::sync` to take a blockchain argument. - Changed `Wallet::sync` to take a `Blockchain`.
- Stop making a request for the block height when calling `Wallet:new`.
- Added `SyncOptions` to capture extra (future) arguments to `Wallet::sync`.
## [v0.16.1] - [v0.16.0] ## [v0.16.1] - [v0.16.0]

View File

@ -41,21 +41,21 @@ The `bdk` library aims to be the core building block for Bitcoin wallets of any
```rust,no_run ```rust,no_run
use bdk::Wallet; use bdk::Wallet;
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::blockchain::ElectrumBlockchain;
use bdk::SyncOptions;
use bdk::electrum_client::Client; use bdk::electrum_client::Client;
fn main() -> Result<(), bdk::Error> { fn main() -> Result<(), bdk::Error> {
let client = Client::new("ssl://electrum.blockstream.info:60002")?; let blockchain = ElectrumBlockchain::from(Client::new("ssl://electrum.blockstream.info:60002")?);
let wallet = Wallet::new( let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
bitcoin::Network::Testnet, bitcoin::Network::Testnet,
MemoryDatabase::default(), MemoryDatabase::default(),
ElectrumBlockchain::from(client)
)?; )?;
wallet.sync(noop_progress(), None)?; wallet.sync(&blockchain, SyncOptions::default())?;
println!("Descriptor balance: {} SAT", wallet.get_balance()?); println!("Descriptor balance: {} SAT", wallet.get_balance()?);
@ -88,9 +88,9 @@ fn main() -> Result<(), bdk::Error> {
### Create a transaction ### Create a transaction
```rust,no_run ```rust,no_run
use bdk::{FeeRate, Wallet}; use bdk::{FeeRate, Wallet, SyncOptions};
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::blockchain::ElectrumBlockchain;
use bdk::electrum_client::Client; use bdk::electrum_client::Client;
use bdk::wallet::AddressIndex::New; use bdk::wallet::AddressIndex::New;
@ -98,16 +98,15 @@ use bdk::wallet::AddressIndex::New;
use bitcoin::consensus::serialize; use bitcoin::consensus::serialize;
fn main() -> Result<(), bdk::Error> { fn main() -> Result<(), bdk::Error> {
let client = Client::new("ssl://electrum.blockstream.info:60002")?; let blockchain = ElectrumBlockchain::from(Client::new("ssl://electrum.blockstream.info:60002")?);
let wallet = Wallet::new( let wallet = Wallet::new(
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)", "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"), Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
bitcoin::Network::Testnet, bitcoin::Network::Testnet,
MemoryDatabase::default(), MemoryDatabase::default(),
ElectrumBlockchain::from(client)
)?; )?;
wallet.sync(noop_progress(), None)?; wallet.sync(&blockchain, SyncOptions::default())?;
let send_to = wallet.get_address(New)?; let send_to = wallet.get_address(New)?;
let (psbt, details) = { let (psbt, details) = {

View File

@ -10,7 +10,6 @@
// licenses. // licenses.
use bdk::blockchain::compact_filters::*; use bdk::blockchain::compact_filters::*;
use bdk::blockchain::noop_progress;
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::*; use bdk::*;
use bitcoin::*; use bitcoin::*;
@ -36,7 +35,7 @@ fn main() -> Result<(), CompactFiltersError> {
let database = MemoryDatabase::default(); let database = MemoryDatabase::default();
let wallet = Arc::new(Wallet::new(descriptor, None, Network::Testnet, database).unwrap()); let wallet = Arc::new(Wallet::new(descriptor, None, Network::Testnet, database).unwrap());
wallet.sync(&blockchain, noop_progress(), None).unwrap(); wallet.sync(&blockchain, SyncOptions::default()).unwrap();
info!("balance: {}", wallet.get_balance()?); info!("balance: {}", wallet.get_balance()?);
Ok(()) Ok(())
} }

View File

@ -110,10 +110,10 @@ impl GetHeight for AnyBlockchain {
#[maybe_async] #[maybe_async]
impl WalletSync for AnyBlockchain { impl WalletSync for AnyBlockchain {
fn wallet_sync<D: BatchDatabase, P: Progress>( fn wallet_sync<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
maybe_await!(impl_inner_method!( maybe_await!(impl_inner_method!(
self, self,
@ -123,10 +123,10 @@ impl WalletSync for AnyBlockchain {
)) ))
} }
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
maybe_await!(impl_inner_method!( maybe_await!(impl_inner_method!(
self, self,

View File

@ -251,10 +251,10 @@ impl GetHeight for CompactFiltersBlockchain {
impl WalletSync for CompactFiltersBlockchain { impl WalletSync for CompactFiltersBlockchain {
#[allow(clippy::mutex_atomic)] // Mutex is easier to understand than a CAS loop. #[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, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let first_peer = &self.peers[0]; let first_peer = &self.peers[0];

View File

@ -95,10 +95,10 @@ impl GetHeight for ElectrumBlockchain {
} }
impl WalletSync for ElectrumBlockchain { impl WalletSync for ElectrumBlockchain {
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
_progress_update: P, _progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut request = script_sync::start(database, self.stop_gap)?; let mut request = script_sync::start(database, self.stop_gap)?;
let mut block_times = HashMap::<u32, u32>::new(); let mut block_times = HashMap::<u32, u32>::new();

View File

@ -114,10 +114,10 @@ impl GetHeight for EsploraBlockchain {
#[maybe_async] #[maybe_async]
impl WalletSync for EsploraBlockchain { impl WalletSync for EsploraBlockchain {
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
_progress_update: P, _progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
use crate::blockchain::script_sync::Request; use crate::blockchain::script_sync::Request;
let mut request = script_sync::start(database, self.stop_gap)?; let mut request = script_sync::start(database, self.stop_gap)?;

View File

@ -109,10 +109,10 @@ impl GetHeight for EsploraBlockchain {
} }
impl WalletSync for EsploraBlockchain { impl WalletSync for EsploraBlockchain {
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
_progress_update: P, _progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
use crate::blockchain::script_sync::Request; use crate::blockchain::script_sync::Request;
let mut request = script_sync::start(database, self.stop_gap)?; let mut request = script_sync::start(database, self.stop_gap)?;

View File

@ -118,10 +118,10 @@ pub trait WalletSync {
/// For types that do not have that distinction, only this method can be implemented, since /// 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. /// [`WalletSync::wallet_sync`] defaults to calling this internally if not overridden.
/// Populate the internal database with transactions and UTXOs /// Populate the internal database with transactions and UTXOs
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error>; ) -> Result<(), Error>;
/// If not overridden, it defaults to calling [`Self::wallet_setup`] internally. /// 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_tx`]: crate::database::BatchOperations::set_tx
/// [`BatchOperations::set_utxo`]: crate::database::BatchOperations::set_utxo /// [`BatchOperations::set_utxo`]: crate::database::BatchOperations::set_utxo
/// [`BatchOperations::del_utxo`]: crate::database::BatchOperations::del_utxo /// [`BatchOperations::del_utxo`]: crate::database::BatchOperations::del_utxo
fn wallet_sync<D: BatchDatabase, P: Progress>( fn wallet_sync<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
maybe_await!(self.wallet_setup(database, progress_update)) 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 /// Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and
/// [`WalletSync::wallet_setup`] /// [`WalletSync::wallet_setup`]
pub trait Progress: Send + 'static { pub trait Progress: Send + 'static + core::fmt::Debug {
/// Send a new progress update /// Send a new progress update
/// ///
/// The `progress` value should be in the range 0.0 - 100.0, and the `message` value is an /// 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 /// Type that implements [`Progress`] and drops every update received
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default, Debug)]
pub struct NoopProgress; pub struct NoopProgress;
/// Create a new instance of [`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 /// Type that implements [`Progress`] and logs at level `INFO` every update received
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default, Debug)]
pub struct LogProgress; pub struct LogProgress;
/// Create a new instance of [`LogProgress`] /// Create a new instance of [`LogProgress`]
@ -251,18 +251,18 @@ impl<T: GetHeight> GetHeight for Arc<T> {
#[maybe_async] #[maybe_async]
impl<T: WalletSync> WalletSync for Arc<T> { impl<T: WalletSync> WalletSync for Arc<T> {
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
maybe_await!(self.deref().wallet_setup(database, progress_update)) maybe_await!(self.deref().wallet_setup(database, progress_update))
} }
fn wallet_sync<D: BatchDatabase, P: Progress>( fn wallet_sync<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
maybe_await!(self.deref().wallet_sync(database, progress_update)) maybe_await!(self.deref().wallet_sync(database, progress_update))
} }

View File

@ -168,10 +168,10 @@ impl GetHeight for RpcBlockchain {
} }
impl WalletSync for RpcBlockchain { impl WalletSync for RpcBlockchain {
fn wallet_setup<D: BatchDatabase, P: Progress>( fn wallet_setup<D: BatchDatabase>(
&self, &self,
database: &mut D, database: &mut D,
progress_update: P, progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut scripts_pubkeys = database.iter_script_pubkeys(Some(KeychainKind::External))?; let mut scripts_pubkeys = database.iter_script_pubkeys(Some(KeychainKind::External))?;
scripts_pubkeys.extend(database.iter_script_pubkeys(Some(KeychainKind::Internal))?); scripts_pubkeys.extend(database.iter_script_pubkeys(Some(KeychainKind::Internal))?);
@ -219,10 +219,10 @@ impl WalletSync for RpcBlockchain {
self.wallet_sync(database, progress_update) self.wallet_sync(database, progress_update)
} }
fn wallet_sync<D: BatchDatabase, P: Progress>( fn wallet_sync<D: BatchDatabase>(
&self, &self,
db: &mut D, db: &mut D,
_progress_update: P, _progress_update: Box<dyn Progress>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut indexes = HashMap::new(); let mut indexes = HashMap::new();
for keykind in &[KeychainKind::External, KeychainKind::Internal] { for keykind in &[KeychainKind::External, KeychainKind::Internal] {

View File

@ -53,9 +53,9 @@
### Example ### Example
```no_run ```no_run
use bdk::Wallet; use bdk::{Wallet, SyncOptions};
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::blockchain::ElectrumBlockchain;
use bdk::electrum_client::Client; use bdk::electrum_client::Client;
fn main() -> Result<(), bdk::Error> { fn main() -> Result<(), bdk::Error> {
@ -68,7 +68,7 @@ fn main() -> Result<(), bdk::Error> {
MemoryDatabase::default(), MemoryDatabase::default(),
)?; )?;
wallet.sync(&blockchain, noop_progress(), None)?; wallet.sync(&blockchain, SyncOptions::default())?;
println!("Descriptor balance: {} SAT", wallet.get_balance()?); println!("Descriptor balance: {} SAT", wallet.get_balance()?);
@ -108,9 +108,9 @@ fn main() -> Result<(), bdk::Error> {
### Example ### Example
```no_run ```no_run
use bdk::{FeeRate, Wallet}; use bdk::{FeeRate, Wallet, SyncOptions};
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::blockchain::ElectrumBlockchain;
use bdk::electrum_client::Client; use bdk::electrum_client::Client;
use bitcoin::consensus::serialize; use bitcoin::consensus::serialize;
@ -126,7 +126,7 @@ fn main() -> Result<(), bdk::Error> {
)?; )?;
let blockchain = ElectrumBlockchain::from(client); let blockchain = ElectrumBlockchain::from(client);
wallet.sync(&blockchain, noop_progress(), None)?; wallet.sync(&blockchain, SyncOptions::default())?;
let send_to = wallet.get_address(New)?; let send_to = wallet.get_address(New)?;
let (psbt, details) = { let (psbt, details) = {
@ -272,6 +272,7 @@ pub use wallet::address_validator;
pub use wallet::signer; pub use wallet::signer;
pub use wallet::signer::SignOptions; pub use wallet::signer::SignOptions;
pub use wallet::tx_builder::TxBuilder; pub use wallet::tx_builder::TxBuilder;
pub use wallet::SyncOptions;
pub use wallet::Wallet; pub use wallet::Wallet;
/// Get the version of BDK at runtime /// Get the version of BDK at runtime

View File

@ -361,10 +361,10 @@ macro_rules! bdk_blockchain_tests {
mod bdk_blockchain_tests { mod bdk_blockchain_tests {
use $crate::bitcoin::{Transaction, Network}; use $crate::bitcoin::{Transaction, Network};
use $crate::testutils::blockchain_tests::TestClient; use $crate::testutils::blockchain_tests::TestClient;
use $crate::blockchain::{Blockchain, noop_progress}; use $crate::blockchain::Blockchain;
use $crate::database::MemoryDatabase; use $crate::database::MemoryDatabase;
use $crate::types::KeychainKind; use $crate::types::KeychainKind;
use $crate::{Wallet, FeeRate}; use $crate::{Wallet, FeeRate, SyncOptions};
use $crate::testutils; use $crate::testutils;
use super::*; 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 // rpc need to call import_multi before receiving any tx, otherwise will not see tx in the mempool
#[cfg(feature = "test-rpc")] #[cfg(feature = "test-rpc")]
wallet.sync(&blockchain, noop_progress(), None).unwrap(); wallet.sync(&blockchain, SyncOptions::default()).unwrap();
(wallet, blockchain, descriptors, test_client) (wallet, blockchain, descriptors, test_client)
} }
@ -415,7 +415,7 @@ macro_rules! bdk_blockchain_tests {
#[cfg(not(feature = "test-rpc"))] #[cfg(not(feature = "test-rpc"))]
assert!(wallet.database().deref().get_sync_time().unwrap().is_none(), "initial sync_time not none"); 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!(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"); 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 ) @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.get_balance().unwrap(), 100_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs"); 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() { fn test_sync_before_and_after_receive() {
let (wallet, blockchain, descriptors, mut test_client) = init_single_sig(); 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); assert_eq!(wallet.get_balance().unwrap(), 0);
test_client.receive(testutils! { test_client.receive(testutils! {
@tx ( (@external descriptors, 0) => 50_000 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); 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 ) @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.get_balance().unwrap(), 105_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); 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 ) @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.get_balance().unwrap(), 75_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs"); 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 ) @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); assert_eq!(wallet.get_balance().unwrap(), 50_000);
test_client.receive(testutils! { test_client.receive(testutils! {
@tx ( (@external descriptors, 0) => 25_000 ) @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"); 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 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); 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); 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.get_balance().unwrap(), 50_000, "incorrect balance after bump");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs 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 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); 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 // Invalidate 1 block
test_client.invalidate(1); 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"); 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 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -609,7 +609,7 @@ macro_rules! bdk_blockchain_tests {
let tx = psbt.extract_tx(); let tx = psbt.extract_tx();
println!("{}", bitcoin::consensus::encode::serialize_hex(&tx)); println!("{}", bitcoin::consensus::encode::serialize_hex(&tx));
blockchain.broadcast(&tx).unwrap(); 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.get_balance().unwrap(), details.received, "incorrect balance after send");
assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs"); 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 (wallet, blockchain, descriptors, mut test_client) = init_single_sig();
let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None)); let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
// need to sync so rpc can start watching // 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! { test_client.receive(testutils! {
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1) @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"); assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
let target_addr = receiver_wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address; 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(&tx1).unwrap();
blockchain.broadcast(&tx2).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"); 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); assert_eq!(wallet.get_balance().unwrap(), 100_000);
} }
@ -694,7 +694,7 @@ macro_rules! bdk_blockchain_tests {
@tx ( (@external descriptors, 0) => 50_000 ) @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.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<_, _>>(); 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()); assert!(details.confirmation_time.is_none());
test_client.generate(1, Some(node_addr)); 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 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(); let details = tx_map.get(&received_txid).unwrap();
@ -718,7 +718,7 @@ macro_rules! bdk_blockchain_tests {
@tx ( (@external descriptors, 0) => 50_000 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -730,7 +730,7 @@ macro_rules! bdk_blockchain_tests {
let sent_tx = psbt.extract_tx(); let sent_tx = psbt.extract_tx();
blockchain.broadcast(&sent_tx).unwrap(); 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"); assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect balance after receive");
// empty wallet // empty wallet
@ -739,7 +739,7 @@ macro_rules! bdk_blockchain_tests {
#[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti #[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti
test_client.generate(1, Some(node_addr)); 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 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(); let received = tx_map.get(&received_txid).unwrap();
@ -761,7 +761,7 @@ macro_rules! bdk_blockchain_tests {
@tx ( (@external descriptors, 0) => 50_000 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
let mut total_sent = 0; let mut total_sent = 0;
@ -773,12 +773,12 @@ macro_rules! bdk_blockchain_tests {
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&psbt.extract_tx()).unwrap(); 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); 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"); assert_eq!(wallet.get_balance().unwrap(), 50_000 - total_sent, "incorrect balance after chain");
// empty wallet // empty wallet
@ -788,7 +788,7 @@ macro_rules! bdk_blockchain_tests {
#[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti #[cfg(feature = "rpc")] // rpc cannot see mempool tx before importmulti
test_client.generate(1, Some(node_addr)); 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"); 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) @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"); assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -811,7 +811,7 @@ macro_rules! bdk_blockchain_tests {
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&psbt.extract_tx()).unwrap(); 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(), 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"); 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(); let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&new_psbt.extract_tx()).unwrap(); 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(), 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"); 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) @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"); assert_eq!(wallet.get_balance().unwrap(), 50_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -846,7 +846,7 @@ macro_rules! bdk_blockchain_tests {
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&psbt.extract_tx()).unwrap(); 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(), 1_000 - details.fee.unwrap_or(0), "incorrect balance after send");
assert_eq!(wallet.get_balance().unwrap(), details.received, "incorrect received 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(); let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&new_psbt.extract_tx()).unwrap(); 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!(wallet.get_balance().unwrap(), 0, "incorrect balance after change removal");
assert_eq!(new_details.received, 0, "incorrect received 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) @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"); assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -881,7 +881,7 @@ macro_rules! bdk_blockchain_tests {
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&psbt.extract_tx()).unwrap(); 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!(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"); 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(); let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&new_psbt.extract_tx()).unwrap(); 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!(new_details.sent, 75_000, "incorrect sent");
assert_eq!(wallet.get_balance().unwrap(), new_details.received, "incorrect balance after add input"); 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) @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"); assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -914,7 +914,7 @@ macro_rules! bdk_blockchain_tests {
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&psbt.extract_tx()).unwrap(); 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!(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"); 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(); let finalized = wallet.sign(&mut new_psbt, Default::default()).unwrap();
assert!(finalized, "Cannot finalize transaction"); assert!(finalized, "Cannot finalize transaction");
blockchain.broadcast(&new_psbt.extract_tx()).unwrap(); 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!(new_details.sent, 75_000, "incorrect sent");
assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance after add input"); assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance after add input");
assert_eq!(new_details.received, 0, "incorrect received 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 ) @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.get_balance().unwrap(), 50_000, "incorrect balance");
let mut builder = wallet.build_tx(); 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"); assert!(serialized_tx.windows(data.len()).any(|e| e==data), "cannot find op_return data in transaction");
blockchain.broadcast(&tx).unwrap(); blockchain.broadcast(&tx).unwrap();
test_client.generate(1, Some(node_addr)); 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"); 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<_, _>>(); 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; 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"); assert_eq!(wallet.get_balance().unwrap(), 0, "incorrect balance");
test_client.generate(1, Some(wallet_addr)); 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"); 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 ) @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"); 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 // 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"); assert!(finalized, "wallet cannot finalize transaction");
let tx = psbt.extract_tx(); let tx = psbt.extract_tx();
blockchain.broadcast(&tx).unwrap(); 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.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_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"); assert_eq!(wallet.list_unspent().unwrap().len(), 1, "wallet has incorrect number of unspents");

View File

@ -55,7 +55,7 @@ use signer::{SignOptions, Signer, SignerOrdering, SignersContainer};
use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams}; use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
use utils::{check_nlocktime, check_nsequence_rbf, After, Older, SecpCtx}; 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::memory::MemoryDatabase;
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils, SyncTime}; use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
use crate::descriptor::derived::AsDerived; 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> impl<D> Wallet<D>
where where
D: BatchDatabase, D: BatchDatabase,
@ -1431,27 +1442,26 @@ where
pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ { pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ {
self.database.borrow() self.database.borrow()
} }
}
impl<D> Wallet<D>
where
D: BatchDatabase,
{
/// Sync the internal database with the blockchain /// Sync the internal database with the blockchain
#[maybe_async] #[maybe_async]
pub fn sync<P: 'static + Progress, B: WalletSync + GetHeight>( pub fn sync<B: WalletSync + GetHeight>(
&self, &self,
blockchain: &B, blockchain: &B,
progress_update: P, sync_opts: SyncOptions,
max_address_param: Option<u32>,
) -> Result<(), Error> { ) -> Result<(), Error> {
debug!("Begin sync..."); debug!("Begin sync...");
let mut run_setup = false; 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() { let max_address = match self.descriptor.is_deriveable() {
false => 0, 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); debug!("max_address {}", max_address);
if self if self
@ -1468,7 +1478,7 @@ where
if let Some(change_descriptor) = &self.change_descriptor { if let Some(change_descriptor) = &self.change_descriptor {
let max_address = match change_descriptor.is_deriveable() { let max_address = match change_descriptor.is_deriveable() {
false => 0, false => 0,
true => max_address_param.unwrap_or(CACHE_ADDR_BATCH_SIZE), true => max_addresses.unwrap_or(CACHE_ADDR_BATCH_SIZE),
}; };
if self if self
@ -1488,12 +1498,10 @@ where
// TODO: we should sync if generating an address triggers a new batch to be stored // TODO: we should sync if generating an address triggers a new batch to be stored
if run_setup { if run_setup {
maybe_await!( maybe_await!(
blockchain.wallet_setup(self.database.borrow_mut().deref_mut(), progress_update,) blockchain.wallet_setup(self.database.borrow_mut().deref_mut(), progress,)
)?; )?;
} else { } else {
maybe_await!( maybe_await!(blockchain.wallet_sync(self.database.borrow_mut().deref_mut(), progress,))?;
blockchain.wallet_sync(self.database.borrow_mut().deref_mut(), progress_update,)
)?;
} }
let sync_time = SyncTime { let sync_time = SyncTime {