]> Untitled Git - bdk/commitdiff
feat(chain,wallet)!: change methods to take in generic instead of `&Transaction`
author志宇 <hello@evanlinjin.me>
Mon, 2 Sep 2024 09:59:09 +0000 (17:59 +0800)
committer志宇 <hello@evanlinjin.me>
Tue, 3 Sep 2024 06:03:07 +0000 (14:03 +0800)
* `Wallet::apply_unconfirmed_txs`
* `IndexedTxGraph::batch_insert_relevant`
* `IndexedTxGraph::batch_insert_relevant_unconfirmed`

crates/chain/src/indexed_tx_graph.rs
crates/chain/tests/test_indexed_tx_graph.rs
crates/wallet/src/wallet/mod.rs
example-crates/example_bitcoind_rpc_polling/src/main.rs
example-crates/wallet_rpc/src/main.rs

index b2da7bf75b3db3d4b1b2a279a97aa2f1291be5d7..9cb1e820ee558432211f664f595c2c060e495616 100644 (file)
@@ -156,9 +156,9 @@ where
     ///
     /// Relevancy is determined by the [`Indexer::is_tx_relevant`] implementation of `I`. Irrelevant
     /// transactions in `txs` will be ignored. `txs` do not need to be in topological order.
-    pub fn batch_insert_relevant<'t>(
+    pub fn batch_insert_relevant<T: Into<Arc<Transaction>>>(
         &mut self,
-        txs: impl IntoIterator<Item = (&'t Transaction, impl IntoIterator<Item = A>)>,
+        txs: impl IntoIterator<Item = (T, impl IntoIterator<Item = A>)>,
     ) -> ChangeSet<A, I::ChangeSet> {
         // The algorithm below allows for non-topologically ordered transactions by using two loops.
         // This is achieved by:
@@ -166,28 +166,28 @@ where
         //    not store anything about them.
         // 2. decide whether to insert them into the graph depending on whether `is_tx_relevant`
         //    returns true or not. (in a second loop).
-        let txs = txs.into_iter().collect::<Vec<_>>();
+        let txs = txs
+            .into_iter()
+            .map(|(tx, anchors)| (<T as Into<Arc<Transaction>>>::into(tx), anchors))
+            .collect::<Vec<_>>();
 
         let mut indexer = I::ChangeSet::default();
         for (tx, _) in &txs {
             indexer.merge(self.index.index_tx(tx));
         }
 
-        let mut graph = tx_graph::ChangeSet::default();
+        let mut tx_graph = tx_graph::ChangeSet::default();
         for (tx, anchors) in txs {
-            if self.index.is_tx_relevant(tx) {
+            if self.index.is_tx_relevant(&tx) {
                 let txid = tx.compute_txid();
-                graph.merge(self.graph.insert_tx(tx.clone()));
+                tx_graph.merge(self.graph.insert_tx(tx.clone()));
                 for anchor in anchors {
-                    graph.merge(self.graph.insert_anchor(txid, anchor));
+                    tx_graph.merge(self.graph.insert_anchor(txid, anchor));
                 }
             }
         }
 
-        ChangeSet {
-            tx_graph: graph,
-            indexer,
-        }
+        ChangeSet { tx_graph, indexer }
     }
 
     /// Batch insert unconfirmed transactions, filtering out those that are irrelevant.
@@ -198,9 +198,9 @@ where
     /// Items of `txs` are tuples containing the transaction and a *last seen* timestamp. The
     /// *last seen* communicates when the transaction is last seen in the mempool which is used for
     /// conflict-resolution in [`TxGraph`] (refer to [`TxGraph::insert_seen_at`] for details).
-    pub fn batch_insert_relevant_unconfirmed<'t>(
+    pub fn batch_insert_relevant_unconfirmed<T: Into<Arc<Transaction>>>(
         &mut self,
-        unconfirmed_txs: impl IntoIterator<Item = (&'t Transaction, u64)>,
+        unconfirmed_txs: impl IntoIterator<Item = (T, u64)>,
     ) -> ChangeSet<A, I::ChangeSet> {
         // The algorithm below allows for non-topologically ordered transactions by using two loops.
         // This is achieved by:
@@ -208,7 +208,10 @@ where
         //    not store anything about them.
         // 2. decide whether to insert them into the graph depending on whether `is_tx_relevant`
         //    returns true or not. (in a second loop).
-        let txs = unconfirmed_txs.into_iter().collect::<Vec<_>>();
+        let txs = unconfirmed_txs
+            .into_iter()
+            .map(|(tx, last_seen)| (<T as Into<Arc<Transaction>>>::into(tx), last_seen))
+            .collect::<Vec<_>>();
 
         let mut indexer = I::ChangeSet::default();
         for (tx, _) in &txs {
index 361e5ab5c30c82aba194e5725f58978dddbb50e3..1fbbcd0df56ec7565625095bf92a40f57cb4358e 100644 (file)
@@ -81,7 +81,7 @@ fn insert_relevant_txs() {
     };
 
     assert_eq!(
-        graph.batch_insert_relevant(txs.iter().map(|tx| (tx, None))),
+        graph.batch_insert_relevant(txs.iter().cloned().map(|tx| (tx, None))),
         changeset,
     );
 
@@ -237,10 +237,10 @@ fn test_list_owned_txouts() {
     // Insert unconfirmed txs with a last_seen timestamp
 
     let _ =
-        graph.batch_insert_relevant([&tx1, &tx2, &tx3, &tx6].iter().enumerate().map(|(i, tx)| {
+        graph.batch_insert_relevant([&tx1, &tx2, &tx3, &tx6].iter().enumerate().map(|(i, &tx)| {
             let height = i as u32;
             (
-                *tx,
+                tx.clone(),
                 local_chain
                     .get(height)
                     .map(|cp| cp.block_id())
@@ -251,7 +251,8 @@ fn test_list_owned_txouts() {
             )
         }));
 
-    let _ = graph.batch_insert_relevant_unconfirmed([&tx4, &tx5].iter().map(|tx| (*tx, 100)));
+    let _ =
+        graph.batch_insert_relevant_unconfirmed([&tx4, &tx5].iter().map(|&tx| (tx.clone(), 100)));
 
     // A helper lambda to extract and filter data from the graph.
     let fetch =
index 8513251aebba043a226413ca19bc677a88f5ad85..118fae088bdea855b26a649a6e8f96d2adfd2aa0 100644 (file)
@@ -2441,9 +2441,9 @@ impl Wallet {
     /// **WARNING**: You must persist the changes resulting from one or more calls to this method
     /// if you need the applied unconfirmed transactions to be reloaded after closing the wallet.
     /// See [`Wallet::reveal_next_address`].
-    pub fn apply_unconfirmed_txs<'t>(
+    pub fn apply_unconfirmed_txs<T: Into<Arc<Transaction>>>(
         &mut self,
-        unconfirmed_txs: impl IntoIterator<Item = (&'t Transaction, u64)>,
+        unconfirmed_txs: impl IntoIterator<Item = (T, u64)>,
     ) {
         let indexed_graph_changeset = self
             .indexed_graph
index d1833b0711e7e86fcf3290fa9614b9975ab42c3b..95c5479676e3947eb37bd83d516997c38089c6fb 100644 (file)
@@ -201,9 +201,10 @@ fn main() -> anyhow::Result<()> {
             }
 
             let mempool_txs = emitter.mempool()?;
-            let graph_changeset = graph.lock().unwrap().batch_insert_relevant_unconfirmed(
-                mempool_txs.iter().map(|(tx, time)| (tx, *time)),
-            );
+            let graph_changeset = graph
+                .lock()
+                .unwrap()
+                .batch_insert_relevant_unconfirmed(mempool_txs);
             {
                 let db = &mut *db.lock().unwrap();
                 db_stage.merge(ChangeSet {
@@ -286,9 +287,7 @@ fn main() -> anyhow::Result<()> {
                         (chain_changeset, graph_changeset)
                     }
                     Emission::Mempool(mempool_txs) => {
-                        let graph_changeset = graph.batch_insert_relevant_unconfirmed(
-                            mempool_txs.iter().map(|(tx, time)| (tx, *time)),
-                        );
+                        let graph_changeset = graph.batch_insert_relevant_unconfirmed(mempool_txs);
                         (local_chain::ChangeSet::default(), graph_changeset)
                     }
                     Emission::Tip(h) => {
index 388ccaf6791b9f0afab14ced8f7ca091008a7809..af6dcafc451c9b13ea72442aba1a536719b3c8d0 100644 (file)
@@ -157,7 +157,7 @@ fn main() -> anyhow::Result<()> {
             }
             Emission::Mempool(mempool_emission) => {
                 let start_apply_mempool = Instant::now();
-                wallet.apply_unconfirmed_txs(mempool_emission.iter().map(|(tx, time)| (tx, *time)));
+                wallet.apply_unconfirmed_txs(mempool_emission);
                 wallet.persist(&mut db)?;
                 println!(
                     "Applied unconfirmed transactions in {}s",