11//! This crate is used for updating [`bdk_chain`] structures with data from the `bitcoind` RPC
2- //! interface.
2+ //! interface (excluding the RPC wallet API) .
33//!
4- //! The main structure is [`Emitter`], which sources blockchain data from
5- //! [`bitcoincore_rpc::Client`].
4+ //! [`Emitter`] is the main structure which sources blockchain data from [`bitcoincore_rpc::Client`].
65//!
76//! To only get block updates (exlude mempool transactions), the caller can use
87//! [`Emitter::emit_block`] until it returns `Ok(None)` (which means the chain tip is reached). A
4342
4443use bdk_chain:: {
4544 bitcoin:: { Block , Transaction } ,
46- indexed_tx_graph:: Indexer ,
45+ indexed_tx_graph:: TxItem ,
4746 local_chain:: { self , CheckPoint } ,
48- Append , BlockId , ConfirmationHeightAnchor , ConfirmationTimeAnchor , TxGraph ,
47+ BlockId , ConfirmationHeightAnchor , ConfirmationTimeAnchor ,
4948} ;
5049pub use bitcoincore_rpc;
5150use bitcoincore_rpc:: { json:: GetBlockResult , RpcApi } ;
@@ -92,24 +91,21 @@ impl EmittedUpdate {
9291 } )
9392 }
9493
95- /// Transforms the emitted update into a [`TxGraph`] update.
96- ///
97- /// The `tx_filter` parameter takes in a closure that filters out irrelevant transactions so
98- /// they do not get included in the [`TxGraph`] update. We have provided two closures;
99- /// [`empty_filter`] and [`indexer_filter`] for this purpose.
94+ /// Return transaction items to be consumed by [`IndexedTxGraph::insert_relevant_txs`].
10095 ///
10196 /// The `anchor_map` parameter takes in a closure that creates anchors of a specific type.
10297 /// [`confirmation_height_anchor`] and [`confirmation_time_anchor`] are avaliable to create
10398 /// updates with [`ConfirmationHeightAnchor`] and [`ConfirmationTimeAnchor`] respectively.
104- pub fn into_tx_graph_update < F , M , A > ( self , tx_filter : F , anchor_map : M ) -> TxGraph < A >
99+ ///
100+ /// [`IndexedTxGraph::insert_relevant_txs`]: bdk_chain::IndexedTxGraph::insert_relevant_txs
101+ pub fn indexed_tx_graph_update < M , A > ( & self , anchor_map : M ) -> Vec < TxItem < ' _ , Option < A > > >
105102 where
106- F : FnMut ( & Transaction ) -> bool ,
107103 M : Fn ( & CheckPoint , & Block , usize ) -> A ,
108- A : Clone + Ord + PartialOrd ,
104+ A : Clone + Ord + PartialEq ,
109105 {
110106 match self {
111- EmittedUpdate :: Block ( e) => e. into_tx_graph_update ( tx_filter , anchor_map) ,
112- EmittedUpdate :: Mempool ( e) => e. into_tx_graph_update ( tx_filter ) ,
107+ EmittedUpdate :: Block ( e) => e. indexed_tx_graph_update ( anchor_map) . collect ( ) ,
108+ EmittedUpdate :: Mempool ( e) => e. indexed_tx_graph_update ( ) . collect ( ) ,
113109 }
114110 }
115111}
@@ -129,87 +125,63 @@ impl EmittedBlock {
129125 self . cp . clone ( )
130126 }
131127
132- /// Transforms the emitted update into a [`TxGraph`] update.
128+ /// Convenience method to get [`local_chain::Update`].
129+ pub fn chain_update ( & self ) -> local_chain:: Update {
130+ local_chain:: Update {
131+ tip : self . cp . clone ( ) ,
132+ introduce_older_blocks : false ,
133+ }
134+ }
135+
136+ /// Return transaction items to be consumed by [`IndexedTxGraph::insert_relevant_txs`].
133137 ///
134- /// The `tx_filter` parameter takes in a closure that filters out irrelevant transactions so
135- /// they do not get included in the [`TxGraph`] update. We have provided two closures;
136- /// [`empty_filter`] and [`indexer_filter`] for this purpose.
138+ /// Refer to [`EmittedUpdate::indexed_tx_graph_update`] for more.
137139 ///
138- /// The `anchor_map` parameter takes in a closure that creates anchors of a specific type.
139- /// [`confirmation_height_anchor`] and [`confirmation_time_anchor`] are avaliable to create
140- /// updates with [`ConfirmationHeightAnchor`] and [`ConfirmationTimeAnchor`] respectively.
141- pub fn into_tx_graph_update < F , M , A > ( self , mut tx_filter : F , anchor_map : M ) -> TxGraph < A >
140+ /// [`IndexedTxGraph::insert_relevant_txs`]: bdk_chain::IndexedTxGraph::insert_relevant_txs
141+ pub fn indexed_tx_graph_update < M , A > (
142+ & self ,
143+ anchor_map : M ,
144+ ) -> impl Iterator < Item = TxItem < ' _ , Option < A > > >
142145 where
143- F : FnMut ( & Transaction ) -> bool ,
144146 M : Fn ( & CheckPoint , & Block , usize ) -> A ,
145- A : Clone + Ord + PartialOrd ,
147+ A : Clone + Ord + PartialEq ,
146148 {
147- let mut tx_graph = TxGraph :: default ( ) ;
148- let tx_iter = self
149- . block
149+ self . block
150150 . txdata
151151 . iter ( )
152152 . enumerate ( )
153- . filter ( move |( _, tx) | tx_filter ( tx) ) ;
154- for ( tx_pos, tx) in tx_iter {
155- let txid = tx. txid ( ) ;
156- let _ = tx_graph. insert_anchor ( txid, anchor_map ( & self . cp , & self . block , tx_pos) ) ;
157- let _ = tx_graph. insert_tx ( tx. clone ( ) ) ;
158- }
159- tx_graph
153+ . map ( move |( i, tx) | ( tx, Some ( anchor_map ( & self . cp , & self . block , i) ) , None ) )
160154 }
161155}
162156
163157/// An emitted subset of mempool transactions.
164158#[ derive( Debug , Clone ) ]
165159pub struct EmittedMempool {
166- /// Subset of mempool transactions.
160+ /// Subset of mempool transactions as tuples of `(tx, seen_at)`.
161+ ///
162+ /// `seen_at` is the unix timestamp of when the transaction was first seen in the mempool.
167163 pub txs : Vec < ( Transaction , u64 ) > ,
168164}
169165
170166impl EmittedMempool {
171- /// Transforms the emitted mempool into a [`TxGraph`] update.
167+ /// Return transaction items to be consumed by [`IndexedTxGraph::insert_relevant_txs`].
168+ ///
169+ /// Refer to [`EmittedUpdate::indexed_tx_graph_update`] for more.
172170 ///
173- /// The `tx_filter` parameter takes in a closure that filters out irrelevant transactions so
174- /// they do not get included in the [`TxGraph`] update. We have provided two closures;
175- /// [`empty_filter`] and [`indexer_filter`] for this purpose.
176- pub fn into_tx_graph_update < F , A > ( self , mut tx_filter : F ) -> TxGraph < A >
171+ /// [`IndexedTxGraph::insert_relevant_txs`]: bdk_chain::IndexedTxGraph::insert_relevant_txs
172+ pub fn indexed_tx_graph_update < A > ( & self ) -> impl Iterator < Item = TxItem < ' _ , Option < A > > >
177173 where
178- F : FnMut ( & Transaction ) -> bool ,
179- A : Clone + Ord + PartialOrd ,
174+ A : Clone + Ord + PartialEq ,
180175 {
181- let mut tx_graph = TxGraph :: default ( ) ;
182- let tx_iter = self . txs . into_iter ( ) . filter ( move |( tx, _) | tx_filter ( tx) ) ;
183- for ( tx, seen_at) in tx_iter {
184- let _ = tx_graph. insert_seen_at ( tx. txid ( ) , seen_at) ;
185- let _ = tx_graph. insert_tx ( tx) ;
186- }
187- tx_graph
188- }
189- }
190-
191- /// Creates a closure that filters transactions based on an [`Indexer`] implementation.
192- pub fn indexer_filter < ' i , I : Indexer > (
193- indexer : & ' i mut I ,
194- changeset : & ' i mut I :: ChangeSet ,
195- ) -> impl FnMut ( & Transaction ) -> bool + ' i
196- where
197- I :: ChangeSet : bdk_chain:: Append ,
198- {
199- |tx| {
200- changeset. append ( indexer. index_tx ( tx) ) ;
201- indexer. is_tx_relevant ( tx)
176+ self . txs
177+ . iter ( )
178+ . map ( |( tx, seen_at) | ( tx, None , Some ( * seen_at) ) )
202179 }
203180}
204181
205- /// Returns an empty filter-closure.
206- pub fn empty_filter ( ) -> impl FnMut ( & Transaction ) -> bool {
207- |_| true
208- }
209-
210182/// A closure that transforms a [`EmittedUpdate`] into a [`ConfirmationHeightAnchor`].
211183///
212- /// This is to be used as an input to [`EmittedUpdate::into_tx_graph_update `].
184+ /// This is to be used as an input to [`EmittedUpdate::indexed_tx_graph_update `].
213185pub fn confirmation_height_anchor (
214186 cp : & CheckPoint ,
215187 _block : & Block ,
@@ -224,7 +196,7 @@ pub fn confirmation_height_anchor(
224196
225197/// A closure that transforms a [`EmittedUpdate`] into a [`ConfirmationTimeAnchor`].
226198///
227- /// This is to be used as an input to [`EmittedUpdate::into_tx_graph_update `].
199+ /// This is to be used as an input to [`EmittedUpdate::indexed_tx_graph_update `].
228200pub fn confirmation_time_anchor (
229201 cp : & CheckPoint ,
230202 block : & Block ,
0 commit comments