11//! Helper types for spk-based blockchain clients.
22
3+ use crate :: {
4+ collections:: { BTreeMap , HashMap } ,
5+ local_chain:: CheckPoint ,
6+ ConfirmationTimeHeightAnchor , TxGraph ,
7+ } ;
8+ use alloc:: { boxed:: Box , sync:: Arc , vec:: Vec } ;
9+ use bitcoin:: { OutPoint , Script , ScriptBuf , Transaction , Txid } ;
310use core:: { fmt:: Debug , marker:: PhantomData , ops:: RangeBounds } ;
411
5- use alloc :: { boxed :: Box , collections :: BTreeMap , vec :: Vec } ;
6- use bitcoin :: { OutPoint , Script , ScriptBuf , Txid } ;
7-
8- use crate :: { local_chain :: CheckPoint , ConfirmationTimeHeightAnchor , TxGraph } ;
12+ /// A cache of [`Arc`]-wrapped full transactions, identified by their [`Txid`]s.
13+ ///
14+ /// This is used by the chain-source to avoid re-fetching full transactions.
15+ pub type TxCache = HashMap < Txid , Arc < Transaction > > ;
916
1017/// Data required to perform a spk-based blockchain client sync.
1118///
@@ -17,6 +24,8 @@ pub struct SyncRequest {
1724 ///
1825 /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
1926 pub chain_tip : CheckPoint ,
27+ /// Cache of full transactions, so the chain-source can avoid re-fetching.
28+ pub tx_cache : TxCache ,
2029 /// Transactions that spend from or to these indexed script pubkeys.
2130 pub spks : Box < dyn ExactSizeIterator < Item = ScriptBuf > + Send > ,
2231 /// Transactions with these txids.
@@ -30,12 +39,36 @@ impl SyncRequest {
3039 pub fn from_chain_tip ( cp : CheckPoint ) -> Self {
3140 Self {
3241 chain_tip : cp,
42+ tx_cache : TxCache :: new ( ) ,
3343 spks : Box :: new ( core:: iter:: empty ( ) ) ,
3444 txids : Box :: new ( core:: iter:: empty ( ) ) ,
3545 outpoints : Box :: new ( core:: iter:: empty ( ) ) ,
3646 }
3747 }
3848
49+ /// Add to the [`TxCache`] held by the request.
50+ ///
51+ /// This consumes the [`SyncRequest`] and returns the updated one.
52+ #[ must_use]
53+ pub fn cache_txs < T > ( mut self , full_txs : impl IntoIterator < Item = ( Txid , T ) > ) -> Self
54+ where
55+ T : Into < Arc < Transaction > > ,
56+ {
57+ self . tx_cache = full_txs
58+ . into_iter ( )
59+ . map ( |( txid, tx) | ( txid, tx. into ( ) ) )
60+ . collect ( ) ;
61+ self
62+ }
63+
64+ /// Add all transactions from [`TxGraph`] into the [`TxCache`].
65+ ///
66+ /// This consumes the [`SyncRequest`] and returns the updated one.
67+ #[ must_use]
68+ pub fn cache_graph_txs < A > ( self , graph : & TxGraph < A > ) -> Self {
69+ self . cache_txs ( graph. full_txs ( ) . map ( |tx_node| ( tx_node. txid , tx_node. tx ) ) )
70+ }
71+
3972 /// Set the [`Script`]s that will be synced against.
4073 ///
4174 /// This consumes the [`SyncRequest`] and returns the updated one.
@@ -194,6 +227,8 @@ pub struct FullScanRequest<K> {
194227 ///
195228 /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
196229 pub chain_tip : CheckPoint ,
230+ /// Cache of full transactions, so the chain-source can avoid re-fetching.
231+ pub tx_cache : TxCache ,
197232 /// Iterators of script pubkeys indexed by the keychain index.
198233 pub spks_by_keychain : BTreeMap < K , Box < dyn Iterator < Item = ( u32 , ScriptBuf ) > + Send > > ,
199234}
@@ -204,10 +239,34 @@ impl<K: Ord + Clone> FullScanRequest<K> {
204239 pub fn from_chain_tip ( chain_tip : CheckPoint ) -> Self {
205240 Self {
206241 chain_tip,
242+ tx_cache : TxCache :: new ( ) ,
207243 spks_by_keychain : BTreeMap :: new ( ) ,
208244 }
209245 }
210246
247+ /// Add to the [`TxCache`] held by the request.
248+ ///
249+ /// This consumes the [`SyncRequest`] and returns the updated one.
250+ #[ must_use]
251+ pub fn cache_txs < T > ( mut self , full_txs : impl IntoIterator < Item = ( Txid , T ) > ) -> Self
252+ where
253+ T : Into < Arc < Transaction > > ,
254+ {
255+ self . tx_cache = full_txs
256+ . into_iter ( )
257+ . map ( |( txid, tx) | ( txid, tx. into ( ) ) )
258+ . collect ( ) ;
259+ self
260+ }
261+
262+ /// Add all transactions from [`TxGraph`] into the [`TxCache`].
263+ ///
264+ /// This consumes the [`SyncRequest`] and returns the updated one.
265+ #[ must_use]
266+ pub fn cache_graph_txs < A > ( self , graph : & TxGraph < A > ) -> Self {
267+ self . cache_txs ( graph. full_txs ( ) . map ( |tx_node| ( tx_node. txid , tx_node. tx ) ) )
268+ }
269+
211270 /// Construct a new [`FullScanRequest`] from a given `chain_tip` and `index`.
212271 ///
213272 /// Unbounded script pubkey iterators for each keychain (`K`) are extracted using
0 commit comments