Skip to content

Commit a7668a2

Browse files
committed
[wallet_redesign] Modified insert_tx to use lowest checkpoint
Also updated the documentation.
1 parent ac80829 commit a7668a2

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -451,17 +451,20 @@ impl<D> Wallet<D> {
451451
Ok(changed)
452452
}
453453

454-
/// Add a transaction to the wallet's internal view of the chain.
455-
/// This stages but does not [`commit`] the change.
456-
///
457-
/// There are a number reasons `tx` could be rejected with an `Err(_)`. The most important one
458-
/// is that the transaction is at a height that is greater than [`latest_checkpoint`]. Therefore
459-
/// you should use [`insert_checkpoint`] to insert new checkpoints before manually inserting new
460-
/// transactions.
454+
/// Add a transaction to the wallet's internal view of the chain. This stages but does not
455+
/// [`commit`] the change.
461456
///
462457
/// Returns whether anything changed with the transaction insertion (e.g. `false` if the
463458
/// transaction was already inserted at the same position).
464459
///
460+
/// A `tx` can be rejected if `position` has a height greater than the [`latest_checkpoint`].
461+
/// Therefore you should use [`insert_checkpoint`] to insert new checkpoints before manually
462+
/// inserting new transactions.
463+
///
464+
/// **WARNING:** If `position` is confirmed, we anchor the `tx` to a the lowest checkpoint that
465+
/// is >= the `position`'s height. The caller is responsible for ensuring the `tx` exists in our
466+
/// local view of the best chain's history.
467+
///
465468
/// [`commit`]: Self::commit
466469
/// [`latest_checkpoint`]: Self::latest_checkpoint
467470
/// [`insert_checkpoint`]: Self::insert_checkpoint
@@ -473,25 +476,28 @@ impl<D> Wallet<D> {
473476
where
474477
D: PersistBackend<ChangeSet>,
475478
{
476-
let tip = self.chain.tip();
477-
478479
let (anchor, last_seen) = match position {
479480
ConfirmationTime::Confirmed { height, time } => {
480-
let tip_height = tip.map(|b| b.height);
481-
if Some(height) > tip_height {
482-
return Err(InsertTxError::ConfirmationHeightCannotBeGreaterThanTip {
483-
tip_height,
481+
// anchor tx to checkpoint with lowest height that is >= position's height
482+
let anchor = self
483+
.chain
484+
.blocks()
485+
.range(height..)
486+
.next()
487+
.ok_or(InsertTxError::ConfirmationHeightCannotBeGreaterThanTip {
488+
tip_height: self.chain.tip().map(|b| b.height),
484489
tx_height: height,
485-
});
486-
}
487-
(
488-
Some(ConfirmationTimeAnchor {
489-
anchor_block: tip.expect("already checked if tip_height > height"),
490+
})
491+
.map(|(&anchor_height, &anchor_hash)| ConfirmationTimeAnchor {
492+
anchor_block: BlockId {
493+
height: anchor_height,
494+
hash: anchor_hash,
495+
},
490496
confirmation_height: height,
491497
confirmation_time: time,
492-
}),
493-
None,
494-
)
498+
})?;
499+
500+
(Some(anchor), None)
495501
}
496502
ConfirmationTime::Unconfirmed { last_seen } => (None, Some(last_seen)),
497503
};

0 commit comments

Comments
 (0)