]> Untitled Git - bdk/commitdiff
fix(wallet)!: Rework `Wallet::insert_tx` to no longer insert anchors
authorvalued mammal <valuedmammal@protonmail.com>
Mon, 20 May 2024 11:01:05 +0000 (07:01 -0400)
committervalued mammal <valuedmammal@protonmail.com>
Sun, 23 Jun 2024 17:15:23 +0000 (13:15 -0400)
since we'd be lacking context that should normally occur during
sync with a chain source. The logic for inserting a graph
anchor from a `ConfirmationTime` is moved to the wallet common
test module in order to simulate receiving new txs and
confirming them.

crates/wallet/src/wallet/export.rs
crates/wallet/src/wallet/mod.rs
crates/wallet/tests/common.rs
crates/wallet/tests/wallet.rs

index 0aa3ec887ce64bfc290b779d3406e8bbcc40bfd7..c4a3c0961cb47c4ec3fd4e50ab8e8865899582a1 100644 (file)
@@ -214,7 +214,7 @@ mod test {
     use core::str::FromStr;
 
     use crate::std::string::ToString;
-    use bdk_chain::{BlockId, ConfirmationTime};
+    use bdk_chain::{BlockId, ConfirmationTimeHeightAnchor};
     use bitcoin::hashes::Hash;
     use bitcoin::{transaction, BlockHash, Network, Transaction};
 
@@ -229,21 +229,21 @@ mod test {
             version: transaction::Version::non_standard(0),
             lock_time: bitcoin::absolute::LockTime::ZERO,
         };
-        wallet
-            .insert_checkpoint(BlockId {
-                height: 5001,
-                hash: BlockHash::all_zeros(),
-            })
-            .unwrap();
-        wallet
-            .insert_tx(
-                transaction,
-                ConfirmationTime::Confirmed {
-                    height: 5000,
-                    time: 0,
-                },
-            )
-            .unwrap();
+        let txid = transaction.compute_txid();
+        let block_id = BlockId {
+            height: 5001,
+            hash: BlockHash::all_zeros(),
+        };
+        wallet.insert_checkpoint(block_id).unwrap();
+        wallet.insert_tx(transaction);
+        wallet.insert_anchor(
+            txid,
+            ConfirmationTimeHeightAnchor {
+                confirmation_height: 5000,
+                confirmation_time: 0,
+                anchor_block: block_id,
+            },
+        );
         wallet
     }
 
index 400ecde1d00733a0633309ec516e142cddb5f4c7..85c47aede18eab6f8b06b3ae8ff91a8a233dc32d 100644 (file)
@@ -284,35 +284,6 @@ impl fmt::Display for NewOrLoadError {
 #[cfg(feature = "std")]
 impl std::error::Error for NewOrLoadError {}
 
-/// An error that may occur when inserting a transaction into [`Wallet`].
-#[derive(Debug)]
-pub enum InsertTxError {
-    /// The error variant that occurs when the caller attempts to insert a transaction with a
-    /// confirmation height that is greater than the internal chain tip.
-    ConfirmationHeightCannotBeGreaterThanTip {
-        /// The internal chain's tip height.
-        tip_height: u32,
-        /// The introduced transaction's confirmation height.
-        tx_height: u32,
-    },
-}
-
-impl fmt::Display for InsertTxError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            InsertTxError::ConfirmationHeightCannotBeGreaterThanTip {
-                tip_height,
-                tx_height,
-            } => {
-                write!(f, "cannot insert tx with confirmation height ({}) higher than internal tip height ({})", tx_height, tip_height)
-            }
-        }
-    }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for InsertTxError {}
-
 /// An error that may occur when applying a block to [`Wallet`].
 #[derive(Debug)]
 pub enum ApplyBlockError {
@@ -906,6 +877,23 @@ impl Wallet {
         self.stage.append(additions.into());
     }
 
+    /// Inserts an `anchor` for a transaction with the given `txid`.
+    ///
+    /// This stages the changes, you must persist them later.
+    pub fn insert_anchor(&mut self, txid: Txid, anchor: ConfirmationTimeHeightAnchor) {
+        let indexed_graph_changeset = self.indexed_graph.insert_anchor(txid, anchor);
+        self.stage.append(indexed_graph_changeset.into());
+    }
+
+    /// Inserts a unix timestamp of when a transaction is seen in the mempool.
+    ///
+    /// This is used for transaction conflict resolution where the transaction with the
+    /// later last-seen is prioritized. This stages the changes, you must persist them later.
+    pub fn insert_seen_at(&mut self, txid: Txid, seen_at: u64) {
+        let indexed_graph_changeset = self.indexed_graph.insert_seen_at(txid, seen_at);
+        self.stage.append(indexed_graph_changeset.into());
+    }
+
     /// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase transaction.
     ///
     /// To calculate the fee for a [`Transaction`] with inputs not owned by this wallet you must
@@ -1079,63 +1067,21 @@ impl Wallet {
     /// Add a transaction to the wallet's internal view of the chain. This stages the change,
     /// you must persist it later.
     ///
-    /// Returns whether anything changed with the transaction insertion (e.g. `false` if the
-    /// transaction was already inserted at the same position).
+    /// This method inserts the given `tx` and returns whether anything changed after insertion,
+    /// which will be false if the same transaction already exists in the wallet's transaction
+    /// graph. Any changes are staged but not committed.
     ///
-    /// A `tx` can be rejected if `position` has a height greater than the [`latest_checkpoint`].
-    /// Therefore you should use [`insert_checkpoint`] to insert new checkpoints before manually
-    /// inserting new transactions.
+    /// # Note
     ///
-    /// **WARNING**: If `position` is confirmed, we anchor the `tx` to the lowest checkpoint that
-    /// is >= the `position`'s height. The caller is responsible for ensuring the `tx` exists in our
-    /// local view of the best chain's history.
-    ///
-    /// You must persist the changes resulting from one or more calls to this method if you need
-    /// the inserted tx to be reloaded after closing the wallet.
-    ///
-    /// [`commit`]: Self::commit
-    /// [`latest_checkpoint`]: Self::latest_checkpoint
-    /// [`insert_checkpoint`]: Self::insert_checkpoint
-    pub fn insert_tx(
-        &mut self,
-        tx: Transaction,
-        position: ConfirmationTime,
-    ) -> Result<bool, InsertTxError> {
-        let (anchor, last_seen) = match position {
-            ConfirmationTime::Confirmed { height, time } => {
-                // anchor tx to checkpoint with lowest height that is >= position's height
-                let anchor = self
-                    .chain
-                    .range(height..)
-                    .last()
-                    .ok_or(InsertTxError::ConfirmationHeightCannotBeGreaterThanTip {
-                        tip_height: self.chain.tip().height(),
-                        tx_height: height,
-                    })
-                    .map(|anchor_cp| ConfirmationTimeHeightAnchor {
-                        anchor_block: anchor_cp.block_id(),
-                        confirmation_height: height,
-                        confirmation_time: time,
-                    })?;
-
-                (Some(anchor), None)
-            }
-            ConfirmationTime::Unconfirmed { last_seen } => (None, Some(last_seen)),
-        };
-
+    /// By default the inserted `tx` won't be considered "canonical" because it's not known
+    /// whether the transaction exists in the best chain. To know whether it exists, the tx
+    /// must be broadcast to the network and the wallet synced via a chain source.
+    pub fn insert_tx(&mut self, tx: Transaction) -> bool {
         let mut changeset = ChangeSet::default();
-        let txid = tx.compute_txid();
         changeset.append(self.indexed_graph.insert_tx(tx).into());
-        if let Some(anchor) = anchor {
-            changeset.append(self.indexed_graph.insert_anchor(txid, anchor).into());
-        }
-        if let Some(last_seen) = last_seen {
-            changeset.append(self.indexed_graph.insert_seen_at(txid, last_seen).into());
-        }
-
-        let changed = !changeset.is_empty();
+        let ret = !changeset.is_empty();
         self.stage.append(changeset);
-        Ok(changed)
+        ret
     }
 
     /// Iterate over the transactions in the wallet.
@@ -2540,7 +2486,7 @@ macro_rules! floating_rate {
 macro_rules! doctest_wallet {
     () => {{
         use $crate::bitcoin::{BlockHash, Transaction, absolute, TxOut, Network, hashes::Hash};
-        use $crate::chain::{ConfirmationTime, BlockId};
+        use $crate::chain::{ConfirmationTimeHeightAnchor, BlockId};
         use $crate::{KeychainKind, wallet::Wallet};
         let descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/0/*)";
         let change_descriptor = "tr([73c5da0a/86'/0'/0']tprv8fMn4hSKPRC1oaCPqxDb1JWtgkpeiQvZhsr8W2xuy3GEMkzoArcAWTfJxYb6Wj8XNNDWEjfYKK4wGQXh3ZUXhDF2NcnsALpWTeSwarJt7Vc/1/*)";
@@ -2561,11 +2507,19 @@ macro_rules! doctest_wallet {
                 script_pubkey: address.script_pubkey(),
             }],
         };
-        let _ = wallet.insert_checkpoint(BlockId { height: 1_000, hash: BlockHash::all_zeros() });
-        let _ = wallet.insert_tx(tx.clone(), ConfirmationTime::Confirmed {
-            height: 500,
-            time: 50_000
-        });
+        let txid = tx.txid();
+        let block = BlockId { height: 1_000, hash: BlockHash::all_zeros() };
+        let _ = wallet.insert_checkpoint(block);
+        let _ = wallet.insert_tx(tx);
+        wallet
+            .insert_anchor(
+                txid,
+                ConfirmationTimeHeightAnchor {
+                    confirmation_height: 500,
+                    confirmation_time: 50_000,
+                    anchor_block: block,
+                }
+            );
 
         wallet
     }}
index bab75e275cb8c087d0a2b02b008c00190dda7011..2d4bb8527379d1a86d543e56b34b4801b635665b 100644 (file)
@@ -1,7 +1,7 @@
 #![allow(unused)]
 
 use bdk_chain::indexed_tx_graph::Indexer;
-use bdk_chain::{BlockId, ConfirmationTime};
+use bdk_chain::{BlockId, ConfirmationTime, ConfirmationTimeHeightAnchor};
 use bdk_wallet::{KeychainKind, LocalOutput, Wallet};
 use bitcoin::hashes::Hash;
 use bitcoin::{
@@ -77,24 +77,26 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
             hash: BlockHash::all_zeros(),
         })
         .unwrap();
-    wallet
-        .insert_tx(
-            tx0,
-            ConfirmationTime::Confirmed {
-                height: 1_000,
-                time: 100,
-            },
-        )
-        .unwrap();
-    wallet
-        .insert_tx(
-            tx1.clone(),
-            ConfirmationTime::Confirmed {
-                height: 2_000,
-                time: 200,
-            },
-        )
-        .unwrap();
+
+    wallet.insert_tx(tx0.clone());
+    insert_anchor_from_conf(
+        &mut wallet,
+        tx0.compute_txid(),
+        ConfirmationTime::Confirmed {
+            height: 1_000,
+            time: 100,
+        },
+    );
+
+    wallet.insert_tx(tx1.clone());
+    insert_anchor_from_conf(
+        &mut wallet,
+        tx1.compute_txid(),
+        ConfirmationTime::Confirmed {
+            height: 2_000,
+            time: 200,
+        },
+    );
 
     (wallet, tx1.compute_txid())
 }
@@ -192,3 +194,24 @@ pub fn feerate_unchecked(sat_vb: f64) -> FeeRate {
     let sat_kwu = (sat_vb * 250.0).ceil() as u64;
     FeeRate::from_sat_per_kwu(sat_kwu)
 }
+
+/// Simulates confirming a tx with `txid` at the specified `position` by inserting an anchor
+/// at the lowest height in local chain that is greater or equal to `position`'s height,
+/// assuming the confirmation time matches `ConfirmationTime::Confirmed`.
+pub fn insert_anchor_from_conf(wallet: &mut Wallet, txid: Txid, position: ConfirmationTime) {
+    if let ConfirmationTime::Confirmed { height, time } = position {
+        // anchor tx to checkpoint with lowest height that is >= position's height
+        let anchor = wallet
+            .local_chain()
+            .range(height..)
+            .last()
+            .map(|anchor_cp| ConfirmationTimeHeightAnchor {
+                anchor_block: anchor_cp.block_id(),
+                confirmation_height: height,
+                confirmation_time: time,
+            })
+            .expect("confirmation height cannot be greater than tip");
+
+        wallet.insert_anchor(txid, anchor);
+    }
+}
index ef5575acb3b1cef74caab443dab4931ca8fc1d46..bf5075e88e8df68248a1735c91417da6f75ccbe0 100644 (file)
@@ -42,12 +42,19 @@ fn receive_output(wallet: &mut Wallet, value: u64, height: ConfirmationTime) ->
         }],
     };
 
-    wallet.insert_tx(tx.clone(), height).unwrap();
+    let txid = tx.compute_txid();
+    wallet.insert_tx(tx);
 
-    OutPoint {
-        txid: tx.compute_txid(),
-        vout: 0,
+    match height {
+        ConfirmationTime::Confirmed { .. } => {
+            insert_anchor_from_conf(wallet, txid, height);
+        }
+        ConfirmationTime::Unconfirmed { last_seen } => {
+            wallet.insert_seen_at(txid, last_seen);
+        }
     }
+
+    OutPoint { txid, vout: 0 }
 }
 
 fn receive_output_in_latest_block(wallet: &mut Wallet, value: u64) -> OutPoint {
@@ -1180,12 +1187,7 @@ fn test_create_tx_add_utxo() {
         version: transaction::Version::non_standard(0),
         lock_time: absolute::LockTime::ZERO,
     };
-    wallet
-        .insert_tx(
-            small_output_tx.clone(),
-            ConfirmationTime::Unconfirmed { last_seen: 0 },
-        )
-        .unwrap();
+    wallet.insert_tx(small_output_tx.clone());
 
     let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
         .unwrap()
@@ -1230,12 +1232,7 @@ fn test_create_tx_manually_selected_insufficient() {
         lock_time: absolute::LockTime::ZERO,
     };
 
-    wallet
-        .insert_tx(
-            small_output_tx.clone(),
-            ConfirmationTime::Unconfirmed { last_seen: 0 },
-        )
-        .unwrap();
+    wallet.insert_tx(small_output_tx.clone());
 
     let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
         .unwrap()
@@ -1281,9 +1278,7 @@ fn test_create_tx_policy_path_no_csv() {
             value: Amount::from_sat(50_000),
         }],
     };
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
     let root_id = external_policy.id;
@@ -1674,9 +1669,7 @@ fn test_bump_fee_irreplaceable_tx() {
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
     wallet.build_fee_bump(txid).unwrap().finish().unwrap();
 }
 
@@ -1692,15 +1685,15 @@ fn test_bump_fee_confirmed_tx() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
 
-    wallet
-        .insert_tx(
-            tx,
-            ConfirmationTime::Confirmed {
-                height: 42,
-                time: 42_000,
-            },
-        )
-        .unwrap();
+    wallet.insert_tx(tx);
+    insert_anchor_from_conf(
+        &mut wallet,
+        txid,
+        ConfirmationTime::Confirmed {
+            height: 42,
+            time: 42_000,
+        },
+    );
 
     wallet.build_fee_bump(txid).unwrap().finish().unwrap();
 }
@@ -1719,9 +1712,7 @@ fn test_bump_fee_low_fee_rate() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
 
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_rate(FeeRate::BROADCAST_MIN);
@@ -1752,9 +1743,7 @@ fn test_bump_fee_low_abs() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
 
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_absolute(Amount::from_sat(10));
@@ -1774,9 +1763,7 @@ fn test_bump_fee_zero_abs() {
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_absolute(Amount::ZERO);
@@ -1800,9 +1787,7 @@ fn test_bump_fee_reduce_change() {
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let feerate = FeeRate::from_sat_per_kwu(625); // 2.5 sat/vb
     let mut builder = wallet.build_fee_bump(txid).unwrap();
@@ -1898,9 +1883,7 @@ fn test_bump_fee_reduce_single_recipient() {
     let original_sent_received = wallet.sent_and_received(&tx);
     let original_fee = check_fee!(wallet, psbt);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let feerate = FeeRate::from_sat_per_kwu(625); // 2.5 sat/vb
     let mut builder = wallet.build_fee_bump(txid).unwrap();
@@ -1946,9 +1929,7 @@ fn test_bump_fee_absolute_reduce_single_recipient() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder
@@ -1991,15 +1972,18 @@ fn test_bump_fee_drain_wallet() {
             value: Amount::from_sat(25_000),
         }],
     };
-    wallet
-        .insert_tx(
-            tx.clone(),
-            ConfirmationTime::Confirmed {
-                height: wallet.latest_checkpoint().height(),
-                time: 42_000,
-            },
-        )
-        .unwrap();
+    let txid = tx.compute_txid();
+    let tip = wallet.latest_checkpoint().height();
+    wallet.insert_tx(tx.clone());
+    insert_anchor_from_conf(
+        &mut wallet,
+        txid,
+        ConfirmationTime::Confirmed {
+            height: tip,
+            time: 42_000,
+        },
+    );
+
     let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
         .unwrap()
         .assume_checked();
@@ -2019,9 +2003,7 @@ fn test_bump_fee_drain_wallet() {
     let original_sent_received = wallet.sent_and_received(&tx);
 
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
     assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
 
     // for the new feerate, it should be enough to reduce the output, but since we specify
@@ -2056,18 +2038,17 @@ fn test_bump_fee_remove_output_manually_selected_only() {
             value: Amount::from_sat(25_000),
         }],
     };
-    wallet
-        .insert_tx(
-            init_tx.clone(),
-            wallet
-                .transactions()
-                .last()
-                .unwrap()
-                .chain_position
-                .cloned()
-                .into(),
-        )
-        .unwrap();
+    let position: ConfirmationTime = wallet
+        .transactions()
+        .last()
+        .unwrap()
+        .chain_position
+        .cloned()
+        .into();
+
+    wallet.insert_tx(init_tx.clone());
+    insert_anchor_from_conf(&mut wallet, init_tx.compute_txid(), position);
+
     let outpoint = OutPoint {
         txid: init_tx.compute_txid(),
         vout: 0,
@@ -2086,9 +2067,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
     assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
@@ -2112,14 +2091,16 @@ fn test_bump_fee_add_input() {
             value: Amount::from_sat(25_000),
         }],
     };
-    let pos = wallet
+    let txid = init_tx.compute_txid();
+    let pos: ConfirmationTime = wallet
         .transactions()
         .last()
         .unwrap()
         .chain_position
         .cloned()
         .into();
-    wallet.insert_tx(init_tx, pos).unwrap();
+    wallet.insert_tx(init_tx);
+    insert_anchor_from_conf(&mut wallet, txid, pos);
 
     let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
         .unwrap()
@@ -2132,9 +2113,7 @@ fn test_bump_fee_add_input() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_details = wallet.sent_and_received(&tx);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_rate(FeeRate::from_sat_per_vb_unchecked(50));
@@ -2189,9 +2168,7 @@ fn test_bump_fee_absolute_add_input() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_absolute(Amount::from_sat(6_000));
@@ -2255,9 +2232,7 @@ fn test_bump_fee_no_change_add_input_and_change() {
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     // Now bump the fees, the wallet should add an extra input and a change output, and leave
     // the original output untouched.
@@ -2325,9 +2300,7 @@ fn test_bump_fee_add_input_change_dust() {
     assert_eq!(tx.input.len(), 1);
     assert_eq!(tx.output.len(), 2);
     let txid = tx.compute_txid();
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     // We set a fee high enough that during rbf we are forced to add
@@ -2396,9 +2369,7 @@ fn test_bump_fee_force_add_input() {
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
-    wallet
-        .insert_tx(tx.clone(), ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx.clone());
     // the new fee_rate is low enough that just reducing the change would be fine, but we force
     // the addition of an extra input with `add_utxo()`
     let mut builder = wallet.build_fee_bump(txid).unwrap();
@@ -2463,9 +2434,7 @@ fn test_bump_fee_absolute_force_add_input() {
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
-    wallet
-        .insert_tx(tx.clone(), ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx.clone());
 
     // the new fee_rate is low enough that just reducing the change would be fine, but we force
     // the addition of an extra input with `add_utxo()`
@@ -2542,9 +2511,7 @@ fn test_bump_fee_unconfirmed_inputs_only() {
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder.fee_rate(FeeRate::from_sat_per_vb_unchecked(25));
     builder.finish().unwrap();
@@ -2575,9 +2542,7 @@ fn test_bump_fee_unconfirmed_input() {
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
-    wallet
-        .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
-        .unwrap();
+    wallet.insert_tx(tx);
 
     let mut builder = wallet.build_fee_bump(txid).unwrap();
     builder
@@ -3774,15 +3739,16 @@ fn test_spend_coinbase() {
             value: Amount::from_sat(25_000),
         }],
     };
-    wallet
-        .insert_tx(
-            coinbase_tx,
-            ConfirmationTime::Confirmed {
-                height: confirmation_height,
-                time: 30_000,
-            },
-        )
-        .unwrap();
+    let txid = coinbase_tx.compute_txid();
+    wallet.insert_tx(coinbase_tx);
+    insert_anchor_from_conf(
+        &mut wallet,
+        txid,
+        ConfirmationTime::Confirmed {
+            height: confirmation_height,
+            time: 30_000,
+        },
+    );
 
     let not_yet_mature_time = confirmation_height + COINBASE_MATURITY - 1;
     let maturity_time = confirmation_height + COINBASE_MATURITY;