feat(chain): introduce TxCache to SyncRequest and FullScanRequest
				
					
				
			This transaction cache can be provided so the chain-source can avoid re-fetching transactions.
This commit is contained in:
		
							parent
							
								
									721bb7f519
								
							
						
					
					
						commit
						58f27b38eb
					
				| @ -1,11 +1,18 @@ | |||||||
| //! Helper types for spk-based blockchain clients.
 | //! Helper types for spk-based blockchain clients.
 | ||||||
| 
 | 
 | ||||||
|  | use crate::{ | ||||||
|  |     collections::{BTreeMap, HashMap}, | ||||||
|  |     local_chain::CheckPoint, | ||||||
|  |     ConfirmationTimeHeightAnchor, TxGraph, | ||||||
|  | }; | ||||||
|  | use alloc::{boxed::Box, sync::Arc, vec::Vec}; | ||||||
|  | use bitcoin::{OutPoint, Script, ScriptBuf, Transaction, Txid}; | ||||||
| use core::{fmt::Debug, marker::PhantomData, ops::RangeBounds}; | use core::{fmt::Debug, marker::PhantomData, ops::RangeBounds}; | ||||||
| 
 | 
 | ||||||
| use alloc::{boxed::Box, collections::BTreeMap, vec::Vec}; | /// A cache of [`Arc`]-wrapped full transactions, identified by their [`Txid`]s.
 | ||||||
| use bitcoin::{OutPoint, Script, ScriptBuf, Txid}; | ///
 | ||||||
| 
 | /// This is used by the chain-source to avoid re-fetching full transactions.
 | ||||||
| use crate::{local_chain::CheckPoint, ConfirmationTimeHeightAnchor, TxGraph}; | pub type TxCache = HashMap<Txid, Arc<Transaction>>; | ||||||
| 
 | 
 | ||||||
| /// Data required to perform a spk-based blockchain client sync.
 | /// Data required to perform a spk-based blockchain client sync.
 | ||||||
| ///
 | ///
 | ||||||
| @ -17,6 +24,8 @@ pub struct SyncRequest { | |||||||
|     ///
 |     ///
 | ||||||
|     /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
 |     /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
 | ||||||
|     pub chain_tip: CheckPoint, |     pub chain_tip: CheckPoint, | ||||||
|  |     /// Cache of full transactions, so the chain-source can avoid re-fetching.
 | ||||||
|  |     pub tx_cache: TxCache, | ||||||
|     /// Transactions that spend from or to these indexed script pubkeys.
 |     /// Transactions that spend from or to these indexed script pubkeys.
 | ||||||
|     pub spks: Box<dyn ExactSizeIterator<Item = ScriptBuf> + Send>, |     pub spks: Box<dyn ExactSizeIterator<Item = ScriptBuf> + Send>, | ||||||
|     /// Transactions with these txids.
 |     /// Transactions with these txids.
 | ||||||
| @ -30,12 +39,36 @@ impl SyncRequest { | |||||||
|     pub fn from_chain_tip(cp: CheckPoint) -> Self { |     pub fn from_chain_tip(cp: CheckPoint) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             chain_tip: cp, |             chain_tip: cp, | ||||||
|  |             tx_cache: TxCache::new(), | ||||||
|             spks: Box::new(core::iter::empty()), |             spks: Box::new(core::iter::empty()), | ||||||
|             txids: Box::new(core::iter::empty()), |             txids: Box::new(core::iter::empty()), | ||||||
|             outpoints: Box::new(core::iter::empty()), |             outpoints: Box::new(core::iter::empty()), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Add to the [`TxCache`] held by the request.
 | ||||||
|  |     ///
 | ||||||
|  |     /// This consumes the [`SyncRequest`] and returns the updated one.
 | ||||||
|  |     #[must_use] | ||||||
|  |     pub fn cache_txs<T>(mut self, full_txs: impl IntoIterator<Item = (Txid, T)>) -> Self | ||||||
|  |     where | ||||||
|  |         T: Into<Arc<Transaction>>, | ||||||
|  |     { | ||||||
|  |         self.tx_cache = full_txs | ||||||
|  |             .into_iter() | ||||||
|  |             .map(|(txid, tx)| (txid, tx.into())) | ||||||
|  |             .collect(); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Add all transactions from [`TxGraph`] into the [`TxCache`].
 | ||||||
|  |     ///
 | ||||||
|  |     /// This consumes the [`SyncRequest`] and returns the updated one.
 | ||||||
|  |     #[must_use] | ||||||
|  |     pub fn cache_graph_txs<A>(self, graph: &TxGraph<A>) -> Self { | ||||||
|  |         self.cache_txs(graph.full_txs().map(|tx_node| (tx_node.txid, tx_node.tx))) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Set the [`Script`]s that will be synced against.
 |     /// Set the [`Script`]s that will be synced against.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// This consumes the [`SyncRequest`] and returns the updated one.
 |     /// This consumes the [`SyncRequest`] and returns the updated one.
 | ||||||
| @ -194,6 +227,8 @@ pub struct FullScanRequest<K> { | |||||||
|     ///
 |     ///
 | ||||||
|     /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
 |     /// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
 | ||||||
|     pub chain_tip: CheckPoint, |     pub chain_tip: CheckPoint, | ||||||
|  |     /// Cache of full transactions, so the chain-source can avoid re-fetching.
 | ||||||
|  |     pub tx_cache: TxCache, | ||||||
|     /// Iterators of script pubkeys indexed by the keychain index.
 |     /// Iterators of script pubkeys indexed by the keychain index.
 | ||||||
|     pub spks_by_keychain: BTreeMap<K, Box<dyn Iterator<Item = (u32, ScriptBuf)> + Send>>, |     pub spks_by_keychain: BTreeMap<K, Box<dyn Iterator<Item = (u32, ScriptBuf)> + Send>>, | ||||||
| } | } | ||||||
| @ -204,10 +239,34 @@ impl<K: Ord + Clone> FullScanRequest<K> { | |||||||
|     pub fn from_chain_tip(chain_tip: CheckPoint) -> Self { |     pub fn from_chain_tip(chain_tip: CheckPoint) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             chain_tip, |             chain_tip, | ||||||
|  |             tx_cache: TxCache::new(), | ||||||
|             spks_by_keychain: BTreeMap::new(), |             spks_by_keychain: BTreeMap::new(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Add to the [`TxCache`] held by the request.
 | ||||||
|  |     ///
 | ||||||
|  |     /// This consumes the [`SyncRequest`] and returns the updated one.
 | ||||||
|  |     #[must_use] | ||||||
|  |     pub fn cache_txs<T>(mut self, full_txs: impl IntoIterator<Item = (Txid, T)>) -> Self | ||||||
|  |     where | ||||||
|  |         T: Into<Arc<Transaction>>, | ||||||
|  |     { | ||||||
|  |         self.tx_cache = full_txs | ||||||
|  |             .into_iter() | ||||||
|  |             .map(|(txid, tx)| (txid, tx.into())) | ||||||
|  |             .collect(); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Add all transactions from [`TxGraph`] into the [`TxCache`].
 | ||||||
|  |     ///
 | ||||||
|  |     /// This consumes the [`SyncRequest`] and returns the updated one.
 | ||||||
|  |     #[must_use] | ||||||
|  |     pub fn cache_graph_txs<A>(self, graph: &TxGraph<A>) -> Self { | ||||||
|  |         self.cache_txs(graph.full_txs().map(|tx_node| (tx_node.txid, tx_node.tx))) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Construct a new [`FullScanRequest`] from a given `chain_tip` and `index`.
 |     /// Construct a new [`FullScanRequest`] from a given `chain_tip` and `index`.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// Unbounded script pubkey iterators for each keychain (`K`) are extracted using
 |     /// Unbounded script pubkey iterators for each keychain (`K`) are extracted using
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user