]> Untitled Git - bdk/commitdiff
feat(chain)!: make `IndexedTxGraph::apply_block_relevant` more efficient
author志宇 <hello@evanlinjin.me>
Tue, 2 Jan 2024 09:31:34 +0000 (17:31 +0800)
committer志宇 <hello@evanlinjin.me>
Mon, 15 Jan 2024 16:27:02 +0000 (00:27 +0800)
Previously, `apply_block_relevant` used `batch_insert_relevant` which
allows inserting non-topologically-ordered transactions. However,
transactions from blocks are always ordered, so we can avoid looping
through block transactions twice (as done in `batch_insert_relevant`).

Additionally, `apply_block_relevant` now takes in a reference to a
`Block` instead of consuming the `Block`. This makes sense as typically
very few of the transactions in the block are inserted.

crates/bdk/src/wallet/mod.rs
crates/bitcoind_rpc/tests/test_emitter.rs
crates/chain/src/indexed_tx_graph.rs

index 8f703c6b73f93f0ec552cd6d2026a54c87c333fc..b18ee983a5acb0db19b7239eac459b10fdd7ccef 100644 (file)
@@ -2385,7 +2385,7 @@ impl<D> Wallet<D> {
     /// with `prev_blockhash` and `height-1` as the `connected_to` parameter.
     ///
     /// [`apply_block_connected_to`]: Self::apply_block_connected_to
-    pub fn apply_block(&mut self, block: Block, height: u32) -> Result<(), CannotConnectError>
+    pub fn apply_block(&mut self, block: &Block, height: u32) -> Result<(), CannotConnectError>
     where
         D: PersistBackend<ChangeSet>,
     {
@@ -2416,7 +2416,7 @@ impl<D> Wallet<D> {
     /// internal [`TxGraph`].
     pub fn apply_block_connected_to(
         &mut self,
-        block: Block,
+        block: &Block,
         height: u32,
         connected_to: BlockId,
     ) -> Result<(), ApplyHeaderError>
index 384df92d069068984dab6acbae1f0ea8dd5f687d..52d7093010ac0c006ec2fe1388798a286b783c15 100644 (file)
@@ -298,7 +298,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
             tip: emission.checkpoint,
             introduce_older_blocks: false,
         })?;
-        let indexed_additions = indexed_tx_graph.apply_block_relevant(emission.block, height);
+        let indexed_additions = indexed_tx_graph.apply_block_relevant(&emission.block, height);
         assert!(indexed_additions.is_empty());
     }
 
@@ -362,7 +362,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
             tip: emission.checkpoint,
             introduce_older_blocks: false,
         })?;
-        let indexed_additions = indexed_tx_graph.apply_block_relevant(emission.block, height);
+        let indexed_additions = indexed_tx_graph.apply_block_relevant(&emission.block, height);
         assert!(indexed_additions.graph.txs.is_empty());
         assert!(indexed_additions.graph.txouts.is_empty());
         assert_eq!(indexed_additions.graph.anchors, exp_anchors);
index 777b5d978b6b7acb798d73e290f3628a486ccb4b..c2b83600b15f12c8e0f0c5f03acbfbdc96456095 100644 (file)
@@ -224,20 +224,26 @@ where
     /// Irrelevant transactions in `txs` will be ignored.
     pub fn apply_block_relevant(
         &mut self,
-        block: Block,
+        block: &Block,
         height: u32,
     ) -> ChangeSet<A, I::ChangeSet> {
         let block_id = BlockId {
             hash: block.block_hash(),
             height,
         };
-        let txs = block.txdata.iter().enumerate().map(|(tx_pos, tx)| {
-            (
-                tx,
-                core::iter::once(A::from_block_position(&block, block_id, tx_pos)),
-            )
-        });
-        self.batch_insert_relevant(txs)
+        let mut changeset = ChangeSet::<A, I::ChangeSet>::default();
+        for (tx_pos, tx) in block.txdata.iter().enumerate() {
+            changeset.indexer.append(self.index.index_tx(tx));
+            if self.index.is_tx_relevant(tx) {
+                let txid = tx.txid();
+                let anchor = A::from_block_position(block, block_id, tx_pos);
+                changeset.graph.append(self.graph.insert_tx(tx.clone()));
+                changeset
+                    .graph
+                    .append(self.graph.insert_anchor(txid, anchor));
+            }
+        }
+        changeset
     }
 
     /// Batch insert all transactions of the given `block` of `height`.