@@ -541,14 +541,77 @@ impl<A: Clone + Ord> TxGraph<A> {
541
541
542
542
/// Inserts the given `seen_at` for `txid` into [`TxGraph`].
543
543
///
544
- /// Note that [`TxGraph`] only keeps track of the latest `seen_at`.
544
+ /// Note that [`TxGraph`] only keeps track of the latest `seen_at`. To batch
545
+ /// update all unconfirmed transactions with the latest `seen_at`, see
546
+ /// [`update_last_seen_unconfirmed`].
547
+ ///
548
+ /// [`update_last_seen_unconfirmed`]: Self::update_last_seen_unconfirmed
545
549
pub fn insert_seen_at ( & mut self , txid : Txid , seen_at : u64 ) -> ChangeSet < A > {
546
550
let mut update = Self :: default ( ) ;
547
551
let ( _, _, update_last_seen) = update. txs . entry ( txid) . or_default ( ) ;
548
552
* update_last_seen = seen_at;
549
553
self . apply_update ( update)
550
554
}
551
555
556
+ /// Update the last seen time for all unconfirmed transactions.
557
+ ///
558
+ /// This method updates the last seen unconfirmed time for this [`TxGraph`] by inserting
559
+ /// the given `seen_at` for every transaction not yet anchored to a confirmed block,
560
+ /// and returns the [`ChangeSet`] after applying all updates to `self`.
561
+ ///
562
+ /// This is useful for keeping track of the latest time a transaction was seen
563
+ /// unconfirmed, which is important for evaluating transaction conflicts in the same
564
+ /// [`TxGraph`]. For details of how [`TxGraph`] resolves conflicts, see the docs for
565
+ /// [`try_get_chain_position`].
566
+ ///
567
+ /// A normal use of this method is to call it with the current system time. Although
568
+ /// block headers contain a timestamp, using the header time would be less effective
569
+ /// at tracking mempool transactions, because it can drift from actual clock time, plus
570
+ /// we may want to update a transaction's last seen time repeatedly between blocks.
571
+ ///
572
+ /// # Example
573
+ ///
574
+ /// ```rust
575
+ /// # use bdk_chain::example_utils::*;
576
+ /// # use std::time::UNIX_EPOCH;
577
+ /// # let tx = tx_from_hex(RAW_TX_1);
578
+ /// # let mut tx_graph = bdk_chain::TxGraph::<()>::new([tx]);
579
+ /// let now = std::time::SystemTime::now()
580
+ /// .duration_since(UNIX_EPOCH)
581
+ /// .expect("valid duration")
582
+ /// .as_secs();
583
+ /// let changeset = tx_graph.update_last_seen_unconfirmed(now);
584
+ /// assert!(!changeset.last_seen.is_empty());
585
+ /// ```
586
+ ///
587
+ /// Note that [`TxGraph`] only keeps track of the latest `seen_at`, so the given time must
588
+ /// by strictly greater than what is currently stored for a transaction to have an effect.
589
+ /// To insert a last seen time for a single txid, see [`insert_seen_at`].
590
+ ///
591
+ /// [`insert_seen_at`]: Self::insert_seen_at
592
+ /// [`try_get_chain_position`]: Self::try_get_chain_position
593
+ pub fn update_last_seen_unconfirmed ( & mut self , seen_at : u64 ) -> ChangeSet < A > {
594
+ let mut changeset = ChangeSet :: default ( ) ;
595
+ let unanchored_txs: Vec < Txid > = self
596
+ . txs
597
+ . iter ( )
598
+ . filter_map (
599
+ |( & txid, ( _, anchors, _) ) | {
600
+ if anchors. is_empty ( ) {
601
+ Some ( txid)
602
+ } else {
603
+ None
604
+ }
605
+ } ,
606
+ )
607
+ . collect ( ) ;
608
+
609
+ for txid in unanchored_txs {
610
+ changeset. append ( self . insert_seen_at ( txid, seen_at) ) ;
611
+ }
612
+ changeset
613
+ }
614
+
552
615
/// Extends this graph with another so that `self` becomes the union of the two sets of
553
616
/// transactions.
554
617
///
0 commit comments