From: Wei Chen Date: Fri, 25 Apr 2025 07:29:36 +0000 (+0000) Subject: feat(graph): add convenience function for inserting relevant `evicted_at`s X-Git-Tag: core-0.5.0~1^2~2 X-Git-Url: http://internal-gitweb-vhost/script/%22https:/enum.FileError.html?a=commitdiff_plain;h=d11f6efe8f6feddaa115cde32ebead19f92c2f64;p=bdk feat(graph): add convenience function for inserting relevant `evicted_at`s --- diff --git a/crates/bitcoind_rpc/src/lib.rs b/crates/bitcoind_rpc/src/lib.rs index 7e363560..dc21997d 100644 --- a/crates/bitcoind_rpc/src/lib.rs +++ b/crates/bitcoind_rpc/src/lib.rs @@ -236,6 +236,14 @@ pub struct MempoolEvent { pub latest_update_time: u64, } +impl MempoolEvent { + /// Returns an iterator of `(txid, evicted_at)` pairs for all evicted transactions. + pub fn evicted_ats(&self) -> impl ExactSizeIterator + '_ { + let time = self.latest_update_time; + self.evicted_txids.iter().map(move |&txid| (txid, time)) + } +} + /// A newly emitted block from [`Emitter`]. #[derive(Debug)] pub struct BlockEvent { diff --git a/crates/bitcoind_rpc/tests/test_emitter.rs b/crates/bitcoind_rpc/tests/test_emitter.rs index 0c30f5a8..360a1f43 100644 --- a/crates/bitcoind_rpc/tests/test_emitter.rs +++ b/crates/bitcoind_rpc/tests/test_emitter.rs @@ -847,11 +847,7 @@ fn test_expect_tx_evicted() -> anyhow::Result<()> { assert!(mempool_event.evicted_txids.contains(&txid_1)); // Update graph with evicted tx. - for txid in mempool_event.evicted_txids { - if graph.graph().get_tx_node(txid).is_some() { - let _ = graph.insert_evicted_at(txid, mempool_event.latest_update_time); - } - } + let _ = graph.batch_insert_relevant_evicted_at(mempool_event.evicted_ats()); let canonical_txids = graph .graph() diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs index bcd6ac3f..89e79432 100644 --- a/crates/chain/src/indexed_tx_graph.rs +++ b/crates/chain/src/indexed_tx_graph.rs @@ -145,6 +145,22 @@ where } } + /// Batch inserts `(txid, evicted_at)` pairs for `txid`s that the graph is tracking. + /// + /// The `evicted_at` timestamp represents the last known time when the transaction was observed + /// to be missing from the mempool. If `txid` was previously recorded with an earlier + /// `evicted_at` value, it is updated only if the new value is greater. + pub fn batch_insert_relevant_evicted_at( + &mut self, + evicted_ats: impl IntoIterator, + ) -> ChangeSet { + let tx_graph = self.graph.batch_insert_relevant_evicted_at(evicted_ats); + ChangeSet { + tx_graph, + ..Default::default() + } + } + /// Batch insert transactions, filtering out those that are irrelevant. /// /// Relevancy is determined by the [`Indexer::is_tx_relevant`] implementation of `I`. Irrelevant diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index 2358b188..a10f3e75 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -835,6 +835,26 @@ impl TxGraph { changeset } + /// Batch inserts `(txid, evicted_at)` pairs into [`TxGraph`] for `txid`s that the graph is + /// tracking. + /// + /// The `evicted_at` timestamp represents the last known time when the transaction was observed + /// to be missing from the mempool. If `txid` was previously recorded with an earlier + /// `evicted_at` value, it is updated only if the new value is greater. + pub fn batch_insert_relevant_evicted_at( + &mut self, + evicted_ats: impl IntoIterator, + ) -> ChangeSet { + let mut changeset = ChangeSet::default(); + for (txid, evicted_at) in evicted_ats { + // Only record evictions for transactions the graph is tracking. + if self.txs.contains_key(&txid) { + changeset.merge(self.insert_evicted_at(txid, evicted_at)); + } + } + changeset + } + /// Extends this graph with the given `update`. /// /// The returned [`ChangeSet`] is the set difference between `update` and `self` (transactions that diff --git a/examples/example_bitcoind_rpc_polling/src/main.rs b/examples/example_bitcoind_rpc_polling/src/main.rs index 3684edbf..8cbe1939 100644 --- a/examples/example_bitcoind_rpc_polling/src/main.rs +++ b/examples/example_bitcoind_rpc_polling/src/main.rs @@ -289,11 +289,9 @@ fn main() -> anyhow::Result<()> { Emission::Mempool(mempool_txs) => { let mut graph_changeset = graph.batch_insert_relevant_unconfirmed(mempool_txs.new_txs.clone()); - for txid in mempool_txs.evicted_txids { - graph_changeset.merge( - graph.insert_evicted_at(txid, mempool_txs.latest_update_time), - ); - } + graph_changeset.merge( + graph.batch_insert_relevant_evicted_at(mempool_txs.evicted_ats()), + ); (local_chain::ChangeSet::default(), graph_changeset) } Emission::Tip(h) => {