Skip to content

Commit b74c2e2

Browse files
committed
fix(wallet): use efficient peek address logic
Changes the peek address logic to use the optimized `Iterator::nth` implementation of `SpkIterator`. Additionally, docs are added for panics that will occur when the caller requests for addresses with out-of-bound derivation indices (BIP32).
1 parent 81aeaba commit b74c2e2

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ where
262262
/// Infallibly return a derived address using the external descriptor, see [`AddressIndex`] for
263263
/// available address index selection strategies. If none of the keys in the descriptor are derivable
264264
/// (i.e. does not end with /*) then the same address will always be returned for any [`AddressIndex`].
265+
///
266+
/// # Panics
267+
///
268+
/// This panics when the caller requests for an address of derivation index greater than the
269+
/// BIP32 max index.
265270
pub fn get_address(&mut self, address_index: AddressIndex) -> AddressInfo {
266271
self.try_get_address(address_index).unwrap()
267272
}
@@ -273,6 +278,11 @@ where
273278
/// see [`AddressIndex`] for available address index selection strategies. If none of the keys
274279
/// in the descriptor are derivable (i.e. does not end with /*) then the same address will always
275280
/// be returned for any [`AddressIndex`].
281+
///
282+
/// # Panics
283+
///
284+
/// This panics when the caller requests for an address of derivation index greater than the
285+
/// BIP32 max index.
276286
pub fn get_internal_address(&mut self, address_index: AddressIndex) -> AddressInfo {
277287
self.try_get_internal_address(address_index).unwrap()
278288
}
@@ -649,6 +659,11 @@ impl<D> Wallet<D> {
649659
///
650660
/// A `PersistBackend<ChangeSet>::WriteError` will result if unable to persist the new address
651661
/// to the `PersistBackend`.
662+
///
663+
/// # Panics
664+
///
665+
/// This panics when the caller requests for an address of derivation index greater than the
666+
/// BIP32 max index.
652667
pub fn try_get_address(
653668
&mut self,
654669
address_index: AddressIndex,
@@ -669,6 +684,11 @@ impl<D> Wallet<D> {
669684
/// see [`AddressIndex`] for available address index selection strategies. If none of the keys
670685
/// in the descriptor are derivable (i.e. does not end with /*) then the same address will always
671686
/// be returned for any [`AddressIndex`].
687+
///
688+
/// # Panics
689+
///
690+
/// This panics when the caller requests for an address of derivation index greater than the
691+
/// BIP32 max index.
672692
pub fn try_get_internal_address(
673693
&mut self,
674694
address_index: AddressIndex,
@@ -691,6 +711,11 @@ impl<D> Wallet<D> {
691711
/// See [`AddressIndex`] for available address index selection strategies. If none of the keys
692712
/// in the descriptor are derivable (i.e. does not end with /*) then the same address will
693713
/// always be returned for any [`AddressIndex`].
714+
///
715+
/// # Panics
716+
///
717+
/// This panics when the caller requests for an address of derivation index greater than the
718+
/// BIP32 max index.
694719
fn _get_address(
695720
&mut self,
696721
keychain: KeychainKind,
@@ -710,12 +735,14 @@ impl<D> Wallet<D> {
710735
let ((index, spk), index_changeset) = txout_index.next_unused_spk(&keychain);
711736
(index, spk.into(), Some(index_changeset))
712737
}
713-
AddressIndex::Peek(index) => {
714-
let (index, spk) = txout_index
715-
.unbounded_spk_iter(&keychain)
716-
.take(index as usize + 1)
717-
.last()
718-
.unwrap();
738+
AddressIndex::Peek(mut peek_index) => {
739+
let mut spk_iter = txout_index.unbounded_spk_iter(&keychain);
740+
if !spk_iter.descriptor().has_wildcard() {
741+
peek_index = 0;
742+
}
743+
let (index, spk) = spk_iter
744+
.nth(peek_index as usize)
745+
.expect("derivation index is out of bounds");
719746
(index, spk, None)
720747
}
721748
};

0 commit comments

Comments
 (0)