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