From b9357a637c73a8fe4be668a2a48757b946328a04 Mon Sep 17 00:00:00 2001 From: rustaceanrob Date: Tue, 2 Dec 2025 09:41:00 +0000 Subject: [PATCH] feat: Add wallet birthday to `CreateParams` There has been discussion offline on how to improve the experience for recovering wallets using block-by-block scanning methods. A birthday has come up multiple times, so I introduce one here in `CreateParams`. I believe the `expect` may only be hit when attempting to over-write the genesis block. If we want to return the error, it would require a break in the error type. IMO this seems unnecessary, as a birthday should not attempt to replace genesis. This may be used immediately in `Wallet::latest_checkpoint` or similar. --- src/wallet/mod.rs | 7 ++++++- src/wallet/params.rs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 137aecc38..9d782967c 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -447,7 +447,12 @@ impl Wallet { let genesis_hash = params .genesis_hash .unwrap_or(genesis_block(network).block_hash()); - let (chain, chain_changeset) = LocalChain::from_genesis_hash(genesis_hash); + let (mut chain, chain_changeset) = LocalChain::from_genesis_hash(genesis_hash); + if let Some(birthday) = params.birthday { + chain + .apply_update(CheckPoint::new(birthday)) + .expect("wallet birthday overrides genesis hash."); + } let (descriptor, mut descriptor_keymap) = (params.descriptor)(&secp, network_kind)?; check_wallet_descriptor(&descriptor)?; diff --git a/src/wallet/params.rs b/src/wallet/params.rs index 4868074bb..b4cd6a419 100644 --- a/src/wallet/params.rs +++ b/src/wallet/params.rs @@ -1,6 +1,6 @@ use alloc::boxed::Box; -use bdk_chain::keychain_txout::DEFAULT_LOOKAHEAD; +use bdk_chain::{keychain_txout::DEFAULT_LOOKAHEAD, BlockId}; use bitcoin::{BlockHash, Network, NetworkKind}; use miniscript::descriptor::KeyMap; @@ -65,6 +65,7 @@ pub struct CreateParams { pub(crate) change_descriptor_keymap: KeyMap, pub(crate) network: Network, pub(crate) genesis_hash: Option, + pub(crate) birthday: Option, pub(crate) lookahead: u32, pub(crate) use_spk_cache: bool, } @@ -88,6 +89,7 @@ impl CreateParams { change_descriptor_keymap: KeyMap::default(), network: Network::Bitcoin, genesis_hash: None, + birthday: None, lookahead: DEFAULT_LOOKAHEAD, use_spk_cache: false, } @@ -110,6 +112,7 @@ impl CreateParams { change_descriptor_keymap: KeyMap::default(), network: Network::Bitcoin, genesis_hash: None, + birthday: None, lookahead: DEFAULT_LOOKAHEAD, use_spk_cache: false, } @@ -135,6 +138,7 @@ impl CreateParams { change_descriptor_keymap: KeyMap::default(), network: Network::Bitcoin, genesis_hash: None, + birthday: None, lookahead: DEFAULT_LOOKAHEAD, use_spk_cache: false, } @@ -162,6 +166,13 @@ impl CreateParams { self } + /// Begin wallet scanning from the specified birthday. Particularly useful for block-based + /// scanning sources. + pub fn birthday(mut self, birthday: BlockId) -> Self { + self.birthday = Some(birthday); + self + } + /// Use a custom `lookahead` value. /// /// The `lookahead` defines a number of script pubkeys to derive over and above the last