]> Untitled Git - bdk/commitdiff
test(wallet): verify wallet panics in dev mode if using keychains with duplicate...
authorSteve Myers <steve@notmandatory.org>
Wed, 26 Jun 2024 17:01:52 +0000 (12:01 -0500)
committerSteve Myers <steve@notmandatory.org>
Thu, 27 Jun 2024 12:56:09 +0000 (07:56 -0500)
crates/wallet/tests/wallet.rs

index ef5575acb3b1cef74caab443dab4931ca8fc1d46..e250a0a5367a2777bcd90168dff6a378b5841a5d 100644 (file)
@@ -31,7 +31,16 @@ mod common;
 use common::*;
 
 fn receive_output(wallet: &mut Wallet, value: u64, height: ConfirmationTime) -> OutPoint {
-    let addr = wallet.next_unused_address(KeychainKind::External);
+    let addr = wallet.next_unused_address(KeychainKind::External).address;
+    receive_output_to_address(wallet, addr, value, height)
+}
+
+fn receive_output_to_address(
+    wallet: &mut Wallet,
+    addr: Address,
+    value: u64,
+    height: ConfirmationTime,
+) -> OutPoint {
     let tx = Transaction {
         version: transaction::Version::ONE,
         lock_time: absolute::LockTime::ZERO,
@@ -3997,6 +4006,44 @@ fn test_taproot_load_descriptor_duplicated_keys() {
     );
 }
 
+/// In dev mode this test panics, but in release mode, or if the `debug_panic` in `TxOutIndex::replenish_inner_index`
+/// is commented out, there is no panic and the balance is calculated correctly. See issue [#1483]
+/// and PR [#1486] for discussion on mixing non-wildcard and wildcard descriptors.
+///
+/// [#1483]: https://github.com/bitcoindevkit/bdk/issues/1483
+/// [#1486]: https://github.com/bitcoindevkit/bdk/pull/1486
+#[test]
+#[should_panic(
+    expected = "replenish lookahead: must not have existing spk: keychain=Internal, lookahead=25, next_store_index=0, next_reveal_index=0"
+)]
+fn test_keychains_with_overlapping_spks() {
+    // this can happen if a non-wildcard descriptor keychain derives an spk that a
+    // wildcard descriptor keychain in the same wallet also derives.
+
+    // index 1 spk overlaps with non-wildcard change descriptor
+    let wildcard_keychain = "wpkh(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*)";
+    let non_wildcard_keychain = "wpkh(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/1)";
+
+    let (mut wallet, _) = get_funded_wallet_with_change(wildcard_keychain, non_wildcard_keychain);
+    assert_eq!(wallet.balance().confirmed, Amount::from_sat(50000));
+
+    let addr = wallet
+        .reveal_addresses_to(KeychainKind::External, 1)
+        .last()
+        .unwrap()
+        .address;
+    let _outpoint = receive_output_to_address(
+        &mut wallet,
+        addr,
+        8000,
+        ConfirmationTime::Confirmed {
+            height: 2000,
+            time: 0,
+        },
+    );
+    assert_eq!(wallet.balance().confirmed, Amount::from_sat(58000));
+}
+
 #[test]
 /// The wallet should re-use previously allocated change addresses when the tx using them is cancelled
 fn test_tx_cancellation() {